aboutsummaryrefslogtreecommitdiff
path: root/drivers/scsi/libsas/sas_expander.c
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2008-02-03 18:29:41 +1100
committerDavid Woodhouse <dwmw2@infradead.org>2008-02-03 18:30:32 +1100
commitc1f3ee120bb61045b1c0a3ead620d1d65af47130 (patch)
tree908430bf2b47fe8e96ac623ae7ab6dd5698d0938 /drivers/scsi/libsas/sas_expander.c
parente619a75ff6201b567a539e787aa9af9bc63a3187 (diff)
parent9135f1901ee6449dfe338adf6e40e9c2025b8150 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Diffstat (limited to 'drivers/scsi/libsas/sas_expander.c')
-rw-r--r--drivers/scsi/libsas/sas_expander.c35
1 files changed, 26 insertions, 9 deletions
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c
index 8727436b222..aefd865a578 100644
--- a/drivers/scsi/libsas/sas_expander.c
+++ b/drivers/scsi/libsas/sas_expander.c
@@ -96,7 +96,7 @@ static int smp_execute_task(struct domain_device *dev, void *req, int req_size,
}
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);
@@ -109,6 +109,16 @@ static int smp_execute_task(struct domain_device *dev, void *req, int req_size,
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__,
@@ -656,9 +666,9 @@ static struct domain_device *sas_ex_discover_end_dev(
sas_ex_get_linkrate(parent, child, phy);
#ifdef CONFIG_SCSI_SAS_ATA
- if ((phy->attached_tproto & SAS_PROTO_STP) || phy->attached_sata_dev) {
+ if ((phy->attached_tproto & SAS_PROTOCOL_STP) || phy->attached_sata_dev) {
child->dev_type = SATA_DEV;
- if (phy->attached_tproto & SAS_PROTO_STP)
+ if (phy->attached_tproto & SAS_PROTOCOL_STP)
child->tproto = phy->attached_tproto;
if (phy->attached_sata_dev)
child->tproto |= SATA_DEV;
@@ -695,7 +705,7 @@ static struct domain_device *sas_ex_discover_end_dev(
}
} else
#endif
- if (phy->attached_tproto & SAS_PROTO_SSP) {
+ if (phy->attached_tproto & SAS_PROTOCOL_SSP) {
child->dev_type = SAS_END_DEV;
rphy = sas_end_device_alloc(phy->port);
/* FIXME: error handling */
@@ -1896,11 +1906,9 @@ int sas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
}
/* 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 &&
@@ -1926,6 +1934,15 @@ int sas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
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;
}