X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=drivers%2Fata%2Flibata-scsi.c;h=fc89590d377265258be05e0d5ff62d95e4aae1d1;hb=520d3a1a8cb3eb8794e3dbb822dbc40c20f18e52;hp=468d791a303c58cb1203c03bd51815e69918197c;hpb=c78968bb0f7714ceba1cdfa23714454fc98cefdf;p=safe%2Fjmp%2Flinux-2.6 diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 468d791..fc89590 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -45,7 +45,7 @@ #include #include #include -#include +#include #include "libata.h" @@ -53,9 +53,9 @@ typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc); -static struct ata_device * __ata_scsi_find_dev(struct ata_port *ap, +static struct ata_device *__ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev); -static struct ata_device * ata_scsi_find_dev(struct ata_port *ap, +static struct ata_device *ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev); static int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel, unsigned int id, unsigned int lun); @@ -110,6 +110,74 @@ static struct scsi_transport_template ata_scsi_transport_template = { }; +static const struct { + enum link_pm value; + const char *name; +} link_pm_policy[] = { + { NOT_AVAILABLE, "max_performance" }, + { MIN_POWER, "min_power" }, + { MAX_PERFORMANCE, "max_performance" }, + { MEDIUM_POWER, "medium_power" }, +}; + +const char *ata_scsi_lpm_get(enum link_pm policy) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(link_pm_policy); i++) + if (link_pm_policy[i].value == policy) + return link_pm_policy[i].name; + + return NULL; +} + +static ssize_t ata_scsi_lpm_put(struct class_device *class_dev, + const char *buf, size_t count) +{ + struct Scsi_Host *shost = class_to_shost(class_dev); + struct ata_port *ap = ata_shost_to_port(shost); + enum link_pm policy = 0; + int i; + + /* + * we are skipping array location 0 on purpose - this + * is because a value of NOT_AVAILABLE is displayed + * to the user as max_performance, but when the user + * writes "max_performance", they actually want the + * value to match MAX_PERFORMANCE. + */ + for (i = 1; i < ARRAY_SIZE(link_pm_policy); i++) { + const int len = strlen(link_pm_policy[i].name); + if (strncmp(link_pm_policy[i].name, buf, len) == 0 && + buf[len] == '\n') { + policy = link_pm_policy[i].value; + break; + } + } + if (!policy) + return -EINVAL; + + ata_lpm_schedule(ap, policy); + return count; +} + +static ssize_t +ata_scsi_lpm_show(struct class_device *class_dev, char *buf) +{ + struct Scsi_Host *shost = class_to_shost(class_dev); + struct ata_port *ap = ata_shost_to_port(shost); + const char *policy = + ata_scsi_lpm_get(ap->pm_policy); + + if (!policy) + return -EINVAL; + + return snprintf(buf, 23, "%s\n", policy); +} +CLASS_DEVICE_ATTR(link_power_management_policy, S_IRUGO | S_IWUSR, + ata_scsi_lpm_show, ata_scsi_lpm_put); +EXPORT_SYMBOL_GPL(class_device_attr_link_power_management_policy); + static void ata_scsi_invalid_field(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) { @@ -228,7 +296,7 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg) scsi_cmd[1] = (4 << 1); /* PIO Data-in */ scsi_cmd[2] = 0x0e; /* no off.line or cc, read from dev, - block count in sector count field */ + block count in sector count field */ data_dir = DMA_FROM_DEVICE; } else { scsi_cmd[1] = (3 << 1); /* Non-data */ @@ -252,7 +320,7 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg) /* Good values for timeout and retries? Values below from scsi_ioctl_send_command() for default case... */ cmd_result = scsi_execute(scsidev, scsi_cmd, data_dir, argbuf, argsize, - sensebuf, (10*HZ), 5, 0); + sensebuf, (10*HZ), 5, 0); if (driver_byte(cmd_result) == DRIVER_SENSE) {/* sense data available */ u8 *desc = sensebuf + 8; @@ -263,18 +331,18 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg) if (cmd_result & SAM_STAT_CHECK_CONDITION) { struct scsi_sense_hdr sshdr; scsi_normalize_sense(sensebuf, SCSI_SENSE_BUFFERSIZE, - &sshdr); - if (sshdr.sense_key==0 && - sshdr.asc==0 && sshdr.ascq==0) + &sshdr); + if (sshdr.sense_key == 0 && + sshdr.asc == 0 && sshdr.ascq == 0) cmd_result &= ~SAM_STAT_CHECK_CONDITION; } /* Send userspace a few ATA registers (same as drivers/ide) */ - if (sensebuf[0] == 0x72 && /* format is "descriptor" */ - desc[0] == 0x09 ) { /* code is "ATA Descriptor" */ - args[0] = desc[13]; /* status */ - args[1] = desc[3]; /* error */ - args[2] = desc[5]; /* sector count (0:7) */ + if (sensebuf[0] == 0x72 && /* format is "descriptor" */ + desc[0] == 0x09) { /* code is "ATA Descriptor" */ + args[0] = desc[13]; /* status */ + args[1] = desc[3]; /* error */ + args[2] = desc[5]; /* sector count (0:7) */ if (copy_to_user(arg, args, sizeof(args))) rc = -EFAULT; } @@ -350,8 +418,8 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg) struct scsi_sense_hdr sshdr; scsi_normalize_sense(sensebuf, SCSI_SENSE_BUFFERSIZE, &sshdr); - if (sshdr.sense_key==0 && - sshdr.asc==0 && sshdr.ascq==0) + if (sshdr.sense_key == 0 && + sshdr.asc == 0 && sshdr.ascq == 0) cmd_result &= ~SAM_STAT_CHECK_CONDITION; } @@ -749,6 +817,13 @@ static void ata_scsi_sdev_config(struct scsi_device *sdev) { sdev->use_10_for_rw = 1; sdev->use_10_for_ms = 1; + + /* Schedule policy is determined by ->qc_defer() callback and + * it needs to see every deferred qc. Set dev_blocked to 1 to + * prevent SCSI midlayer from automatically deferring + * requests. + */ + sdev->max_device_blocked = 1; } static void ata_scsi_dev_config(struct scsi_device *sdev, @@ -794,8 +869,6 @@ int ata_scsi_slave_config(struct scsi_device *sdev) ata_scsi_sdev_config(sdev); - blk_queue_max_phys_segments(sdev->request_queue, LIBATA_MAX_PRD); - sdev->manage_start_stop = 1; if (dev) @@ -937,6 +1010,13 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc) goto invalid_fld; /* LOEJ bit set not supported */ if (((cdb[4] >> 4) & 0xf) != 0) goto invalid_fld; /* power conditions not supported */ + + if (qc->dev->horkage & ATA_HORKAGE_SKIP_PM) { + /* the device lacks PM support, finish without doing anything */ + scmd->result = SAM_STAT_GOOD; + return 1; + } + if (cdb[4] & 0x1) { tf->nsect = 1; /* 1 sector, lba=0 */ @@ -963,7 +1043,7 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc) if ((qc->dev->flags & ATA_DFLAG_SPUNDOWN) && (system_state == SYSTEM_HALT || system_state == SYSTEM_POWER_OFF)) { - static unsigned long warned = 0; + static unsigned long warned; if (!test_and_set_bit(0, &warned)) { ata_dev_printk(qc->dev, KERN_WARNING, @@ -1028,6 +1108,9 @@ static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc) else tf->command = ATA_CMD_FLUSH; + /* flush is critical for IO integrity, consider it an IO command */ + qc->flags |= ATA_QCFLAG_IO; + return 0; } @@ -1351,29 +1434,7 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) struct ata_port *ap = qc->ap; struct scsi_cmnd *cmd = qc->scsicmd; u8 *cdb = cmd->cmnd; - int need_sense = (qc->err_mask != 0); - - /* We snoop the SET_FEATURES - Write Cache ON/OFF command, and - * schedule EH_REVALIDATE operation to update the IDENTIFY DEVICE - * cache - */ - if (ap->ops->error_handler && !need_sense) { - switch (qc->tf.command) { - case ATA_CMD_SET_FEATURES: - if ((qc->tf.feature == SETFEATURES_WC_ON) || - (qc->tf.feature == SETFEATURES_WC_OFF)) { - ap->link.eh_info.action |= ATA_EH_REVALIDATE; - ata_port_schedule_eh(ap); - } - break; - - case ATA_CMD_INIT_DEV_PARAMS: /* CHS translation changed */ - case ATA_CMD_SET_MULTI: /* multi_count changed */ - ap->link.eh_info.action |= ATA_EH_REVALIDATE; - ata_port_schedule_eh(ap); - break; - } - } + int need_sense = (qc->err_mask != 0); /* For ATA pass thru (SAT) commands, generate a sense block if * user mandated it or if there's an error. Note that if we @@ -1383,7 +1444,7 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) * was no error, SK, ASC and ASCQ will all be zero. */ if (((cdb[0] == ATA_16) || (cdb[0] == ATA_12)) && - ((cdb[2] & 0x20) || need_sense)) { + ((cdb[2] & 0x20) || need_sense)) { ata_gen_passthru_sense(qc); } else { if (!need_sense) { @@ -1416,37 +1477,6 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) } /** - * ata_scmd_need_defer - Check whether we need to defer scmd - * @dev: ATA device to which the command is addressed - * @is_io: Is the command IO (and thus possibly NCQ)? - * - * NCQ and non-NCQ commands cannot run together. As upper layer - * only knows the queue depth, we are responsible for maintaining - * exclusion. This function checks whether a new command can be - * issued to @dev. - * - * LOCKING: - * spin_lock_irqsave(host lock) - * - * RETURNS: - * 1 if deferring is needed, 0 otherwise. - */ -static int ata_scmd_need_defer(struct ata_device *dev, int is_io) -{ - struct ata_link *link = dev->link; - int is_ncq = is_io && ata_ncq_enabled(dev); - - if (is_ncq) { - if (!ata_tag_valid(link->active_tag)) - return 0; - } else { - if (!ata_tag_valid(link->active_tag) && !link->sactive) - return 0; - } - return 1; -} - -/** * ata_scsi_translate - Translate then issue SCSI command to ATA device * @dev: ATA device to which the command is addressed * @cmd: SCSI command to execute @@ -1477,14 +1507,12 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), ata_xlat_func_t xlat_func) { + struct ata_port *ap = dev->link->ap; struct ata_queued_cmd *qc; - int is_io = xlat_func == ata_scsi_rw_xlat; + int rc; VPRINTK("ENTER\n"); - if (unlikely(ata_scmd_need_defer(dev, is_io))) - goto defer; - qc = ata_scsi_qc_new(dev, cmd, done); if (!qc) goto err_mem; @@ -1508,6 +1536,11 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd, if (xlat_func(qc)) goto early_finish; + if (ap->ops->qc_defer) { + if ((rc = ap->ops->qc_defer(qc))) + goto defer; + } + /* select device, send command to hardware */ ata_qc_issue(qc); @@ -1515,7 +1548,7 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd, return 0; early_finish: - ata_qc_free(qc); + ata_qc_free(qc); qc->scsidone(cmd); DPRINTK("EXIT - early finish (good or error)\n"); return 0; @@ -1529,8 +1562,12 @@ err_mem: return 0; defer: + ata_qc_free(qc); DPRINTK("EXIT - defer\n"); - return SCSI_MLQUEUE_DEVICE_BUSY; + if (rc == ATA_DEFER_LINK) + return SCSI_MLQUEUE_DEVICE_BUSY; + else + return SCSI_MLQUEUE_HOST_BUSY; } /** @@ -1555,7 +1592,7 @@ static unsigned int ata_scsi_rbuf_get(struct scsi_cmnd *cmd, u8 **buf_out) struct scatterlist *sg = scsi_sglist(cmd); if (sg) { - buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset; + buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset; buflen = sg->length; } else { buf = NULL; @@ -1601,8 +1638,8 @@ static inline void ata_scsi_rbuf_put(struct scsi_cmnd *cmd, u8 *buf) */ void ata_scsi_rbuf_fill(struct ata_scsi_args *args, - unsigned int (*actor) (struct ata_scsi_args *args, - u8 *rbuf, unsigned int buflen)) + unsigned int (*actor) (struct ata_scsi_args *args, + u8 *rbuf, unsigned int buflen)) { u8 *rbuf; unsigned int buflen, rc; @@ -2151,7 +2188,7 @@ saving_not_supp: * None. */ unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf, - unsigned int buflen) + unsigned int buflen) { u64 last_lba = args->dev->n_sectors - 1; /* LBA of the last block */ @@ -2315,8 +2352,8 @@ static void atapi_request_sense(struct ata_queued_cmd *qc) qc->tf.feature |= ATAPI_PKT_DMA; } else { qc->tf.protocol = ATA_PROT_ATAPI; - qc->tf.lbam = (8 * 1024) & 0xff; - qc->tf.lbah = (8 * 1024) >> 8; + qc->tf.lbam = SCSI_SENSE_BUFFERSIZE; + qc->tf.lbah = 0; } qc->nbytes = SCSI_SENSE_BUFFERSIZE; @@ -2425,6 +2462,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc) struct ata_device *dev = qc->dev; int using_pio = (dev->flags & ATA_DFLAG_PIO); int nodata = (scmd->sc_data_direction == DMA_NONE); + unsigned int nbytes; memset(qc->cdb, 0, dev->cdb_len); memcpy(qc->cdb, scmd->cmnd, scmd->cmd_len); @@ -2444,14 +2482,20 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc) if (!using_pio && ata_check_atapi_dma(qc)) using_pio = 1; + /* Some controller variants snoop this value for Packet transfers + to do state machine and FIFO management. Thus we want to set it + properly, and for DMA where it is effectively meaningless */ + nbytes = min(qc->nbytes, (unsigned int)63 * 1024); + + qc->tf.lbam = (nbytes & 0xFF); + qc->tf.lbah = (nbytes >> 8); + if (using_pio || nodata) { /* no data, or PIO data xfer */ if (nodata) qc->tf.protocol = ATA_PROT_ATAPI_NODATA; else qc->tf.protocol = ATA_PROT_ATAPI; - qc->tf.lbam = (8 * 1024) & 0xff; - qc->tf.lbah = (8 * 1024) >> 8; } else { /* DMA data xfer */ qc->tf.protocol = ATA_PROT_ATAPI_DMA; @@ -2462,10 +2506,13 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc) qc->tf.feature |= ATAPI_DMADIR; } + + /* FIXME: We need to translate 0x05 READ_BLOCK_LIMITS to a MODE_SENSE + as ATAPI tape drives don't get this right otherwise */ return 0; } -static struct ata_device * ata_find_dev(struct ata_port *ap, int devno) +static struct ata_device *ata_find_dev(struct ata_port *ap, int devno) { if (ap->nr_pmp_links == 0) { if (likely(devno < ata_link_max_devices(&ap->link))) @@ -2478,8 +2525,8 @@ static struct ata_device * ata_find_dev(struct ata_port *ap, int devno) return NULL; } -static struct ata_device * __ata_scsi_find_dev(struct ata_port *ap, - const struct scsi_device *scsidev) +static struct ata_device *__ata_scsi_find_dev(struct ata_port *ap, + const struct scsi_device *scsidev) { int devno; @@ -2565,27 +2612,27 @@ static u8 ata_scsi_map_proto(u8 byte1) { switch((byte1 & 0x1e) >> 1) { - case 3: /* Non-data */ - return ATA_PROT_NODATA; - - case 6: /* DMA */ - case 10: /* UDMA Data-in */ - case 11: /* UDMA Data-Out */ - return ATA_PROT_DMA; - - case 4: /* PIO Data-in */ - case 5: /* PIO Data-out */ - return ATA_PROT_PIO; - - case 0: /* Hard Reset */ - case 1: /* SRST */ - case 8: /* Device Diagnostic */ - case 9: /* Device Reset */ - case 7: /* DMA Queued */ - case 12: /* FPDMA */ - case 15: /* Return Response Info */ - default: /* Reserved */ - break; + case 3: /* Non-data */ + return ATA_PROT_NODATA; + + case 6: /* DMA */ + case 10: /* UDMA Data-in */ + case 11: /* UDMA Data-Out */ + return ATA_PROT_DMA; + + case 4: /* PIO Data-in */ + case 5: /* PIO Data-out */ + return ATA_PROT_PIO; + + case 0: /* Hard Reset */ + case 1: /* SRST */ + case 8: /* Device Diagnostic */ + case 9: /* Device Reset */ + case 7: /* DMA Queued */ + case 12: /* FPDMA */ + case 15: /* Return Response Info */ + default: /* Reserved */ + break; } return ATA_PROT_UNKNOWN; @@ -2720,8 +2767,8 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) */ qc->nbytes = scsi_bufflen(scmd); - /* request result TF */ - qc->flags |= ATA_QCFLAG_RESULT_TF; + /* request result TF and be quiet about device error */ + qc->flags |= ATA_QCFLAG_RESULT_TF | ATA_QCFLAG_QUIET; return 0; @@ -2920,94 +2967,94 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd, args.done = done; switch(scsicmd[0]) { - /* TODO: worth improving? */ - case FORMAT_UNIT: + /* TODO: worth improving? */ + case FORMAT_UNIT: + ata_scsi_invalid_field(cmd, done); + break; + + case INQUIRY: + if (scsicmd[1] & 2) /* is CmdDt set? */ 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 switch (scsicmd[2]) { + case 0x00: + ata_scsi_rbuf_fill(&args, ata_scsiop_inq_00); break; - - case INQUIRY: - if (scsicmd[1] & 2) /* is CmdDt set? */ - 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 switch (scsicmd[2]) { - case 0x00: - ata_scsi_rbuf_fill(&args, ata_scsiop_inq_00); - break; - case 0x80: - ata_scsi_rbuf_fill(&args, ata_scsiop_inq_80); - break; - case 0x83: - ata_scsi_rbuf_fill(&args, ata_scsiop_inq_83); - break; - case 0x89: - ata_scsi_rbuf_fill(&args, ata_scsiop_inq_89); - break; - default: - ata_scsi_invalid_field(cmd, done); - break; - } + case 0x80: + ata_scsi_rbuf_fill(&args, ata_scsiop_inq_80); break; - - case MODE_SENSE: - case MODE_SENSE_10: - ata_scsi_rbuf_fill(&args, ata_scsiop_mode_sense); + case 0x83: + ata_scsi_rbuf_fill(&args, ata_scsiop_inq_83); break; - - case MODE_SELECT: /* unconditionally return */ - case MODE_SELECT_10: /* bad-field-in-cdb */ + case 0x89: + ata_scsi_rbuf_fill(&args, ata_scsiop_inq_89); + break; + default: ata_scsi_invalid_field(cmd, done); break; + } + break; + + case MODE_SENSE: + case MODE_SENSE_10: + ata_scsi_rbuf_fill(&args, ata_scsiop_mode_sense); + break; + + case MODE_SELECT: /* unconditionally return */ + case MODE_SELECT_10: /* bad-field-in-cdb */ + ata_scsi_invalid_field(cmd, done); + break; - case READ_CAPACITY: + case READ_CAPACITY: + ata_scsi_rbuf_fill(&args, ata_scsiop_read_cap); + break; + + case SERVICE_ACTION_IN: + if ((scsicmd[1] & 0x1f) == SAI_READ_CAPACITY_16) ata_scsi_rbuf_fill(&args, ata_scsiop_read_cap); - break; + else + ata_scsi_invalid_field(cmd, done); + break; - case SERVICE_ACTION_IN: - if ((scsicmd[1] & 0x1f) == SAI_READ_CAPACITY_16) - ata_scsi_rbuf_fill(&args, ata_scsiop_read_cap); - else - ata_scsi_invalid_field(cmd, done); - break; + case REPORT_LUNS: + ata_scsi_rbuf_fill(&args, ata_scsiop_report_luns); + break; - case REPORT_LUNS: - ata_scsi_rbuf_fill(&args, ata_scsiop_report_luns); - break; + case REQUEST_SENSE: + ata_scsi_set_sense(cmd, 0, 0, 0); + cmd->result = (DRIVER_SENSE << 24); + done(cmd); + break; - case REQUEST_SENSE: - ata_scsi_set_sense(cmd, 0, 0, 0); - cmd->result = (DRIVER_SENSE << 24); - done(cmd); - break; + /* if we reach this, then writeback caching is disabled, + * turning this into a no-op. + */ + case SYNCHRONIZE_CACHE: + /* fall through */ + + /* no-op's, complete with success */ + case REZERO_UNIT: + case SEEK_6: + case SEEK_10: + case TEST_UNIT_READY: + ata_scsi_rbuf_fill(&args, ata_scsiop_noop); + break; - /* if we reach this, then writeback caching is disabled, - * turning this into a no-op. - */ - case SYNCHRONIZE_CACHE: - /* fall through */ - - /* no-op's, complete with success */ - case REZERO_UNIT: - case SEEK_6: - case SEEK_10: - case TEST_UNIT_READY: + case SEND_DIAGNOSTIC: + tmp8 = scsicmd[1] & ~(1 << 3); + if ((tmp8 == 0x4) && (!scsicmd[3]) && (!scsicmd[4])) ata_scsi_rbuf_fill(&args, ata_scsiop_noop); - break; - - case SEND_DIAGNOSTIC: - tmp8 = scsicmd[1] & ~(1 << 3); - if ((tmp8 == 0x4) && (!scsicmd[3]) && (!scsicmd[4])) - ata_scsi_rbuf_fill(&args, ata_scsiop_noop); - else - ata_scsi_invalid_field(cmd, done); - break; + else + ata_scsi_invalid_field(cmd, done); + break; - /* all other commands */ - default: - ata_scsi_set_sense(cmd, ILLEGAL_REQUEST, 0x20, 0x0); - /* "Invalid command operation code" */ - done(cmd); - break; + /* all other commands */ + default: + ata_scsi_set_sense(cmd, ILLEGAL_REQUEST, 0x20, 0x0); + /* "Invalid command operation code" */ + done(cmd); + break; } } @@ -3034,6 +3081,13 @@ int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht) shost->max_channel = 1; shost->max_cmd_len = 16; + /* Schedule policy is determined by ->qc_defer() + * callback and it needs to see every deferred qc. + * Set host_blocked to 1 to prevent SCSI midlayer from + * automatically deferring requests. + */ + shost->max_host_blocked = 1; + rc = scsi_add_host(ap->scsi_host, ap->host->dev); if (rc) goto err_add; @@ -3232,21 +3286,21 @@ static void ata_scsi_handle_link_detach(struct ata_link *link) /** * ata_scsi_media_change_notify - send media change event - * @atadev: Pointer to the disk device with media change event + * @dev: Pointer to the disk device with media change event * * Tell the block layer to send a media change notification * event. * * LOCKING: - * interrupt context, may not sleep. + * spin_lock_irqsave(host lock) */ -void ata_scsi_media_change_notify(struct ata_device *atadev) +void ata_scsi_media_change_notify(struct ata_device *dev) { #ifdef OTHER_AN_PATCHES_HAVE_BEEN_APPLIED - scsi_device_event_notify(atadev->sdev, SDEV_MEDIA_CHANGE); + if (dev->sdev) + scsi_device_event_notify(dev->sdev, SDEV_MEDIA_CHANGE); #endif } -EXPORT_SYMBOL_GPL(ata_scsi_media_change_notify); /** * ata_scsi_hotplug - SCSI part of hotplug