diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-17 17:54:40 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-17 17:54:40 -0700 |
commit | c55d267de274d308927b60c3e740c1a826832317 (patch) | |
tree | 21b53a8c725d9f9650f60d94b349459d5b8dae10 /drivers/scsi/libsas/sas_ata.c | |
parent | 61ef46fd45c3c62dc7c880a45dd2aa841b9af8fb (diff) | |
parent | bc898c97f7ba24def788d9f80786cf028a197122 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (170 commits)
[SCSI] scsi_dh_rdac: Add MD36xxf into device list
[SCSI] scsi_debug: add consecutive medium errors
[SCSI] libsas: fix ata list corruption issue
[SCSI] hpsa: export resettable host attribute
[SCSI] hpsa: move device attributes to avoid forward declarations
[SCSI] scsi_debug: Logical Block Provisioning (SBC3r26)
[SCSI] sd: Logical Block Provisioning update
[SCSI] Include protection operation in SCSI command trace
[SCSI] hpsa: fix incorrect PCI IDs and add two new ones (2nd try)
[SCSI] target: Fix volume size misreporting for volumes > 2TB
[SCSI] bnx2fc: Broadcom FCoE offload driver
[SCSI] fcoe: fix broken fcoe interface reset
[SCSI] fcoe: precedence bug in fcoe_filter_frames()
[SCSI] libfcoe: Remove stale fcoe-netdev entries
[SCSI] libfcoe: Move FCOE_MTU definition from fcoe.h to libfcoe.h
[SCSI] libfc: introduce __fc_fill_fc_hdr that accepts fc_hdr as an argument
[SCSI] fcoe, libfc: initialize EM anchors list and then update npiv EMs
[SCSI] Revert "[SCSI] libfc: fix exchange being deleted when the abort itself is timed out"
[SCSI] libfc: Fixing a memory leak when destroying an interface
[SCSI] megaraid_sas: Version and Changelog update
...
Fix up trivial conflicts due to whitespace differences in
drivers/scsi/libsas/{sas_ata.c,sas_scsi_host.c}
Diffstat (limited to 'drivers/scsi/libsas/sas_ata.c')
-rw-r--r-- | drivers/scsi/libsas/sas_ata.c | 80 |
1 files changed, 22 insertions, 58 deletions
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index 4d3b704ede1..31fc21f4d83 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c @@ -71,13 +71,13 @@ static enum ata_completion_errors sas_to_ata_err(struct task_status_struct *ts) case SAS_SG_ERR: return AC_ERR_INVALID; - case SAM_STAT_CHECK_CONDITION: case SAS_OPEN_TO: case SAS_OPEN_REJECT: SAS_DPRINTK("%s: Saw error %d. What to do?\n", __func__, ts->stat); return AC_ERR_OTHER; + case SAM_STAT_CHECK_CONDITION: case SAS_ABORTED_TASK: return AC_ERR_DEV; @@ -107,13 +107,15 @@ static void sas_ata_task_done(struct sas_task *task) sas_ha = dev->port->ha; spin_lock_irqsave(dev->sata_dev.ap->lock, flags); - if (stat->stat == SAS_PROTO_RESPONSE || stat->stat == SAM_STAT_GOOD) { + if (stat->stat == SAS_PROTO_RESPONSE || stat->stat == SAM_STAT_GOOD || + ((stat->stat == SAM_STAT_CHECK_CONDITION && + dev->sata_dev.command_set == ATAPI_COMMAND_SET))) { ata_tf_from_fis(resp->ending_fis, &dev->sata_dev.tf); qc->err_mask |= ac_err_mask(dev->sata_dev.tf.command); dev->sata_dev.sstatus = resp->sstatus; dev->sata_dev.serror = resp->serror; dev->sata_dev.scontrol = resp->scontrol; - } else if (stat->stat != SAM_STAT_GOOD) { + } else { ac = sas_to_ata_err(stat); if (ac) { SAS_DPRINTK("%s: SAS error %x\n", __func__, @@ -305,55 +307,6 @@ static void sas_ata_post_internal(struct ata_queued_cmd *qc) } } -static int sas_ata_scr_write(struct ata_link *link, unsigned int sc_reg_in, - u32 val) -{ - struct domain_device *dev = link->ap->private_data; - - SAS_DPRINTK("STUB %s\n", __func__); - switch (sc_reg_in) { - case SCR_STATUS: - dev->sata_dev.sstatus = val; - break; - case SCR_CONTROL: - dev->sata_dev.scontrol = val; - break; - case SCR_ERROR: - dev->sata_dev.serror = val; - break; - case SCR_ACTIVE: - dev->sata_dev.ap->link.sactive = val; - break; - default: - return -EINVAL; - } - return 0; -} - -static int sas_ata_scr_read(struct ata_link *link, unsigned int sc_reg_in, - u32 *val) -{ - struct domain_device *dev = link->ap->private_data; - - SAS_DPRINTK("STUB %s\n", __func__); - switch (sc_reg_in) { - case SCR_STATUS: - *val = dev->sata_dev.sstatus; - return 0; - case SCR_CONTROL: - *val = dev->sata_dev.scontrol; - return 0; - case SCR_ERROR: - *val = dev->sata_dev.serror; - return 0; - case SCR_ACTIVE: - *val = dev->sata_dev.ap->link.sactive; - return 0; - default: - return -EINVAL; - } -} - static struct ata_port_operations sas_sata_ops = { .prereset = ata_std_prereset, .softreset = NULL, @@ -367,8 +320,6 @@ static struct ata_port_operations sas_sata_ops = { .qc_fill_rtf = sas_ata_qc_fill_rtf, .port_start = ata_sas_port_start, .port_stop = ata_sas_port_stop, - .scr_read = sas_ata_scr_read, - .scr_write = sas_ata_scr_write }; static struct ata_port_info sata_port_info = { @@ -801,7 +752,7 @@ void sas_ata_strategy_handler(struct Scsi_Host *shost) if (!dev_is_sata(ddev)) continue; - + ata_port_printk(ap, KERN_DEBUG, "sas eh calling libata port error handler"); ata_scsi_port_error_handler(shost, ap); } @@ -834,13 +785,13 @@ int sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q, LIST_HEAD(sata_q); ap = NULL; - + list_for_each_entry_safe(cmd, n, work_q, eh_entry) { struct domain_device *ddev = cmd_to_domain_dev(cmd); if (!dev_is_sata(ddev) || TO_SAS_TASK(cmd)) continue; - if(ap && ap != ddev->sata_dev.ap) + if (ap && ap != ddev->sata_dev.ap) continue; ap = ddev->sata_dev.ap; rtn = 1; @@ -848,8 +799,21 @@ int sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q, } if (!list_empty(&sata_q)) { - ata_port_printk(ap, KERN_DEBUG,"sas eh calling libata cmd error handler\n"); + ata_port_printk(ap, KERN_DEBUG, "sas eh calling libata cmd error handler\n"); ata_scsi_cmd_error_handler(shost, ap, &sata_q); + /* + * ata's error handler may leave the cmd on the list + * so make sure they don't remain on a stack list + * about to go out of scope. + * + * This looks strange, since the commands are + * now part of no list, but the next error + * action will be ata_port_error_handler() + * which takes no list and sweeps them up + * anyway from the ata tag array. + */ + while (!list_empty(&sata_q)) + list_del_init(sata_q.next); } } while (ap); |