From 644dd0cc494702ecd0698f467de113ace9593888 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Mon, 3 Oct 2005 15:55:19 -0400 Subject: [libata] improve device scan Replace SCSI's legacy "bang at the door" method of probing with one directly controlled by the underlying ATA transport layer. We now only call scsi_scan_target() for devices we find, rather than probing every possible channel/id within a certain range. --- drivers/scsi/libata.h | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/scsi/libata.h') diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h index d608b3a0f6fe..c7a1fa1c9abc 100644 --- a/drivers/scsi/libata.h +++ b/drivers/scsi/libata.h @@ -51,6 +51,7 @@ extern void swap_buf_le16(u16 *buf, unsigned int buf_words); /* libata-scsi.c */ +extern void ata_scsi_scan_host(struct ata_port *ap); extern void ata_to_sense_error(struct ata_queued_cmd *qc, u8 drv_stat); extern int ata_scsi_error(struct Scsi_Host *host); extern unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf, -- cgit v1.2.3 From a939c9631527053aa38aa8795a6f7203c7f20b69 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Wed, 5 Oct 2005 17:09:16 -0400 Subject: libata: move atapi_request_sense() to libata-scsi module No content changes, just moving code around. --- drivers/scsi/libata-core.c | 49 +--------------------------------------------- drivers/scsi/libata-scsi.c | 46 +++++++++++++++++++++++++++++++++++++++++++ drivers/scsi/libata.h | 3 +++ 3 files changed, 50 insertions(+), 48 deletions(-) (limited to 'drivers/scsi/libata.h') diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index ceffaef37d17..f731bbdd4236 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c @@ -71,7 +71,6 @@ static int fgb(u32 bitmap); static int ata_choose_xfer_mode(struct ata_port *ap, u8 *xfer_mode_out, unsigned int *xfer_shift_out); -static int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat); static void __ata_qc_complete(struct ata_queued_cmd *qc); static unsigned int ata_unique_id = 1; @@ -3015,52 +3014,6 @@ fsm_start: goto fsm_start; } -static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev, - struct scsi_cmnd *cmd) -{ - DECLARE_COMPLETION(wait); - struct ata_queued_cmd *qc; - unsigned long flags; - int rc; - - DPRINTK("ATAPI request sense\n"); - - qc = ata_qc_new_init(ap, dev); - BUG_ON(qc == NULL); - - /* FIXME: is this needed? */ - memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer)); - - ata_sg_init_one(qc, cmd->sense_buffer, sizeof(cmd->sense_buffer)); - qc->dma_dir = DMA_FROM_DEVICE; - - memset(&qc->cdb, 0, ap->cdb_len); - qc->cdb[0] = REQUEST_SENSE; - qc->cdb[4] = SCSI_SENSE_BUFFERSIZE; - - qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; - qc->tf.command = ATA_CMD_PACKET; - - qc->tf.protocol = ATA_PROT_ATAPI; - qc->tf.lbam = (8 * 1024) & 0xff; - qc->tf.lbah = (8 * 1024) >> 8; - qc->nbytes = SCSI_SENSE_BUFFERSIZE; - - qc->waiting = &wait; - qc->complete_fn = ata_qc_complete_noop; - - spin_lock_irqsave(&ap->host_set->lock, flags); - rc = ata_qc_issue(qc); - spin_unlock_irqrestore(&ap->host_set->lock, flags); - - if (rc) - ata_port_disable(ap); - else - wait_for_completion(&wait); - - DPRINTK("EXIT\n"); -} - /** * ata_qc_timeout - Handle timeout of queued command * @qc: Command that timed out @@ -3254,7 +3207,7 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, return qc; } -static int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat) +int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat) { return 0; } diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index 1a1ef3429e55..c58a7a19780f 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c @@ -1479,6 +1479,52 @@ void ata_scsi_badcmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), u8 done(cmd); } +void atapi_request_sense(struct ata_port *ap, struct ata_device *dev, + struct scsi_cmnd *cmd) +{ + DECLARE_COMPLETION(wait); + struct ata_queued_cmd *qc; + unsigned long flags; + int rc; + + DPRINTK("ATAPI request sense\n"); + + qc = ata_qc_new_init(ap, dev); + BUG_ON(qc == NULL); + + /* FIXME: is this needed? */ + memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer)); + + ata_sg_init_one(qc, cmd->sense_buffer, sizeof(cmd->sense_buffer)); + qc->dma_dir = DMA_FROM_DEVICE; + + memset(&qc->cdb, 0, ap->cdb_len); + qc->cdb[0] = REQUEST_SENSE; + qc->cdb[4] = SCSI_SENSE_BUFFERSIZE; + + qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; + qc->tf.command = ATA_CMD_PACKET; + + qc->tf.protocol = ATA_PROT_ATAPI; + qc->tf.lbam = (8 * 1024) & 0xff; + qc->tf.lbah = (8 * 1024) >> 8; + qc->nbytes = SCSI_SENSE_BUFFERSIZE; + + qc->waiting = &wait; + qc->complete_fn = ata_qc_complete_noop; + + spin_lock_irqsave(&ap->host_set->lock, flags); + rc = ata_qc_issue(qc); + spin_unlock_irqrestore(&ap->host_set->lock, flags); + + if (rc) + ata_port_disable(ap); + else + wait_for_completion(&wait); + + DPRINTK("EXIT\n"); +} + static int atapi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) { struct scsi_cmnd *cmd = qc->scsicmd; diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h index c7a1fa1c9abc..a4b55dc9c698 100644 --- a/drivers/scsi/libata.h +++ b/drivers/scsi/libata.h @@ -39,6 +39,7 @@ struct ata_scsi_args { /* libata-core.c */ extern int atapi_enabled; +extern int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat); extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, struct ata_device *dev); extern void ata_qc_free(struct ata_queued_cmd *qc); @@ -51,6 +52,8 @@ extern void swap_buf_le16(u16 *buf, unsigned int buf_words); /* libata-scsi.c */ +extern void atapi_request_sense(struct ata_port *ap, struct ata_device *dev, + struct scsi_cmnd *cmd); extern void ata_scsi_scan_host(struct ata_port *ap); extern void ata_to_sense_error(struct ata_queued_cmd *qc, u8 drv_stat); extern int ata_scsi_error(struct Scsi_Host *host); -- cgit v1.2.3 From 845c5834d0aa60eb1588397696e7fabbaab2d3b0 Mon Sep 17 00:00:00 2001 From: Douglas Gilbert Date: Sun, 9 Oct 2005 08:55:41 -0400 Subject: [libata scsi] add ata_scsi_set_sense helper - add extern ata_scsi_set_sense() to build SCSI fixed sense data and corresponding SCSI status Signed-off-by: Douglas Gilbert Signed-off-by: Jeff Garzik --- drivers/scsi/libata-scsi.c | 28 ++++++++++++++++++++++++++++ drivers/scsi/libata.h | 2 ++ 2 files changed, 30 insertions(+) (limited to 'drivers/scsi/libata.h') diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index 1c3a10fb3c44..bca9a5016b17 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c @@ -1450,6 +1450,34 @@ unsigned int ata_scsiop_report_luns(struct ata_scsi_args *args, u8 *rbuf, return 0; } +/** + * ata_scsi_set_sense - Set SCSI sense data and status + * @cmd: SCSI request to be handled + * @sk: SCSI-defined sense key + * @asc: SCSI-defined additional sense code + * @ascq: SCSI-defined additional sense code qualifier + * + * Helper function that builds a valid fixed format, current + * response code and the given sense key (sk), additional sense + * code (asc) and additional sense code qualifier (ascq) with + * a SCSI command status of %SAM_STAT_CHECK_CONDITION and + * DRIVER_SENSE set in the upper bits of scsi_cmnd::result . + * + * LOCKING: + * Not required + */ + +void ata_scsi_set_sense(struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq) +{ + cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; + + cmd->sense_buffer[0] = 0x70; /* fixed format, current */ + cmd->sense_buffer[2] = sk; + cmd->sense_buffer[7] = 18 - 8; /* additional sense length */ + cmd->sense_buffer[12] = asc; + cmd->sense_buffer[13] = ascq; +} + /** * ata_scsi_badcmd - End a SCSI request with an error * @cmd: SCSI request to be handled diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h index a4b55dc9c698..4622e643ffd3 100644 --- a/drivers/scsi/libata.h +++ b/drivers/scsi/libata.h @@ -80,6 +80,8 @@ extern unsigned int ata_scsiop_report_luns(struct ata_scsi_args *args, u8 *rbuf, extern void ata_scsi_badcmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), u8 asc, u8 ascq); +extern void ata_scsi_set_sense(struct scsi_cmnd *cmd, + u8 sk, u8 asc, u8 ascq); extern void ata_scsi_rbuf_fill(struct ata_scsi_args *args, unsigned int (*actor) (struct ata_scsi_args *args, u8 *rbuf, unsigned int buflen)); -- cgit v1.2.3 From ae00651020413bd7eb5fa3bd0abbd78d7cf1abb2 Mon Sep 17 00:00:00 2001 From: Douglas Gilbert Date: Sun, 9 Oct 2005 09:09:35 -0400 Subject: [libata scsi] improve scsi error handling with ata_scsi_set_sense() - change "xlat" and "fill" actors in libata-scsi so they are responsible for SCSI status and sense data when they return 1. This allows GOOD status or a specialized error to be set. - yield an error for mode sense requests for saved values [sat-r06] - remove static inlines for ata_bad_scsiop() and ata_bad_cdb() which are no longer used Signed-off-by: Douglas Gilbert Signed-off-by: Jeff Garzik --- drivers/scsi/libata-scsi.c | 184 +++++++++++++++++++++++++++++---------------- drivers/scsi/libata.h | 10 --- 2 files changed, 121 insertions(+), 73 deletions(-) (limited to 'drivers/scsi/libata.h') diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index bca9a5016b17..c64169ca7ff0 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c @@ -49,6 +49,14 @@ static struct ata_device * ata_scsi_find_dev(struct ata_port *ap, struct scsi_device *scsidev); +static void ata_scsi_invalid_field(struct scsi_cmnd *cmd, + void (*done)(struct scsi_cmnd *)) +{ + ata_scsi_set_sense(cmd, ILLEGAL_REQUEST, 0x24, 0x0); + /* "Invalid field in cbd" */ + done(cmd); +} + /** * ata_std_bios_param - generic bios head/sector/cylinder calculator used by sd. * @sdev: SCSI device for which BIOS geometry is to be determined @@ -182,7 +190,6 @@ void ata_to_sense_error(struct ata_queued_cmd *qc, u8 drv_stat) { struct scsi_cmnd *cmd = qc->scsicmd; u8 err = 0; - unsigned char *sb = cmd->sense_buffer; /* Based on the 3ware driver translation table */ static unsigned char sense_table[][4] = { /* BBD|ECC|ID|MAR */ @@ -225,8 +232,6 @@ void ata_to_sense_error(struct ata_queued_cmd *qc, u8 drv_stat) }; int i = 0; - cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; - /* * Is this an error we can process/parse */ @@ -281,11 +286,9 @@ void ata_to_sense_error(struct ata_queued_cmd *qc, u8 drv_stat) /* Look for best matches first */ if((sense_table[i][0] & err) == sense_table[i][0]) { - sb[0] = 0x70; - sb[2] = sense_table[i][1]; - sb[7] = 0x0a; - sb[12] = sense_table[i][2]; - sb[13] = sense_table[i][3]; + ata_scsi_set_sense(cmd, sense_table[i][1] /* sk */, + sense_table[i][2] /* asc */, + sense_table[i][3] /* ascq */ ); return; } i++; @@ -300,11 +303,9 @@ void ata_to_sense_error(struct ata_queued_cmd *qc, u8 drv_stat) { if(stat_table[i][0] & drv_stat) { - sb[0] = 0x70; - sb[2] = stat_table[i][1]; - sb[7] = 0x0a; - sb[12] = stat_table[i][2]; - sb[13] = stat_table[i][3]; + ata_scsi_set_sense(cmd, sense_table[i][1] /* sk */, + sense_table[i][2] /* asc */, + sense_table[i][3] /* ascq */ ); return; } i++; @@ -313,15 +314,12 @@ void ata_to_sense_error(struct ata_queued_cmd *qc, u8 drv_stat) printk(KERN_ERR "ata%u: called with no error (%02X)!\n", qc->ap->id, drv_stat); /* additional-sense-code[-qualifier] */ - sb[0] = 0x70; - sb[2] = MEDIUM_ERROR; - sb[7] = 0x0A; if (cmd->sc_data_direction == DMA_FROM_DEVICE) { - sb[12] = 0x11; /* "unrecovered read error" */ - sb[13] = 0x04; + ata_scsi_set_sense(cmd, MEDIUM_ERROR, 0x11, 0x4); + /* "unrecovered read error" */ } else { - sb[12] = 0x0C; /* "write error - */ - sb[13] = 0x02; /* auto-reallocation failed" */ + ata_scsi_set_sense(cmd, MEDIUM_ERROR, 0xc, 0x2); + /* "write error - auto-reallocation failed" */ } } @@ -430,9 +428,9 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc, ; /* ignore IMMED bit, violates sat-r05 */ } if (scsicmd[4] & 0x2) - return 1; /* LOEJ bit set not supported */ + goto invalid_fld; /* LOEJ bit set not supported */ if (((scsicmd[4] >> 4) & 0xf) != 0) - return 1; /* power conditions not supported */ + goto invalid_fld; /* power conditions not supported */ if (scsicmd[4] & 0x1) { tf->nsect = 1; /* 1 sector, lba=0 */ @@ -464,6 +462,11 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc, */ return 0; + +invalid_fld: + ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x0); + /* "Invalid field in cbd" */ + return 1; } @@ -623,20 +626,20 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) else if (scsicmd[0] == VERIFY_16) scsi_16_lba_len(scsicmd, &block, &n_block); else - return 1; + goto invalid_fld; if (!n_block) - return 1; + goto nothing_to_do; if (block >= dev_sectors) - return 1; + goto out_of_range; if ((block + n_block) > dev_sectors) - return 1; + goto out_of_range; if (lba48) { if (n_block > (64 * 1024)) - return 1; + goto invalid_fld; } else { if (n_block > 256) - return 1; + goto invalid_fld; } if (lba) { @@ -679,7 +682,7 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) Head: 0-15 Sector: 1-255*/ if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect)) - return 1; + goto out_of_range; tf->command = ATA_CMD_VERIFY; tf->nsect = n_block & 0xff; /* Sector count 0 means 256 sectors */ @@ -690,6 +693,20 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) } return 0; + +invalid_fld: + ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x0); + /* "Invalid field in cbd" */ + return 1; + +out_of_range: + ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x21, 0x0); + /* "Logical Block Address out of range" */ + return 1; + +nothing_to_do: + qc->scsicmd->result = SAM_STAT_GOOD; + return 1; } /** @@ -754,7 +771,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) break; default: DPRINTK("no-byte command\n"); - return 1; + goto invalid_fld; } /* Check and compose ATA command */ @@ -764,13 +781,13 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) * However, for ATA R/W commands, sector count 0 means * 256 or 65536 sectors, not 0 sectors as in SCSI. */ - return 1; + goto nothing_to_do; if (lba) { if (lba48) { /* The request -may- be too large for LBA48. */ if ((block >> 48) || (n_block > 65536)) - return 1; + goto out_of_range; tf->hob_nsect = (n_block >> 8) & 0xff; @@ -782,7 +799,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) /* The request -may- be too large for LBA28. */ if ((block >> 28) || (n_block > 256)) - return 1; + goto out_of_range; tf->device |= (block >> 24) & 0xf; } @@ -801,7 +818,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) /* The request -may- be too large for CHS addressing. */ if ((block >> 28) || (n_block > 256)) - return 1; + goto out_of_range; /* Convert LBA to CHS */ track = (u32)block / dev->sectors; @@ -817,7 +834,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) Head: 0-15 Sector: 1-255*/ if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect)) - return 1; + goto out_of_range; qc->nsect = n_block; tf->nsect = n_block & 0xff; /* Sector count 0 means 256 sectors */ @@ -828,6 +845,20 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) } return 0; + +invalid_fld: + ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x0); + /* "Invalid field in cbd" */ + return 1; + +out_of_range: + ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x21, 0x0); + /* "Logical Block Address out of range" */ + return 1; + +nothing_to_do: + qc->scsicmd->result = SAM_STAT_GOOD; + return 1; } static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) @@ -859,6 +890,12 @@ static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) * This function sets up an ata_queued_cmd structure for the * SCSI command, and sends that ata_queued_cmd to the hardware. * + * The xlat_func argument (actor) returns 0 if ready to execute + * ATA command, else 1 to finish translation. If 1 is returned + * then cmd->result (and possibly cmd->sense_buffer) are assumed + * to be set reflecting an error condition or clean (early) + * termination. + * * LOCKING: * spin_lock_irqsave(host_set lock) */ @@ -875,7 +912,7 @@ static void ata_scsi_translate(struct ata_port *ap, struct ata_device *dev, qc = ata_scsi_qc_new(ap, dev, cmd, done); if (!qc) - return; + goto err_mem; /* data is present; dma-map it */ if (cmd->sc_data_direction == DMA_FROM_DEVICE || @@ -883,7 +920,7 @@ static void ata_scsi_translate(struct ata_port *ap, struct ata_device *dev, if (unlikely(cmd->request_bufflen < 1)) { printk(KERN_WARNING "ata%u(%u): WARNING: zero len r/w req\n", ap->id, dev->devno); - goto err_out; + goto err_did; } if (cmd->use_sg) @@ -898,19 +935,28 @@ static void ata_scsi_translate(struct ata_port *ap, struct ata_device *dev, qc->complete_fn = ata_scsi_qc_complete; if (xlat_func(qc, scsicmd)) - goto err_out; + goto early_finish; /* select device, send command to hardware */ if (ata_qc_issue(qc)) - goto err_out; + goto err_did; VPRINTK("EXIT\n"); return; -err_out: +early_finish: + ata_qc_free(qc); + done(cmd); + DPRINTK("EXIT - early finish (good or error)\n"); + return; + +err_did: ata_qc_free(qc); - ata_bad_cdb(cmd, done); - DPRINTK("EXIT - badcmd\n"); +err_mem: + cmd->result = (DID_ERROR << 16); + done(cmd); + DPRINTK("EXIT - internal\n"); + return; } /** @@ -977,7 +1023,8 @@ static inline void ata_scsi_rbuf_put(struct scsi_cmnd *cmd, u8 *buf) * Mapping the response buffer, calling the command's handler, * and handling the handler's return value. This return value * indicates whether the handler wishes the SCSI command to be - * completed successfully, or not. + * completed successfully (0), or not (in which case cmd->result + * and sense buffer are assumed to be set). * * LOCKING: * spin_lock_irqsave(host_set lock) @@ -996,12 +1043,9 @@ void ata_scsi_rbuf_fill(struct ata_scsi_args *args, rc = actor(args, rbuf, buflen); ata_scsi_rbuf_put(cmd, rbuf); - if (rc) - ata_bad_cdb(cmd, args->done); - else { + if (rc == 0) cmd->result = SAM_STAT_GOOD; - args->done(cmd); - } + args->done(cmd); } /** @@ -1307,8 +1351,16 @@ unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf, * in the same manner) */ page_control = scsicmd[2] >> 6; - if ((page_control != 0) && (page_control != 3)) - return 1; + switch (page_control) { + case 0: /* current */ + break; /* supported */ + case 3: /* saved */ + goto saving_not_supp; + case 1: /* changeable */ + case 2: /* defaults */ + default: + goto invalid_fld; + } if (six_byte) output_len = 4; @@ -1339,7 +1391,7 @@ unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf, break; default: /* invalid page code */ - return 1; + goto invalid_fld; } if (six_byte) { @@ -1352,6 +1404,16 @@ unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf, } return 0; + +invalid_fld: + ata_scsi_set_sense(args->cmd, ILLEGAL_REQUEST, 0x24, 0x0); + /* "Invalid field in cbd" */ + return 1; + +saving_not_supp: + ata_scsi_set_sense(args->cmd, ILLEGAL_REQUEST, 0x39, 0x0); + /* "Saving parameters not supported" */ + return 1; } /** @@ -1496,13 +1558,7 @@ void ata_scsi_set_sense(struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq) void ata_scsi_badcmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), u8 asc, u8 ascq) { DPRINTK("ENTER\n"); - cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; - - cmd->sense_buffer[0] = 0x70; - cmd->sense_buffer[2] = ILLEGAL_REQUEST; - cmd->sense_buffer[7] = 14 - 8; /* addnl. sense len. FIXME: correct? */ - cmd->sense_buffer[12] = asc; - cmd->sense_buffer[13] = ascq; + ata_scsi_set_sense(cmd, ILLEGAL_REQUEST, asc, ascq); done(cmd); } @@ -1871,7 +1927,7 @@ void ata_scsi_simulate(u16 *id, case INQUIRY: if (scsicmd[1] & 2) /* is CmdDt set? */ - ata_bad_cdb(cmd, done); + ata_scsi_invalid_field(cmd, done); else if ((scsicmd[1] & 1) == 0) /* is EVPD clear? */ ata_scsi_rbuf_fill(&args, ata_scsiop_inq_std); else if (scsicmd[2] == 0x00) @@ -1881,7 +1937,7 @@ void ata_scsi_simulate(u16 *id, else if (scsicmd[2] == 0x83) ata_scsi_rbuf_fill(&args, ata_scsiop_inq_83); else - ata_bad_cdb(cmd, done); + ata_scsi_invalid_field(cmd, done); break; case MODE_SENSE: @@ -1891,7 +1947,7 @@ void ata_scsi_simulate(u16 *id, case MODE_SELECT: /* unconditionally return */ case MODE_SELECT_10: /* bad-field-in-cdb */ - ata_bad_cdb(cmd, done); + ata_scsi_invalid_field(cmd, done); break; case READ_CAPACITY: @@ -1902,7 +1958,7 @@ void ata_scsi_simulate(u16 *id, if ((scsicmd[1] & 0x1f) == SAI_READ_CAPACITY_16) ata_scsi_rbuf_fill(&args, ata_scsiop_read_cap); else - ata_bad_cdb(cmd, done); + ata_scsi_invalid_field(cmd, done); break; case REPORT_LUNS: @@ -1914,7 +1970,9 @@ void ata_scsi_simulate(u16 *id, /* all other commands */ default: - ata_bad_scsiop(cmd, done); + ata_scsi_set_sense(cmd, ILLEGAL_REQUEST, 0x20, 0x0); + /* "Invalid command operation code" */ + done(cmd); break; } } diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h index 4622e643ffd3..a18f2ac1d4a1 100644 --- a/drivers/scsi/libata.h +++ b/drivers/scsi/libata.h @@ -86,14 +86,4 @@ extern void ata_scsi_rbuf_fill(struct ata_scsi_args *args, unsigned int (*actor) (struct ata_scsi_args *args, u8 *rbuf, unsigned int buflen)); -static inline void ata_bad_scsiop(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) -{ - ata_scsi_badcmd(cmd, done, 0x20, 0x00); -} - -static inline void ata_bad_cdb(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) -{ - ata_scsi_badcmd(cmd, done, 0x24, 0x00); -} - #endif /* __LIBATA_H__ */ -- cgit v1.2.3