diff options
Diffstat (limited to 'drivers/ata/libata-scsi.c')
-rw-r--r-- | drivers/ata/libata-scsi.c | 63 |
1 files changed, 31 insertions, 32 deletions
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index a21c9895408d..57f674f51b0c 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -859,18 +859,14 @@ static void ata_to_sense_error(u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc, {0xFF, 0xFF, 0xFF, 0xFF}, // END mark }; static const unsigned char stat_table[][4] = { - /* Must be first because BUSY means no other bits valid */ - {0x80, ABORTED_COMMAND, 0x47, 0x00}, - // Busy, fake parity for now - {0x40, ILLEGAL_REQUEST, 0x21, 0x04}, - // Device ready, unaligned write command - {0x20, HARDWARE_ERROR, 0x44, 0x00}, - // Device fault, internal target failure - {0x08, ABORTED_COMMAND, 0x47, 0x00}, - // Timed out in xfer, fake parity for now - {0x04, RECOVERED_ERROR, 0x11, 0x00}, - // Recovered ECC error Medium error, recovered - {0xFF, 0xFF, 0xFF, 0xFF}, // END mark + /* Busy: must be first because BUSY means no other bits valid */ + { ATA_BUSY, ABORTED_COMMAND, 0x00, 0x00 }, + /* Device fault: INTERNAL TARGET FAILURE */ + { ATA_DF, HARDWARE_ERROR, 0x44, 0x00 }, + /* Corrected data error */ + { ATA_CORR, RECOVERED_ERROR, 0x00, 0x00 }, + + { 0xFF, 0xFF, 0xFF, 0xFF }, /* END mark */ }; /* @@ -942,6 +938,8 @@ static void ata_gen_passthru_sense(struct ata_queued_cmd *qc) if (!(qc->flags & ATA_QCFLAG_RTF_FILLED)) { ata_dev_dbg(dev, "missing result TF: can't generate ATA PT sense data\n"); + if (qc->err_mask) + ata_scsi_set_sense(dev, cmd, ABORTED_COMMAND, 0, 0); return; } @@ -996,8 +994,8 @@ static void ata_gen_ata_sense(struct ata_queued_cmd *qc) if (!(qc->flags & ATA_QCFLAG_RTF_FILLED)) { ata_dev_dbg(dev, - "missing result TF: can't generate sense data\n"); - return; + "Missing result TF: reporting aborted command\n"); + goto aborted; } /* Use ata_to_sense_error() to map status register bits @@ -1008,13 +1006,15 @@ static void ata_gen_ata_sense(struct ata_queued_cmd *qc) ata_to_sense_error(tf->status, tf->error, &sense_key, &asc, &ascq); ata_scsi_set_sense(dev, cmd, sense_key, asc, ascq); - } else { - /* Could not decode error */ - ata_dev_warn(dev, "could not decode error status 0x%x err_mask 0x%x\n", - tf->status, qc->err_mask); - ata_scsi_set_sense(dev, cmd, ABORTED_COMMAND, 0, 0); return; } + + /* Could not decode error */ + ata_dev_warn(dev, + "Could not decode error 0x%x, status 0x%x (err_mask=0x%x)\n", + tf->error, tf->status, qc->err_mask); +aborted: + ata_scsi_set_sense(dev, cmd, ABORTED_COMMAND, 0, 0); } void ata_scsi_sdev_config(struct scsi_device *sdev) @@ -1923,8 +1923,7 @@ static unsigned int ata_scsiop_inq_00(struct ata_device *dev, }; for (i = 0; i < sizeof(pages); i++) { - if (pages[i] == 0xb6 && - !(dev->flags & ATA_DFLAG_ZAC)) + if (pages[i] == 0xb6 && !ata_dev_is_zac(dev)) continue; rbuf[num_pages + 4] = pages[i]; num_pages++; @@ -2181,7 +2180,7 @@ static unsigned int ata_scsiop_inq_b2(struct ata_device *dev, static unsigned int ata_scsiop_inq_b6(struct ata_device *dev, struct scsi_cmnd *cmd, u8 *rbuf) { - if (!(dev->flags & ATA_DFLAG_ZAC)) { + if (!ata_dev_is_zac(dev)) { ata_scsi_set_invalid_field(dev, cmd, 2, 0xff); return 0; } @@ -4317,9 +4316,10 @@ int __ata_scsi_queuecmd(struct scsi_cmnd *scmd, struct ata_device *dev) * scsi_queue_rq() will defer commands if scsi_host_in_recovery(). * However, this check is done without holding the ap->lock (a libata * specific lock), so we can have received an error irq since then, - * therefore we must check if EH is pending, while holding ap->lock. + * therefore we must check if EH is pending or running, while holding + * ap->lock. */ - if (ap->pflags & (ATA_PFLAG_EH_PENDING | ATA_PFLAG_EH_IN_PROGRESS)) + if (ata_port_eh_scheduled(ap)) return SCSI_MLQUEUE_DEVICE_BUSY; if (unlikely(!scmd->cmd_len)) @@ -4634,24 +4634,23 @@ void ata_scsi_scan_host(struct ata_port *ap, int sync) * ata_scsi_offline_dev - offline attached SCSI device * @dev: ATA device to offline attached SCSI device for * - * This function is called from ata_eh_hotplug() and responsible - * for taking the SCSI device attached to @dev offline. This - * function is called with host lock which protects dev->sdev - * against clearing. + * This function is called from ata_eh_detach_dev() and is responsible for + * taking the SCSI device attached to @dev offline. This function is + * called with host lock which protects dev->sdev against clearing. * * LOCKING: * spin_lock_irqsave(host lock) * * RETURNS: - * 1 if attached SCSI device exists, 0 otherwise. + * true if attached SCSI device exists, false otherwise. */ -int ata_scsi_offline_dev(struct ata_device *dev) +bool ata_scsi_offline_dev(struct ata_device *dev) { if (dev->sdev) { scsi_device_set_state(dev->sdev, SDEV_OFFLINE); - return 1; + return true; } - return 0; + return false; } /** |