diff options
author | Jeff Garzik <jgarzik@pobox.com> | 2005-11-14 14:50:05 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-11-14 14:50:05 -0500 |
commit | c6e6e666cbfe40f0d7fb1a293ff6332973acac37 (patch) | |
tree | 21609c228d8aaf1f9a2217f7fd08266ed669f5bc /drivers | |
parent | 2c13b7cee045af689b36349c2bc6a9ed6e3d73fa (diff) |
[libata] REQUEST SENSE handling fixes
- Move ATAPI check-condition handling out of the timeout handler
- Use multi-qc-issue feature to issue REQUEST SENSE ATAPI PACKET
command upon receiving an ATAPI check-condition.
This cleans things up a lot, and eliminates a nasty recursion bug.
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/libata-core.c | 22 | ||||
-rw-r--r-- | drivers/scsi/libata-scsi.c | 77 | ||||
-rw-r--r-- | drivers/scsi/libata.h | 2 |
3 files changed, 43 insertions, 58 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 3855bfa8e8d4..ba1eb8b38e00 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -3284,32 +3284,11 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc) | |||
3284 | { | 3284 | { |
3285 | struct ata_port *ap = qc->ap; | 3285 | struct ata_port *ap = qc->ap; |
3286 | struct ata_host_set *host_set = ap->host_set; | 3286 | struct ata_host_set *host_set = ap->host_set; |
3287 | struct ata_device *dev = qc->dev; | ||
3288 | u8 host_stat = 0, drv_stat; | 3287 | u8 host_stat = 0, drv_stat; |
3289 | unsigned long flags; | 3288 | unsigned long flags; |
3290 | 3289 | ||
3291 | DPRINTK("ENTER\n"); | 3290 | DPRINTK("ENTER\n"); |
3292 | 3291 | ||
3293 | /* FIXME: doesn't this conflict with timeout handling? */ | ||
3294 | if (qc->dev->class == ATA_DEV_ATAPI && qc->scsicmd) { | ||
3295 | struct scsi_cmnd *cmd = qc->scsicmd; | ||
3296 | |||
3297 | if (!(cmd->eh_eflags & SCSI_EH_CANCEL_CMD)) { | ||
3298 | |||
3299 | /* finish completing original command */ | ||
3300 | spin_lock_irqsave(&host_set->lock, flags); | ||
3301 | __ata_qc_complete(qc); | ||
3302 | spin_unlock_irqrestore(&host_set->lock, flags); | ||
3303 | |||
3304 | atapi_request_sense(ap, dev, cmd); | ||
3305 | |||
3306 | cmd->result = (CHECK_CONDITION << 1) | (DID_OK << 16); | ||
3307 | scsi_finish_command(cmd); | ||
3308 | |||
3309 | goto out; | ||
3310 | } | ||
3311 | } | ||
3312 | |||
3313 | spin_lock_irqsave(&host_set->lock, flags); | 3292 | spin_lock_irqsave(&host_set->lock, flags); |
3314 | 3293 | ||
3315 | /* hack alert! We cannot use the supplied completion | 3294 | /* hack alert! We cannot use the supplied completion |
@@ -3348,7 +3327,6 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc) | |||
3348 | 3327 | ||
3349 | spin_unlock_irqrestore(&host_set->lock, flags); | 3328 | spin_unlock_irqrestore(&host_set->lock, flags); |
3350 | 3329 | ||
3351 | out: | ||
3352 | DPRINTK("EXIT\n"); | 3330 | DPRINTK("EXIT\n"); |
3353 | } | 3331 | } |
3354 | 3332 | ||
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index 0df4b682965d..3b4ca55a3332 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c | |||
@@ -1955,22 +1955,44 @@ void ata_scsi_badcmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), u8 | |||
1955 | done(cmd); | 1955 | done(cmd); |
1956 | } | 1956 | } |
1957 | 1957 | ||
1958 | void atapi_request_sense(struct ata_port *ap, struct ata_device *dev, | 1958 | static int atapi_sense_complete(struct ata_queued_cmd *qc,unsigned int err_mask) |
1959 | struct scsi_cmnd *cmd) | ||
1960 | { | 1959 | { |
1961 | DECLARE_COMPLETION(wait); | 1960 | if (err_mask && ((err_mask & AC_ERR_DEV) == 0)) |
1962 | struct ata_queued_cmd *qc; | 1961 | /* FIXME: not quite right; we don't want the |
1963 | unsigned long flags; | 1962 | * translation of taskfile registers into |
1964 | int rc; | 1963 | * a sense descriptors, since that's only |
1964 | * correct for ATA, not ATAPI | ||
1965 | */ | ||
1966 | ata_gen_ata_desc_sense(qc); | ||
1965 | 1967 | ||
1966 | DPRINTK("ATAPI request sense\n"); | 1968 | qc->scsidone(qc->scsicmd); |
1969 | return 0; | ||
1970 | } | ||
1967 | 1971 | ||
1968 | qc = ata_qc_new_init(ap, dev); | 1972 | /* is it pointless to prefer PIO for "safety reasons"? */ |
1969 | BUG_ON(qc == NULL); | 1973 | static inline int ata_pio_use_silly(struct ata_port *ap) |
1974 | { | ||
1975 | return (ap->flags & ATA_FLAG_PIO_DMA); | ||
1976 | } | ||
1977 | |||
1978 | static void atapi_request_sense(struct ata_queued_cmd *qc) | ||
1979 | { | ||
1980 | struct ata_port *ap = qc->ap; | ||
1981 | struct scsi_cmnd *cmd = qc->scsicmd; | ||
1982 | |||
1983 | DPRINTK("ATAPI request sense\n"); | ||
1970 | 1984 | ||
1971 | /* FIXME: is this needed? */ | 1985 | /* FIXME: is this needed? */ |
1972 | memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer)); | 1986 | memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer)); |
1973 | 1987 | ||
1988 | ap->ops->tf_read(ap, &qc->tf); | ||
1989 | |||
1990 | /* fill these in, for the case where they are -not- overwritten */ | ||
1991 | cmd->sense_buffer[0] = 0x70; | ||
1992 | cmd->sense_buffer[2] = qc->tf.feature >> 4; | ||
1993 | |||
1994 | ata_qc_reinit(qc); | ||
1995 | |||
1974 | ata_sg_init_one(qc, cmd->sense_buffer, sizeof(cmd->sense_buffer)); | 1996 | ata_sg_init_one(qc, cmd->sense_buffer, sizeof(cmd->sense_buffer)); |
1975 | qc->dma_dir = DMA_FROM_DEVICE; | 1997 | qc->dma_dir = DMA_FROM_DEVICE; |
1976 | 1998 | ||
@@ -1981,22 +2003,20 @@ void atapi_request_sense(struct ata_port *ap, struct ata_device *dev, | |||
1981 | qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; | 2003 | qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; |
1982 | qc->tf.command = ATA_CMD_PACKET; | 2004 | qc->tf.command = ATA_CMD_PACKET; |
1983 | 2005 | ||
1984 | qc->tf.protocol = ATA_PROT_ATAPI; | 2006 | if (ata_pio_use_silly(ap)) { |
1985 | qc->tf.lbam = (8 * 1024) & 0xff; | 2007 | qc->tf.protocol = ATA_PROT_ATAPI_DMA; |
1986 | qc->tf.lbah = (8 * 1024) >> 8; | 2008 | qc->tf.feature |= ATAPI_PKT_DMA; |
2009 | } else { | ||
2010 | qc->tf.protocol = ATA_PROT_ATAPI; | ||
2011 | qc->tf.lbam = (8 * 1024) & 0xff; | ||
2012 | qc->tf.lbah = (8 * 1024) >> 8; | ||
2013 | } | ||
1987 | qc->nbytes = SCSI_SENSE_BUFFERSIZE; | 2014 | qc->nbytes = SCSI_SENSE_BUFFERSIZE; |
1988 | 2015 | ||
1989 | qc->waiting = &wait; | 2016 | qc->complete_fn = atapi_sense_complete; |
1990 | qc->complete_fn = ata_qc_complete_noop; | ||
1991 | 2017 | ||
1992 | spin_lock_irqsave(&ap->host_set->lock, flags); | 2018 | if (ata_qc_issue(qc)) |
1993 | rc = ata_qc_issue(qc); | 2019 | ata_qc_complete(qc, AC_ERR_OTHER); |
1994 | spin_unlock_irqrestore(&ap->host_set->lock, flags); | ||
1995 | |||
1996 | if (rc) | ||
1997 | ata_port_disable(ap); | ||
1998 | else | ||
1999 | wait_for_completion(&wait); | ||
2000 | 2020 | ||
2001 | DPRINTK("EXIT\n"); | 2021 | DPRINTK("EXIT\n"); |
2002 | } | 2022 | } |
@@ -2008,19 +2028,8 @@ static int atapi_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask) | |||
2008 | VPRINTK("ENTER, err_mask 0x%X\n", err_mask); | 2028 | VPRINTK("ENTER, err_mask 0x%X\n", err_mask); |
2009 | 2029 | ||
2010 | if (unlikely(err_mask & AC_ERR_DEV)) { | 2030 | if (unlikely(err_mask & AC_ERR_DEV)) { |
2011 | DPRINTK("request check condition\n"); | ||
2012 | |||
2013 | /* FIXME: command completion with check condition | ||
2014 | * but no sense causes the error handler to run, | ||
2015 | * which then issues REQUEST SENSE, fills in the sense | ||
2016 | * buffer, and completes the command (for the second | ||
2017 | * time). We need to issue REQUEST SENSE some other | ||
2018 | * way, to avoid completing the command twice. | ||
2019 | */ | ||
2020 | cmd->result = SAM_STAT_CHECK_CONDITION; | 2031 | cmd->result = SAM_STAT_CHECK_CONDITION; |
2021 | 2032 | atapi_request_sense(qc); | |
2022 | qc->scsidone(cmd); | ||
2023 | |||
2024 | return 1; | 2033 | return 1; |
2025 | } | 2034 | } |
2026 | 2035 | ||
diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h index fad051ca4672..74a84e0ec0a4 100644 --- a/drivers/scsi/libata.h +++ b/drivers/scsi/libata.h | |||
@@ -54,8 +54,6 @@ extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg); | |||
54 | 54 | ||
55 | 55 | ||
56 | /* libata-scsi.c */ | 56 | /* libata-scsi.c */ |
57 | extern void atapi_request_sense(struct ata_port *ap, struct ata_device *dev, | ||
58 | struct scsi_cmnd *cmd); | ||
59 | extern void ata_scsi_scan_host(struct ata_port *ap); | 57 | extern void ata_scsi_scan_host(struct ata_port *ap); |
60 | extern int ata_scsi_error(struct Scsi_Host *host); | 58 | extern int ata_scsi_error(struct Scsi_Host *host); |
61 | extern unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf, | 59 | extern unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf, |