diff options
author | David Woodhouse <dwmw2@infradead.org> | 2008-02-03 18:29:41 +1100 |
---|---|---|
committer | David Woodhouse <dwmw2@infradead.org> | 2008-02-03 18:30:32 +1100 |
commit | c1f3ee120bb61045b1c0a3ead620d1d65af47130 (patch) | |
tree | 908430bf2b47fe8e96ac623ae7ab6dd5698d0938 /drivers/scsi/libsas/sas_expander.c | |
parent | e619a75ff6201b567a539e787aa9af9bc63a3187 (diff) | |
parent | 9135f1901ee6449dfe338adf6e40e9c2025b8150 (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.c | 35 |
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; } |