}
wait_for_completion(&task->completion);
- res = -ETASK;
+ res = -ECOMM;
if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
SAS_DPRINTK("smp task timed out or aborted\n");
i->dft->lldd_abort_task(task);
task->task_status.stat == SAM_GOOD) {
res = 0;
break;
+ } if (task->task_status.resp == SAS_TASK_COMPLETE &&
+ task->task_status.stat == SAS_DATA_UNDERRUN) {
+ /* no error, but return the number of bytes of
+ * underrun */
+ res = task->task_status.residual;
+ break;
+ } if (task->task_status.resp == SAS_TASK_COMPLETE &&
+ task->task_status.stat == SAS_DATA_OVERRUN) {
+ res = -EMSGSIZE;
+ break;
} else {
SAS_DPRINTK("%s: task to dev %016llx response: 0x%x "
- "status 0x%x\n", __FUNCTION__,
+ "status 0x%x\n", __func__,
SAS_ADDR(dev->sas_addr),
task->task_status.resp,
task->task_status.stat);
goto out;
} else if (res != SMP_RESP_FUNC_ACC) {
SAS_DPRINTK("%s: dev %016llx phy 0x%x index 0x%x "
- "result 0x%x\n", __FUNCTION__,
+ "result 0x%x\n", __func__,
SAS_ADDR(dev->sas_addr), phy_id, i, res);
goto out;
}
if (!rsp) {
printk("%s: space for a smp response is missing\n",
- __FUNCTION__);
+ __func__);
return -EINVAL;
}
/* no rphy means no smp target support (ie aic94xx host) */
- if (!rphy) {
- printk("%s: can we send a smp request to a host?\n",
- __FUNCTION__);
- return -EINVAL;
- }
+ if (!rphy)
+ return sas_smp_host_handler(shost, req, rsp);
+
type = rphy->identify.device_type;
if (type != SAS_EDGE_EXPANDER_DEVICE &&
type != SAS_FANOUT_EXPANDER_DEVICE) {
printk("%s: can we send a smp request to a device?\n",
- __FUNCTION__);
+ __func__);
return -EINVAL;
}
dev = sas_find_dev_by_rphy(rphy);
if (!dev) {
- printk("%s: fail to find a domain_device?\n", __FUNCTION__);
+ printk("%s: fail to find a domain_device?\n", __func__);
return -EINVAL;
}
/* do we need to support multiple segments? */
if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) {
printk("%s: multiple segments req %u %u, rsp %u %u\n",
- __FUNCTION__, req->bio->bi_vcnt, req->data_len,
+ __func__, req->bio->bi_vcnt, req->data_len,
rsp->bio->bi_vcnt, rsp->data_len);
return -EINVAL;
}
ret = smp_execute_task(dev, bio_data(req->bio), req->data_len,
bio_data(rsp->bio), rsp->data_len);
+ if (ret > 0) {
+ /* positive number is the untransferred residual */
+ rsp->data_len = ret;
+ req->data_len = 0;
+ ret = 0;
+ } else if (ret == 0) {
+ rsp->data_len = 0;
+ req->data_len = 0;
+ }
return ret;
}