From 2b06719153089aa8f5ac577f15f8aa8e5b5fe357 Mon Sep 17 00:00:00 2001 From: Mark Lord Date: Wed, 7 Feb 2007 11:40:12 -0500 Subject: libata bugfix: HDIO_DRIVE_TASK I was trying to use HDIO_DRIVE_TASK for something today, and discovered that the libata implementation does not copy over the upper four LBA bits from args[6]. This is serious, as any tools using this ioctl would have their commands applied to the wrong sectors on the drive, possibly resulting in disk corruption. Ideally, newer apps should use SG_IO/ATA_16 directly, avoiding this bug. But with libata poised to displace drivers/ide, better compatibility here is a must. This patch fixes libata to use the upper four LBA bits passed in from the ioctl. The original drivers/ide implementation copies over all bits except for the master/slave select bit. With this patch, libata will copy only the four high-order LBA bits, just in case there are assumptions elsewhere in libata (?). Signed-Off-By: Mark Lord Signed-off-by: Jeff Garzik --- drivers/ata/libata-scsi.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/ata/libata-scsi.c') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 0009818a4306..d1bf1ca4f717 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -333,6 +333,7 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg) scsi_cmd[8] = args[3]; scsi_cmd[10] = args[4]; scsi_cmd[12] = args[5]; + scsi_cmd[13] = args[6] & 0x0f; scsi_cmd[14] = args[0]; /* Good values for timeout and retries? Values below -- cgit v1.2.3-59-g8ed1b From 4d05447ec702364b8a2aebb4d625b16479268575 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 18 Feb 2007 02:24:37 +0900 Subject: libata: fix probe_ent alloc/free bugs ata_probe_ent_alloc() had a temporary hack such that devm_kzalloc() was used for allocation if devres had been previously initialized on the device; otherwise, plain kzalloc() was used. This was to make the code useable from both the old and devres-aware libata drivers during transition. This hack made ata_sas_port_alloc() unable to determine how the probe_ent is allocated, causing double free in some cases. Remove the now-unneeded hack and make ata_sas_port_alloc() use devm_kfree(). Signed-off-by: Tejun Heo Cc: James Bottomley Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 6 +----- drivers/ata/libata-scsi.c | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers/ata/libata-scsi.c') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 407e7e15c252..794f327e398a 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -5948,11 +5948,7 @@ ata_probe_ent_alloc(struct device *dev, const struct ata_port_info *port) { struct ata_probe_ent *probe_ent; - /* XXX - the following if can go away once all LLDs are managed */ - if (!list_empty(&dev->devres_head)) - probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL); - else - probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL); + probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL); if (!probe_ent) { printk(KERN_ERR DRV_NAME "(%s): out of memory\n", kobject_name(&(dev->kobj))); diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index d1bf1ca4f717..7bb782b5ce0c 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -3235,7 +3235,7 @@ struct ata_port *ata_sas_port_alloc(struct ata_host *host, ata_port_init(ap, host, ent, 0); ap->lock = shost->host_lock; - kfree(ent); + devm_kfree(host->dev, ent); return ap; } EXPORT_SYMBOL_GPL(ata_sas_port_alloc); -- cgit v1.2.3-59-g8ed1b From fcf1bf1584647f9fd864c193fee81840c4c5ce41 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 20 Feb 2007 23:27:06 +0900 Subject: libata: fix ata_scmd_need_defer() Fix ata_scmd_need_defer() such that... * whether NCQ is used or not is exactly determined using the same criteria as the issue path. * defer-check is performed in all cases. This fixes race condition where turning off NCQ on the fly causes non-NCQ commands sneak into NCQ phase. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/libata-scsi.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/ata/libata-scsi.c') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 7bb782b5ce0c..aa6cb6dcec41 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1496,11 +1496,9 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) static int ata_scmd_need_defer(struct ata_device *dev, int is_io) { struct ata_port *ap = dev->ap; + int is_ncq = is_io && ata_ncq_enabled(dev); - if (!(dev->flags & ATA_DFLAG_NCQ)) - return 0; - - if (is_io) { + if (is_ncq) { if (!ata_tag_valid(ap->active_tag)) return 0; } else { -- cgit v1.2.3-59-g8ed1b From c3c70c443c2ef1fce31f201a93780c884b903993 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 20 Feb 2007 23:31:22 +0900 Subject: libata: fix ata_scsi_change_queue_depth() Fix ata_scsi_change_queue_depth() such that... * NCQ on/off is exactly determined using the same logic as the issue path. * queue depth is adjusted to 1 if NCQ is not enabled. * -EINVAL is returned if requested action is ignored due to limitations. This fixes the bug which allows queue depth to be increased on blacklisted NCQ hosts/devices. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/libata-scsi.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) (limited to 'drivers/ata/libata-scsi.c') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index aa6cb6dcec41..48e388800f5a 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -987,29 +987,32 @@ int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth) struct ata_port *ap = ata_shost_to_port(sdev->host); struct ata_device *dev; unsigned long flags; - int max_depth; - if (queue_depth < 1) + if (queue_depth < 1 || queue_depth == sdev->queue_depth) return sdev->queue_depth; dev = ata_scsi_find_dev(ap, sdev); if (!dev || !ata_dev_enabled(dev)) return sdev->queue_depth; - max_depth = min(sdev->host->can_queue, ata_id_queue_depth(dev->id)); - max_depth = min(ATA_MAX_QUEUE - 1, max_depth); - if (queue_depth > max_depth) - queue_depth = max_depth; - - scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, queue_depth); - + /* NCQ enabled? */ spin_lock_irqsave(ap->lock, flags); - if (queue_depth > 1) - dev->flags &= ~ATA_DFLAG_NCQ_OFF; - else + dev->flags &= ~ATA_DFLAG_NCQ_OFF; + if (queue_depth == 1 || !ata_ncq_enabled(dev)) { dev->flags |= ATA_DFLAG_NCQ_OFF; + queue_depth = 1; + } spin_unlock_irqrestore(ap->lock, flags); + /* limit and apply queue depth */ + queue_depth = min(queue_depth, sdev->host->can_queue); + queue_depth = min(queue_depth, ata_id_queue_depth(dev->id)); + queue_depth = min(queue_depth, ATA_MAX_QUEUE - 1); + + if (sdev->queue_depth == queue_depth) + return -EINVAL; + + scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, queue_depth); return queue_depth; } -- cgit v1.2.3-59-g8ed1b From 44877b4e22f391d39c6589412106a3668e81a05b Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 21 Feb 2007 01:06:51 +0900 Subject: libata: s/ap->id/ap->print_id/g ata_port has two different id fields - id and port_no. id is system-wide 1-based unique id for the port while port_no is 0-based host-wide port number. The former is primarily used to identify the ATA port to the user in printk messages while the latter is used in various places in libata core and LLDs to index the port inside the host. The two fields feel quite similar and sometimes ap->id is used in place of ap->port_no, which is very difficult to spot. This patch renames ap->id to ap->print_id to reduce the possibility of such bugs. Some printk messages are adjusted such that id string (ata%u[.%u]) isn't printed twice and/or to use ata_*_printk() instead of hardcoded id format. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 58 +++++++++++++++++++++++------------------------ drivers/ata/libata-eh.c | 4 ++-- drivers/ata/libata-scsi.c | 8 +++---- drivers/ata/libata-sff.c | 2 +- drivers/ata/pata_sis.c | 4 ++-- drivers/ata/pdc_adma.c | 2 +- drivers/ata/sata_mv.c | 2 +- drivers/ata/sata_qstor.c | 2 +- drivers/ata/sata_sx4.c | 14 ++++++------ include/linux/libata.h | 8 +++---- 10 files changed, 52 insertions(+), 52 deletions(-) (limited to 'drivers/ata/libata-scsi.c') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 3adc2cf61f14..d3b4e25074c1 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -72,7 +72,7 @@ static unsigned int ata_dev_init_params(struct ata_device *dev, static unsigned int ata_dev_set_xfermode(struct ata_device *dev); static void ata_dev_xfermask(struct ata_device *dev); -static unsigned int ata_unique_id = 1; +static unsigned int ata_print_id = 1; static struct workqueue_struct *ata_wq; struct workqueue_struct *ata_aux_wq; @@ -891,8 +891,8 @@ void ata_dev_select(struct ata_port *ap, unsigned int device, unsigned int wait, unsigned int can_sleep) { if (ata_msg_probe(ap)) - ata_port_printk(ap, KERN_INFO, "ata_dev_select: ENTER, ata%u: " - "device %u, wait %u\n", ap->id, device, wait); + ata_port_printk(ap, KERN_INFO, "ata_dev_select: ENTER, " + "device %u, wait %u\n", device, wait); if (wait) ata_wait_idle(ap); @@ -1392,8 +1392,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, int rc; if (ata_msg_ctl(ap)) - ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER, host %u, dev %u\n", - __FUNCTION__, ap->id, dev->devno); + ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __FUNCTION__); ata_dev_select(ap, dev->devno, 1, 1); /* select device 0/1 */ @@ -1430,7 +1429,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, if (err_mask) { if (err_mask & AC_ERR_NODEV_HINT) { DPRINTK("ata%u.%d: NODEV after polling detection\n", - ap->id, dev->devno); + ap->print_id, dev->devno); return -ENOENT; } @@ -1558,15 +1557,13 @@ int ata_dev_configure(struct ata_device *dev) int rc; if (!ata_dev_enabled(dev) && ata_msg_info(ap)) { - ata_dev_printk(dev, KERN_INFO, - "%s: ENTER/EXIT (host %u, dev %u) -- nodev\n", - __FUNCTION__, ap->id, dev->devno); + ata_dev_printk(dev, KERN_INFO, "%s: ENTER/EXIT -- nodev\n", + __FUNCTION__); return 0; } if (ata_msg_probe(ap)) - ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER, host %u, dev %u\n", - __FUNCTION__, ap->id, dev->devno); + ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __FUNCTION__); /* set _SDD */ rc = ata_acpi_push_id(ap, dev->devno); @@ -1610,8 +1607,9 @@ int ata_dev_configure(struct ata_device *dev) if (dev->class == ATA_DEV_ATA) { if (ata_id_is_cfa(id)) { if (id[162] & 1) /* CPRM may make this media unusable */ - ata_dev_printk(dev, KERN_WARNING, "ata%u: device %u supports DRM functions and may not be fully accessable.\n", - ap->id, dev->devno); + ata_dev_printk(dev, KERN_WARNING, + "supports DRM functions and may " + "not be fully accessable.\n"); snprintf(revbuf, 7, "CFA"); } else @@ -2650,7 +2648,7 @@ static unsigned int ata_bus_softreset(struct ata_port *ap, { struct ata_ioports *ioaddr = &ap->ioaddr; - DPRINTK("ata%u: bus reset via SRST\n", ap->id); + DPRINTK("ata%u: bus reset via SRST\n", ap->print_id); /* software reset. causes dev0 to be selected */ iowrite8(ap->ctl, ioaddr->ctl_addr); @@ -2710,7 +2708,7 @@ void ata_bus_reset(struct ata_port *ap) u8 err; unsigned int dev0, dev1 = 0, devmask = 0; - DPRINTK("ENTER, host %u, port %u\n", ap->id, ap->port_no); + DPRINTK("ENTER, host %u, port %u\n", ap->print_id, ap->port_no); /* determine if device 0/1 are present */ if (ap->flags & ATA_FLAG_SATA_RESET) @@ -3779,7 +3777,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc) struct scatterlist *lsg = &sg[qc->n_elem - 1]; int n_elem, pre_n_elem, dir, trim_sg = 0; - VPRINTK("ENTER, ata%u\n", ap->id); + VPRINTK("ENTER, ata%u\n", ap->print_id); WARN_ON(!(qc->flags & ATA_QCFLAG_SG)); /* we must lengthen transfers to end on a 32-bit boundary */ @@ -4180,7 +4178,7 @@ static void atapi_pio_bytes(struct ata_queued_cmd *qc) if (do_write != i_write) goto err_out; - VPRINTK("ata%u: xfering %d bytes\n", ap->id, bytes); + VPRINTK("ata%u: xfering %d bytes\n", ap->print_id, bytes); __atapi_pio_bytes(qc, bytes); @@ -4297,7 +4295,7 @@ int ata_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc, fsm_start: DPRINTK("ata%u: protocol %d task_state %d (dev_stat 0x%X)\n", - ap->id, qc->tf.protocol, ap->hsm_task_state, status); + ap->print_id, qc->tf.protocol, ap->hsm_task_state, status); switch (ap->hsm_task_state) { case HSM_ST_FIRST: @@ -4330,8 +4328,8 @@ fsm_start: * let the EH abort the command or reset the device. */ if (unlikely(status & (ATA_ERR | ATA_DF))) { - printk(KERN_WARNING "ata%d: DRQ=1 with device error, dev_stat 0x%X\n", - ap->id, status); + ata_port_printk(ap, KERN_WARNING, "DRQ=1 with device " + "error, dev_stat 0x%X\n", status); qc->err_mask |= AC_ERR_HSM; ap->hsm_task_state = HSM_ST_ERR; goto fsm_start; @@ -4388,8 +4386,9 @@ fsm_start: * let the EH abort the command or reset the device. */ if (unlikely(status & (ATA_ERR | ATA_DF))) { - printk(KERN_WARNING "ata%d: DRQ=1 with device error, dev_stat 0x%X\n", - ap->id, status); + ata_port_printk(ap, KERN_WARNING, "DRQ=1 with " + "device error, dev_stat 0x%X\n", + status); qc->err_mask |= AC_ERR_HSM; ap->hsm_task_state = HSM_ST_ERR; goto fsm_start; @@ -4475,7 +4474,7 @@ fsm_start: /* no more data to transfer */ DPRINTK("ata%u: dev %u command complete, drv_stat 0x%x\n", - ap->id, qc->dev->devno, status); + ap->print_id, qc->dev->devno, status); WARN_ON(qc->err_mask); @@ -5017,7 +5016,7 @@ inline unsigned int ata_host_intr (struct ata_port *ap, u8 status, host_stat = 0; VPRINTK("ata%u: protocol %d task_state %d\n", - ap->id, qc->tf.protocol, ap->hsm_task_state); + ap->print_id, qc->tf.protocol, ap->hsm_task_state); /* Check whether we are expecting interrupt in this state */ switch (ap->hsm_task_state) { @@ -5038,7 +5037,8 @@ inline unsigned int ata_host_intr (struct ata_port *ap, qc->tf.protocol == ATA_PROT_ATAPI_DMA) { /* check status of DMA engine */ host_stat = ap->ops->bmdma_status(ap); - VPRINTK("ata%u: host_stat 0x%X\n", ap->id, host_stat); + VPRINTK("ata%u: host_stat 0x%X\n", + ap->print_id, host_stat); /* if it's not our irq... */ if (!(host_stat & ATA_DMA_INTR)) @@ -5497,7 +5497,7 @@ void ata_port_init(struct ata_port *ap, struct ata_host *host, ap->lock = &host->lock; ap->flags = ATA_FLAG_DISABLED; - ap->id = ata_unique_id++; + ap->print_id = ata_print_id++; ap->ctl = ATA_DEVCTL_OBS; ap->host = host; ap->dev = ent->dev; @@ -5568,7 +5568,7 @@ static void ata_port_init_shost(struct ata_port *ap, struct Scsi_Host *shost) { ap->scsi_host = shost; - shost->unique_id = ap->id; + shost->unique_id = ap->print_id; shost->max_id = 16; shost->max_lun = 1; shost->max_channel = 1; @@ -5832,9 +5832,9 @@ int ata_device_add(const struct ata_probe_ent *ent) /* wait for EH to finish */ ata_port_wait_eh(ap); } else { - DPRINTK("ata%u: bus probe begin\n", ap->id); + DPRINTK("ata%u: bus probe begin\n", ap->print_id); rc = ata_bus_probe(ap); - DPRINTK("ata%u: bus probe end\n", ap->id); + DPRINTK("ata%u: bus probe end\n", ap->print_id); if (rc) { /* FIXME: do something useful here? diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 31738627ec64..cad0d6db6df5 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -588,7 +588,7 @@ static void __ata_port_freeze(struct ata_port *ap) ap->pflags |= ATA_PFLAG_FROZEN; - DPRINTK("ata%u port frozen\n", ap->id); + DPRINTK("ata%u port frozen\n", ap->print_id); } /** @@ -661,7 +661,7 @@ void ata_eh_thaw_port(struct ata_port *ap) spin_unlock_irqrestore(ap->lock, flags); - DPRINTK("ata%u port thawed\n", ap->id); + DPRINTK("ata%u port thawed\n", ap->print_id); } static void ata_eh_scsidone(struct scsi_cmnd *scmd) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 48e388800f5a..00a9a6c8f83c 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -782,7 +782,7 @@ static void ata_gen_passthru_sense(struct ata_queued_cmd *qc) */ if (qc->err_mask || tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) { - ata_to_sense_error(qc->ap->id, tf->command, tf->feature, + ata_to_sense_error(qc->ap->print_id, tf->command, tf->feature, &sb[1], &sb[2], &sb[3], verbose); sb[1] &= 0x0f; } @@ -855,7 +855,7 @@ static void ata_gen_ata_sense(struct ata_queued_cmd *qc) */ if (qc->err_mask || tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) { - ata_to_sense_error(qc->ap->id, tf->command, tf->feature, + ata_to_sense_error(qc->ap->print_id, tf->command, tf->feature, &sb[1], &sb[2], &sb[3], verbose); sb[1] &= 0x0f; } @@ -1473,7 +1473,7 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) } if (need_sense && !ap->ops->error_handler) - ata_dump_status(ap->id, &qc->result_tf); + ata_dump_status(ap->print_id, &qc->result_tf); qc->scsidone(cmd); @@ -2776,7 +2776,7 @@ static inline void ata_scsi_dump_cdb(struct ata_port *ap, u8 *scsicmd = cmd->cmnd; DPRINTK("CDB (%u:%d,%d,%d) %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", - ap->id, + ap->print_id, scsidev->channel, scsidev->id, scsidev->lun, scsicmd[0], scsicmd[1], scsicmd[2], scsicmd[3], scsicmd[4], scsicmd[5], scsicmd[6], scsicmd[7], diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 16bc3e35bdd4..7fea094e6d3a 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -175,7 +175,7 @@ void ata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) */ void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf) { - DPRINTK("ata%u: cmd 0x%X\n", ap->id, tf->command); + DPRINTK("ata%u: cmd 0x%X\n", ap->print_id, tf->command); iowrite8(tf->command, ap->ioaddr.command_addr); ata_pause(ap); diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c index 0a17a95e0504..efa530b43c02 100644 --- a/drivers/ata/pata_sis.c +++ b/drivers/ata/pata_sis.c @@ -150,7 +150,7 @@ static int sis_66_pre_reset(struct ata_port *ap) if (!pci_test_config_bits(pdev, &sis_enable_bits[ap->port_no])) { ata_port_disable(ap); - printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); + ata_port_printk(ap, KERN_INFO, "port disabled. ignoring.\n"); return 0; } /* Older chips keep cable detect in bits 4/5 of reg 0x48 */ @@ -196,7 +196,7 @@ static int sis_old_pre_reset(struct ata_port *ap) if (!pci_test_config_bits(pdev, &sis_enable_bits[ap->port_no])) { ata_port_disable(ap); - printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); + ata_port_printk(ap, KERN_INFO, "port disabled. ignoring.\n"); return 0; } ap->cbl = ATA_CBL_PATA40; diff --git a/drivers/ata/pdc_adma.c b/drivers/ata/pdc_adma.c index 857ac23217ab..37bab32d74d6 100644 --- a/drivers/ata/pdc_adma.c +++ b/drivers/ata/pdc_adma.c @@ -498,7 +498,7 @@ static inline unsigned int adma_intr_mmio(struct ata_host *host) if ((status & ATA_BUSY)) continue; DPRINTK("ata%u: protocol %d (dev_stat 0x%X)\n", - ap->id, qc->tf.protocol, status); + ap->print_id, qc->tf.protocol, status); /* complete taskfile transaction */ pp->state = adma_state_idle; diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index c73aa3bbaa3e..06867b92c9c7 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -1276,7 +1276,7 @@ static void mv_err_intr(struct ata_port *ap, int reset_allowed) pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN; } DPRINTK(KERN_ERR "ata%u: port error; EDMA err cause: 0x%08x " - "SERR: 0x%08x\n", ap->id, edma_err_cause, serr); + "SERR: 0x%08x\n", ap->print_id, edma_err_cause, serr); /* Clear EDMA now that SERR cleanup done */ writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c index 6097d8f2a0c0..1558571be0ee 100644 --- a/drivers/ata/sata_qstor.c +++ b/drivers/ata/sata_qstor.c @@ -446,7 +446,7 @@ static inline unsigned int qs_intr_mmio(struct ata_host *host) if ((status & ATA_BUSY)) continue; DPRINTK("ata%u: protocol %d (dev_stat 0x%X)\n", - ap->id, qc->tf.protocol, status); + ap->print_id, qc->tf.protocol, status); /* complete taskfile transaction */ pp->state = qs_state_idle; diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c index 0ebd77b080d6..4fb8bfcefc0d 100644 --- a/drivers/ata/sata_sx4.c +++ b/drivers/ata/sata_sx4.c @@ -421,7 +421,7 @@ static void pdc20621_dma_prep(struct ata_queued_cmd *qc) WARN_ON(!(qc->flags & ATA_QCFLAG_DMAMAP)); - VPRINTK("ata%u: ENTER\n", ap->id); + VPRINTK("ata%u: ENTER\n", ap->print_id); /* hard-code chip #0 */ mmio += PDC_CHIP0_OFS; @@ -478,7 +478,7 @@ static void pdc20621_nodata_prep(struct ata_queued_cmd *qc) unsigned int portno = ap->port_no; unsigned int i; - VPRINTK("ata%u: ENTER\n", ap->id); + VPRINTK("ata%u: ENTER\n", ap->print_id); /* hard-code chip #0 */ mmio += PDC_CHIP0_OFS; @@ -605,7 +605,7 @@ static void pdc20621_packet_start(struct ata_queued_cmd *qc) /* hard-code chip #0 */ mmio += PDC_CHIP0_OFS; - VPRINTK("ata%u: ENTER\n", ap->id); + VPRINTK("ata%u: ENTER\n", ap->print_id); wmb(); /* flush PRD, pkt writes */ @@ -672,7 +672,7 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap, /* step two - DMA from DIMM to host */ if (doing_hdma) { - VPRINTK("ata%u: read hdma, 0x%x 0x%x\n", ap->id, + VPRINTK("ata%u: read hdma, 0x%x 0x%x\n", ap->print_id, readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT)); /* get drive status; clear intr; complete txn */ qc->err_mask |= ac_err_mask(ata_wait_idle(ap)); @@ -683,7 +683,7 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap, /* step one - exec ATA command */ else { u8 seq = (u8) (port_no + 1 + 4); - VPRINTK("ata%u: read ata, 0x%x 0x%x\n", ap->id, + VPRINTK("ata%u: read ata, 0x%x 0x%x\n", ap->print_id, readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT)); /* submit hdma pkt */ @@ -698,7 +698,7 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap, /* step one - DMA from host to DIMM */ if (doing_hdma) { u8 seq = (u8) (port_no + 1); - VPRINTK("ata%u: write hdma, 0x%x 0x%x\n", ap->id, + VPRINTK("ata%u: write hdma, 0x%x 0x%x\n", ap->print_id, readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT)); /* submit ata pkt */ @@ -711,7 +711,7 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap, /* step two - execute ATA command */ else { - VPRINTK("ata%u: write ata, 0x%x 0x%x\n", ap->id, + VPRINTK("ata%u: write ata, 0x%x 0x%x\n", ap->print_id, readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT)); /* get drive status; clear intr; complete txn */ qc->err_mask |= ac_err_mask(ata_wait_idle(ap)); diff --git a/include/linux/libata.h b/include/linux/libata.h index 5233e47eeb89..1f2099de0511 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -536,8 +536,8 @@ struct ata_port { spinlock_t *lock; unsigned long flags; /* ATA_FLAG_xxx */ unsigned int pflags; /* ATA_PFLAG_xxx */ - unsigned int id; /* unique id req'd by scsi midlyr */ - unsigned int port_no; /* unique port #; from zero */ + unsigned int print_id; /* user visible unique port ID */ + unsigned int port_no; /* 0 based port no. inside the host */ struct ata_prd *prd; /* our SG list */ dma_addr_t prd_dma; /* and its DMA mapping */ @@ -892,10 +892,10 @@ extern void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset, * printk helpers */ #define ata_port_printk(ap, lv, fmt, args...) \ - printk(lv"ata%u: "fmt, (ap)->id , ##args) + printk(lv"ata%u: "fmt, (ap)->print_id , ##args) #define ata_dev_printk(dev, lv, fmt, args...) \ - printk(lv"ata%u.%02u: "fmt, (dev)->ap->id, (dev)->devno , ##args) + printk(lv"ata%u.%02u: "fmt, (dev)->ap->print_id, (dev)->devno , ##args) /* * ata_eh_info helpers -- cgit v1.2.3-59-g8ed1b From 6ffa01d88c9dd45e2ed917b5eeeb494d07efb1ab Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 2 Mar 2007 17:32:47 +0900 Subject: libata: add CONFIG_PM to libata core layer Conditionalize all PM related stuff in libata core layer using CONFIG_PM. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 11 +++++++++++ drivers/ata/libata-eh.c | 29 +++++++++++++++++++++++++++++ drivers/ata/libata-scsi.c | 2 ++ include/linux/libata.h | 4 ++++ 4 files changed, 46 insertions(+) (limited to 'drivers/ata/libata-scsi.c') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 606145eeba44..dc362fa01ca4 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -5354,6 +5354,7 @@ int ata_flush_cache(struct ata_device *dev) return 0; } +#ifdef CONFIG_PM static int ata_host_request_pm(struct ata_host *host, pm_message_t mesg, unsigned int action, unsigned int ehi_flags, int wait) @@ -5469,6 +5470,7 @@ void ata_host_resume(struct ata_host *host) ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET, 0); host->dev->power.power_state = PMSG_ON; } +#endif /** * ata_port_start - Set port up for dma. @@ -6104,6 +6106,7 @@ int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits) return (tmp == bits->val) ? 1 : 0; } +#ifdef CONFIG_PM void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t mesg) { pci_save_state(pdev); @@ -6155,6 +6158,8 @@ int ata_pci_device_resume(struct pci_dev *pdev) ata_host_resume(host); return rc; } +#endif /* CONFIG_PM */ + #endif /* CONFIG_PCI */ @@ -6363,8 +6368,10 @@ EXPORT_SYMBOL_GPL(sata_scr_write); EXPORT_SYMBOL_GPL(sata_scr_write_flush); EXPORT_SYMBOL_GPL(ata_port_online); EXPORT_SYMBOL_GPL(ata_port_offline); +#ifdef CONFIG_PM EXPORT_SYMBOL_GPL(ata_host_suspend); EXPORT_SYMBOL_GPL(ata_host_resume); +#endif /* CONFIG_PM */ EXPORT_SYMBOL_GPL(ata_id_string); EXPORT_SYMBOL_GPL(ata_id_c_string); EXPORT_SYMBOL_GPL(ata_id_to_dma_mode); @@ -6380,16 +6387,20 @@ EXPORT_SYMBOL_GPL(pci_test_config_bits); EXPORT_SYMBOL_GPL(ata_pci_init_native_mode); EXPORT_SYMBOL_GPL(ata_pci_init_one); EXPORT_SYMBOL_GPL(ata_pci_remove_one); +#ifdef CONFIG_PM EXPORT_SYMBOL_GPL(ata_pci_device_do_suspend); EXPORT_SYMBOL_GPL(ata_pci_device_do_resume); EXPORT_SYMBOL_GPL(ata_pci_device_suspend); EXPORT_SYMBOL_GPL(ata_pci_device_resume); +#endif /* CONFIG_PM */ EXPORT_SYMBOL_GPL(ata_pci_default_filter); EXPORT_SYMBOL_GPL(ata_pci_clear_simplex); #endif /* CONFIG_PCI */ +#ifdef CONFIG_PM EXPORT_SYMBOL_GPL(ata_scsi_device_suspend); EXPORT_SYMBOL_GPL(ata_scsi_device_resume); +#endif /* CONFIG_PM */ EXPORT_SYMBOL_GPL(ata_eng_timeout); EXPORT_SYMBOL_GPL(ata_port_schedule_eh); diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index cad0d6db6df5..7349c3dbf774 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -52,8 +52,33 @@ enum { static void __ata_port_freeze(struct ata_port *ap); static void ata_eh_finish(struct ata_port *ap); +#ifdef CONFIG_PM static void ata_eh_handle_port_suspend(struct ata_port *ap); static void ata_eh_handle_port_resume(struct ata_port *ap); +static int ata_eh_suspend(struct ata_port *ap, + struct ata_device **r_failed_dev); +static void ata_eh_prep_resume(struct ata_port *ap); +static int ata_eh_resume(struct ata_port *ap, struct ata_device **r_failed_dev); +#else /* CONFIG_PM */ +static void ata_eh_handle_port_suspend(struct ata_port *ap) +{ } + +static void ata_eh_handle_port_resume(struct ata_port *ap) +{ } + +static int ata_eh_suspend(struct ata_port *ap, struct ata_device **r_failed_dev) +{ + return 0; +} + +static void ata_eh_prep_resume(struct ata_port *ap) +{ } + +static int ata_eh_resume(struct ata_port *ap, struct ata_device **r_failed_dev) +{ + return 0; +} +#endif /* CONFIG_PM */ static void ata_ering_record(struct ata_ering *ering, int is_io, unsigned int err_mask) @@ -1790,6 +1815,7 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap, return rc; } +#ifdef CONFIG_PM /** * ata_eh_suspend - handle suspend EH action * @ap: target host port @@ -1947,6 +1973,7 @@ static int ata_eh_resume(struct ata_port *ap, struct ata_device **r_failed_dev) DPRINTK("EXIT\n"); return 0; } +#endif /* CONFIG_PM */ static int ata_port_nr_enabled(struct ata_port *ap) { @@ -2249,6 +2276,7 @@ void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset, ata_eh_finish(ap); } +#ifdef CONFIG_PM /** * ata_eh_handle_port_suspend - perform port suspend operation * @ap: port to suspend @@ -2364,3 +2392,4 @@ static void ata_eh_handle_port_resume(struct ata_port *ap) } spin_unlock_irqrestore(ap->lock, flags); } +#endif /* CONFIG_PM */ diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 00a9a6c8f83c..6cc817a10204 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -510,6 +510,7 @@ static void ata_dump_status(unsigned id, struct ata_taskfile *tf) } } +#ifdef CONFIG_PM /** * ata_scsi_device_suspend - suspend ATA device associated with sdev * @sdev: the SCSI device to suspend @@ -634,6 +635,7 @@ int ata_scsi_device_resume(struct scsi_device *sdev) sdev->sdev_gendev.power.power_state = PMSG_ON; return 0; } +#endif /* CONFIG_PM */ /** * ata_to_sense_error - convert ATA error to SCSI error diff --git a/include/linux/libata.h b/include/linux/libata.h index 3f89d13c2e9a..e3f32f3189b2 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -718,10 +718,12 @@ extern void ata_std_ports(struct ata_ioports *ioaddr); extern int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, unsigned int n_ports); extern void ata_pci_remove_one (struct pci_dev *pdev); +#ifdef CONFIG_PM extern void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t mesg); extern int __must_check ata_pci_device_do_resume(struct pci_dev *pdev); extern int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg); extern int ata_pci_device_resume(struct pci_dev *pdev); +#endif extern int ata_pci_clear_simplex(struct pci_dev *pdev); #endif /* CONFIG_PCI */ extern int ata_device_add(const struct ata_probe_ent *ent); @@ -747,10 +749,12 @@ extern int sata_scr_write(struct ata_port *ap, int reg, u32 val); extern int sata_scr_write_flush(struct ata_port *ap, int reg, u32 val); extern int ata_port_online(struct ata_port *ap); extern int ata_port_offline(struct ata_port *ap); +#ifdef CONFIG_PM extern int ata_scsi_device_resume(struct scsi_device *); extern int ata_scsi_device_suspend(struct scsi_device *, pm_message_t mesg); extern int ata_host_suspend(struct ata_host *host, pm_message_t mesg); extern void ata_host_resume(struct ata_host *host); +#endif extern int ata_ratelimit(void); extern int ata_busy_sleep(struct ata_port *ap, unsigned long timeout_pat, unsigned long timeout); -- cgit v1.2.3-59-g8ed1b From 277239f228654fc03affdf2aa0e7a3969f420415 Mon Sep 17 00:00:00 2001 From: Mark Lord Date: Fri, 30 Mar 2007 17:45:52 -0400 Subject: libata bugfix: preserve LBA bit for HDIO_DRIVE_TASK Preserve the LBA bit in the DevSel/Head register for HDIO_DRIVE_TASK. Signed-off-by: Mark Lord Signed-off-by: Jeff Garzik --- drivers/ata/libata-scsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/ata/libata-scsi.c') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 6cc817a10204..e9364434182c 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -333,7 +333,7 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg) scsi_cmd[8] = args[3]; scsi_cmd[10] = args[4]; scsi_cmd[12] = args[5]; - scsi_cmd[13] = args[6] & 0x0f; + scsi_cmd[13] = args[6] & 0x4f; scsi_cmd[14] = args[0]; /* Good values for timeout and retries? Values below -- cgit v1.2.3-59-g8ed1b From f0ef88ed413232daebfe675c7b1bbf100d604d4b Mon Sep 17 00:00:00 2001 From: Mark Lord Date: Fri, 2 Feb 2007 12:36:25 -0500 Subject: RESEND: libata: check cdb len per dev instead of per host Resending, with s/printk/DPRINTK/ as pointed out by Alan. Fix libata to perform CDB len validation per device rather than per host. This way, validation still works when we have a mix of 12-byte and 16-byte devices on a common host interface. Signed-off-by: Mark Lord Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 18 +----------------- drivers/ata/libata-scsi.c | 5 +++-- 2 files changed, 4 insertions(+), 19 deletions(-) (limited to 'drivers/ata/libata-scsi.c') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 2b998b321881..99a881558e8d 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -1560,20 +1560,6 @@ static void ata_dev_config_ncq(struct ata_device *dev, snprintf(desc, desc_sz, "NCQ (depth %d/%d)", hdepth, ddepth); } -static void ata_set_port_max_cmd_len(struct ata_port *ap) -{ - int i; - - if (ap->scsi_host) { - unsigned int len = 0; - - for (i = 0; i < ATA_MAX_DEVICES; i++) - len = max(len, ap->device[i].cdb_len); - - ap->scsi_host->max_cmd_len = len; - } -} - /** * ata_dev_configure - Configure the specified ATA/ATAPI device * @dev: Target device to configure @@ -1773,8 +1759,6 @@ int ata_dev_configure(struct ata_device *dev) } } - ata_set_port_max_cmd_len(ap); - /* limit bridge transfers to udma5, 200 sectors */ if (ata_dev_knobble(dev)) { if (ata_msg_drv(ap) && print_info) @@ -5670,7 +5654,7 @@ static void ata_port_init_shost(struct ata_port *ap, struct Scsi_Host *shost) shost->max_id = 16; shost->max_lun = 1; shost->max_channel = 1; - shost->max_cmd_len = 12; + shost->max_cmd_len = 16; } /** diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index e9364434182c..7d41afe8ccbc 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -2792,8 +2792,9 @@ static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd, { int rc = 0; - if (unlikely(!scmd->cmd_len)) { - ata_dev_printk(dev, KERN_WARNING, "WARNING: zero len CDB\n"); + if (unlikely(!scmd->cmd_len || scmd->cmd_len > dev->cdb_len)) { + DPRINTK("bad CDB len=%u, max=%u\n", + scmd->cmd_len, dev->cdb_len); scmd->result = DID_ERROR << 16; done(scmd); return 0; -- cgit v1.2.3-59-g8ed1b From 5a5dbd18a7496ed403f6f54bb20c955c65482fa5 Mon Sep 17 00:00:00 2001 From: Mark Lord Date: Fri, 16 Mar 2007 10:22:26 -0400 Subject: libata: add support for READ/WRITE LONG The READ/WRITE LONG commands are theoretically obsolete, but the majority of drives in existance still implement them. The WRITE_LONG and WRITE_LONG_ONCE commands are of particular interest for fault injection testing -- eg. creating "media errors" at specific locations on a disk. The fussy bit is that these commands require a non-standard sector size, usually 520 bytes instead of 512. This patch adds support to libata for READ/WRITE LONG commands issued via SG_IO/ATA_16. Signed-off-by: Mark Lord Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 20 ++++++++++---------- drivers/ata/libata-scsi.c | 12 ++++++++++++ include/linux/ata.h | 6 ++++++ include/linux/libata.h | 2 ++ 4 files changed, 30 insertions(+), 10 deletions(-) (limited to 'drivers/ata/libata-scsi.c') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 971a737a8734..96bf86f67388 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4106,10 +4106,10 @@ void ata_data_xfer_noirq(struct ata_device *adev, unsigned char *buf, /** - * ata_pio_sector - Transfer ATA_SECT_SIZE (512 bytes) of data. + * ata_pio_sector - Transfer a sector of data. * @qc: Command on going * - * Transfer ATA_SECT_SIZE of data from/to the ATA device. + * Transfer qc->sect_size bytes of data from/to the ATA device. * * LOCKING: * Inherited from caller. @@ -4124,7 +4124,7 @@ static void ata_pio_sector(struct ata_queued_cmd *qc) unsigned int offset; unsigned char *buf; - if (qc->curbytes == qc->nbytes - ATA_SECT_SIZE) + if (qc->curbytes == qc->nbytes - qc->sect_size) ap->hsm_task_state = HSM_ST_LAST; page = sg[qc->cursg].page; @@ -4144,17 +4144,17 @@ static void ata_pio_sector(struct ata_queued_cmd *qc) buf = kmap_atomic(page, KM_IRQ0); /* do the actual data transfer */ - ap->ops->data_xfer(qc->dev, buf + offset, ATA_SECT_SIZE, do_write); + ap->ops->data_xfer(qc->dev, buf + offset, qc->sect_size, do_write); kunmap_atomic(buf, KM_IRQ0); local_irq_restore(flags); } else { buf = page_address(page); - ap->ops->data_xfer(qc->dev, buf + offset, ATA_SECT_SIZE, do_write); + ap->ops->data_xfer(qc->dev, buf + offset, qc->sect_size, do_write); } - qc->curbytes += ATA_SECT_SIZE; - qc->cursg_ofs += ATA_SECT_SIZE; + qc->curbytes += qc->sect_size; + qc->cursg_ofs += qc->sect_size; if (qc->cursg_ofs == (&sg[qc->cursg])->length) { qc->cursg++; @@ -4163,10 +4163,10 @@ static void ata_pio_sector(struct ata_queued_cmd *qc) } /** - * ata_pio_sectors - Transfer one or many 512-byte sectors. + * ata_pio_sectors - Transfer one or many sectors. * @qc: Command on going * - * Transfer one or many ATA_SECT_SIZE of data from/to the + * Transfer one or many sectors of data from/to the * ATA device for the DRQ request. * * LOCKING: @@ -4181,7 +4181,7 @@ static void ata_pio_sectors(struct ata_queued_cmd *qc) WARN_ON(qc->dev->multi_count == 0); - nsect = min((qc->nbytes - qc->curbytes) / ATA_SECT_SIZE, + nsect = min((qc->nbytes - qc->curbytes) / qc->sect_size, qc->dev->multi_count); while (nsect--) ata_pio_sector(qc); diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 7d41afe8ccbc..563ef0bfb038 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -2678,6 +2678,18 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) tf->device = qc->dev->devno ? tf->device | ATA_DEV1 : tf->device & ~ATA_DEV1; + /* READ/WRITE LONG use a non-standard sect_size */ + qc->sect_size = ATA_SECT_SIZE; + switch (tf->command) { + case ATA_CMD_READ_LONG: + case ATA_CMD_READ_LONG_ONCE: + case ATA_CMD_WRITE_LONG: + case ATA_CMD_WRITE_LONG_ONCE: + if (tf->protocol != ATA_PROT_PIO || tf->nsect != 1) + goto invalid_fld; + qc->sect_size = scmd->request_bufflen; + } + /* * Filter SET_FEATURES - XFER MODE command -- otherwise, * SET_FEATURES - XFER MODE must be preceded/succeeded diff --git a/include/linux/ata.h b/include/linux/ata.h index 6caeb98e29dd..ffb6cdc5010d 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -164,6 +164,12 @@ enum { /* READ_LOG_EXT pages */ ATA_LOG_SATA_NCQ = 0x10, + /* READ/WRITE LONG (obsolete) */ + ATA_CMD_READ_LONG = 0x22, + ATA_CMD_READ_LONG_ONCE = 0x23, + ATA_CMD_WRITE_LONG = 0x32, + ATA_CMD_WRITE_LONG_ONCE = 0x33, + /* SETFEATURES stuff */ SETFEATURES_XFER = 0x03, XFER_UDMA_7 = 0x47, diff --git a/include/linux/libata.h b/include/linux/libata.h index 5a40a8d95114..12237d4b9f9b 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -427,6 +427,7 @@ struct ata_queued_cmd { int dma_dir; unsigned int pad_len; + unsigned int sect_size; unsigned int nbytes; unsigned int curbytes; @@ -1182,6 +1183,7 @@ static inline void ata_qc_reinit(struct ata_queued_cmd *qc) qc->n_elem = 0; qc->err_mask = 0; qc->pad_len = 0; + qc->sect_size = ATA_SECT_SIZE; ata_tf_init(qc->dev, &qc->tf); -- cgit v1.2.3-59-g8ed1b From f31871951b38daf2d7ca17daad59fdb735062da3 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 17 Apr 2007 23:44:07 +0900 Subject: libata: separate out ata_host_alloc() and ata_host_register() Reorganize ata_host_alloc() and its subroutines into the following three functions. * ata_host_alloc() : allocates host and its ports. shost is not registered automatically. * ata_scsi_add_hosts() : allocates and adds shosts associated with an ATA host. Used by ata_host_register(). * ata_host_register() : takes a fully initialized ata_host structure and registers it to libata layer and probes it. Only ata_host_alloc() and ata_host_register() are exported. ata_device_add() is rewritten using the above functions. This patch does not introduce any observable behavior change. Things worth mentioning. * print_id is assigned at registration time and LLDs are allowed to overallocate ports and reduce host->n_ports during initialization. ata_host_register() will throw away unused ports automatically. * All SCSI host initialization stuff now resides in ata_scsi_add_hosts() in libata-scsi.c, where it should be. * ipr is now the only user of ata_host_init(). Either kill it by converting ipr to use ata_host_alloc() and friends or rename and move it to libata-scsi.c Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 471 ++++++++++++++++++++++++++-------------------- drivers/ata/libata-scsi.c | 68 +++++-- drivers/ata/libata.h | 8 +- include/linux/libata.h | 3 + 4 files changed, 326 insertions(+), 224 deletions(-) (limited to 'drivers/ata/libata-scsi.c') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index aea766a48e05..b23f35a4ee6b 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -72,7 +72,7 @@ static unsigned int ata_dev_init_params(struct ata_device *dev, static unsigned int ata_dev_set_xfermode(struct ata_device *dev); static void ata_dev_xfermask(struct ata_device *dev); -static unsigned int ata_print_id = 1; +unsigned int ata_print_id = 1; static struct workqueue_struct *ata_wq; struct workqueue_struct *ata_aux_wq; @@ -5666,42 +5666,35 @@ void ata_dev_init(struct ata_device *dev) } /** - * ata_port_init - Initialize an ata_port structure - * @ap: Structure to initialize - * @host: Collection of hosts to which @ap belongs - * @ent: Probe information provided by low-level driver - * @port_no: Port number associated with this ata_port + * ata_port_alloc - allocate and initialize basic ATA port resources + * @host: ATA host this allocated port belongs to * - * Initialize a new ata_port structure. + * Allocate and initialize basic ATA port resources. + * + * RETURNS: + * Allocate ATA port on success, NULL on failure. * * LOCKING: - * Inherited from caller. + * Inherited from calling layer (may sleep). */ -void ata_port_init(struct ata_port *ap, struct ata_host *host, - const struct ata_probe_ent *ent, unsigned int port_no) +struct ata_port *ata_port_alloc(struct ata_host *host) { + struct ata_port *ap; unsigned int i; + DPRINTK("ENTER\n"); + + ap = kzalloc(sizeof(*ap), GFP_KERNEL); + if (!ap) + return NULL; + ap->lock = &host->lock; ap->flags = ATA_FLAG_DISABLED; - ap->print_id = ata_print_id++; + ap->print_id = -1; ap->ctl = ATA_DEVCTL_OBS; ap->host = host; - ap->dev = ent->dev; - ap->port_no = port_no; - if (port_no == 1 && ent->pinfo2) { - ap->pio_mask = ent->pinfo2->pio_mask; - ap->mwdma_mask = ent->pinfo2->mwdma_mask; - ap->udma_mask = ent->pinfo2->udma_mask; - ap->flags |= ent->pinfo2->flags; - ap->ops = ent->pinfo2->port_ops; - } else { - ap->pio_mask = ent->pio_mask; - ap->mwdma_mask = ent->mwdma_mask; - ap->udma_mask = ent->udma_mask; - ap->flags |= ent->port_flags; - ap->ops = ent->port_ops; - } + ap->dev = host->dev; + ap->hw_sata_spd_limit = UINT_MAX; ap->active_tag = ATA_TAG_POISON; ap->last_ctl = 0xFF; @@ -5721,10 +5714,7 @@ void ata_port_init(struct ata_port *ap, struct ata_host *host, INIT_LIST_HEAD(&ap->eh_done_q); init_waitqueue_head(&ap->eh_wait_q); - /* set cable type */ ap->cbl = ATA_CBL_NONE; - if (ap->flags & ATA_FLAG_SATA) - ap->cbl = ATA_CBL_SATA; for (i = 0; i < ATA_MAX_DEVICES; i++) { struct ata_device *dev = &ap->device[i]; @@ -5737,77 +5727,6 @@ void ata_port_init(struct ata_port *ap, struct ata_host *host, ap->stats.unhandled_irq = 1; ap->stats.idle_irq = 1; #endif - - memcpy(&ap->ioaddr, &ent->port[port_no], sizeof(struct ata_ioports)); -} - -/** - * ata_port_init_shost - Initialize SCSI host associated with ATA port - * @ap: ATA port to initialize SCSI host for - * @shost: SCSI host associated with @ap - * - * Initialize SCSI host @shost associated with ATA port @ap. - * - * LOCKING: - * Inherited from caller. - */ -static void ata_port_init_shost(struct ata_port *ap, struct Scsi_Host *shost) -{ - ap->scsi_host = shost; - - shost->unique_id = ap->print_id; - shost->max_id = 16; - shost->max_lun = 1; - shost->max_channel = 1; - shost->max_cmd_len = 16; -} - -/** - * ata_port_add - Attach low-level ATA driver to system - * @ent: Information provided by low-level driver - * @host: Collections of ports to which we add - * @port_no: Port number associated with this host - * - * Attach low-level ATA driver to system. - * - * LOCKING: - * PCI/etc. bus probe sem. - * - * RETURNS: - * New ata_port on success, for NULL on error. - */ -static struct ata_port * ata_port_add(const struct ata_probe_ent *ent, - struct ata_host *host, - unsigned int port_no) -{ - struct Scsi_Host *shost; - struct ata_port *ap; - - DPRINTK("ENTER\n"); - - if (!ent->port_ops->error_handler && - !(ent->port_flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST))) { - printk(KERN_ERR "ata%u: no reset mechanism available\n", - port_no); - return NULL; - } - - ap = kzalloc(sizeof(struct ata_port), GFP_KERNEL); - if (!ap) - return NULL; - - shost = scsi_host_alloc(ent->sht, sizeof(struct ata_port *)); - if (!shost) { - kfree(ap); - return NULL; - } - - *(struct ata_port **)&shost->hostdata[0] = ap; - shost->transportt = &ata_scsi_transport_template; - - ata_port_init(ap, host, ent, port_no); - ata_port_init_shost(ap, shost); - return ap; } @@ -5845,6 +5764,71 @@ static void ata_host_release(struct device *gendev, void *res) dev_set_drvdata(gendev, NULL); } +/** + * ata_host_alloc - allocate and init basic ATA host resources + * @dev: generic device this host is associated with + * @max_ports: maximum number of ATA ports associated with this host + * + * Allocate and initialize basic ATA host resources. LLD calls + * this function to allocate a host, initializes it fully and + * attaches it using ata_host_register(). + * + * @max_ports ports are allocated and host->n_ports is + * initialized to @max_ports. The caller is allowed to decrease + * host->n_ports before calling ata_host_register(). The unused + * ports will be automatically freed on registration. + * + * RETURNS: + * Allocate ATA host on success, NULL on failure. + * + * LOCKING: + * Inherited from calling layer (may sleep). + */ +struct ata_host *ata_host_alloc(struct device *dev, int max_ports) +{ + struct ata_host *host; + size_t sz; + int i; + + DPRINTK("ENTER\n"); + + if (!devres_open_group(dev, NULL, GFP_KERNEL)) + return NULL; + + /* alloc a container for our list of ATA ports (buses) */ + sz = sizeof(struct ata_host) + (max_ports + 1) * sizeof(void *); + /* alloc a container for our list of ATA ports (buses) */ + host = devres_alloc(ata_host_release, sz, GFP_KERNEL); + if (!host) + goto err_out; + + devres_add(dev, host); + dev_set_drvdata(dev, host); + + spin_lock_init(&host->lock); + host->dev = dev; + host->n_ports = max_ports; + + /* allocate ports bound to this host */ + for (i = 0; i < max_ports; i++) { + struct ata_port *ap; + + ap = ata_port_alloc(host); + if (!ap) + goto err_out; + + ap->port_no = i; + host->ports[i] = ap; + } + + devres_remove_group(dev, NULL); + return host; + + err_out: + devres_release_group(dev, NULL); + return NULL; +} + /** * ata_host_start - start and freeze ports of an ATA host * @host: ATA host to start ports for @@ -5852,7 +5836,8 @@ static void ata_host_release(struct device *gendev, void *res) * Start and then freeze ports of @host. Started status is * recorded in host->flags, so this function can be called * multiple times. Ports are guaranteed to get started only - * once. + * once. If host->ops isn't initialized yet, its set to the + * first non-dummy port ops. * * LOCKING: * Inherited from calling layer (may sleep). @@ -5870,6 +5855,9 @@ int ata_host_start(struct ata_host *host) for (i = 0; i < host->n_ports; i++) { struct ata_port *ap = host->ports[i]; + if (!host->ops && !ata_port_is_dummy(ap)) + host->ops = ap->ops; + if (ap->ops->port_start) { rc = ap->ops->port_start(ap); if (rc) { @@ -5906,7 +5894,7 @@ int ata_host_start(struct ata_host *host) * PCI/etc. bus probe sem. * */ - +/* KILLME - the only user left is ipr */ void ata_host_init(struct ata_host *host, struct device *dev, unsigned long flags, const struct ata_port_operations *ops) { @@ -5916,6 +5904,143 @@ void ata_host_init(struct ata_host *host, struct device *dev, host->ops = ops; } +/** + * ata_host_register - register initialized ATA host + * @host: ATA host to register + * @sht: template for SCSI host + * + * Register initialized ATA host. @host is allocated using + * ata_host_alloc() and fully initialized by LLD. This function + * starts ports, registers @host with ATA and SCSI layers and + * probe registered devices. + * + * LOCKING: + * Inherited from calling layer (may sleep). + * + * RETURNS: + * 0 on success, -errno otherwise. + */ +int ata_host_register(struct ata_host *host, struct scsi_host_template *sht) +{ + int i, rc; + + /* host must have been started */ + if (!(host->flags & ATA_HOST_STARTED)) { + dev_printk(KERN_ERR, host->dev, + "BUG: trying to register unstarted host\n"); + WARN_ON(1); + return -EINVAL; + } + + /* Blow away unused ports. This happens when LLD can't + * determine the exact number of ports to allocate at + * allocation time. + */ + for (i = host->n_ports; host->ports[i]; i++) + kfree(host->ports[i]); + + /* give ports names and add SCSI hosts */ + for (i = 0; i < host->n_ports; i++) + host->ports[i]->print_id = ata_print_id++; + + rc = ata_scsi_add_hosts(host, sht); + if (rc) + return rc; + + /* set cable, sata_spd_limit and report */ + for (i = 0; i < host->n_ports; i++) { + struct ata_port *ap = host->ports[i]; + int irq_line; + u32 scontrol; + unsigned long xfer_mask; + + /* set SATA cable type if still unset */ + if (ap->cbl == ATA_CBL_NONE && (ap->flags & ATA_FLAG_SATA)) + ap->cbl = ATA_CBL_SATA; + + /* init sata_spd_limit to the current value */ + if (sata_scr_read(ap, SCR_CONTROL, &scontrol) == 0) { + int spd = (scontrol >> 4) & 0xf; + ap->hw_sata_spd_limit &= (1 << spd) - 1; + } + ap->sata_spd_limit = ap->hw_sata_spd_limit; + + /* report the secondary IRQ for second channel legacy */ + irq_line = host->irq; + if (i == 1 && host->irq2) + irq_line = host->irq2; + + xfer_mask = ata_pack_xfermask(ap->pio_mask, ap->mwdma_mask, + ap->udma_mask); + + /* print per-port info to dmesg */ + if (!ata_port_is_dummy(ap)) + ata_port_printk(ap, KERN_INFO, "%cATA max %s cmd 0x%p " + "ctl 0x%p bmdma 0x%p irq %d\n", + ap->cbl == ATA_CBL_SATA ? 'S' : 'P', + ata_mode_string(xfer_mask), + ap->ioaddr.cmd_addr, + ap->ioaddr.ctl_addr, + ap->ioaddr.bmdma_addr, + irq_line); + else + ata_port_printk(ap, KERN_INFO, "DUMMY\n"); + } + + /* perform each probe synchronously */ + DPRINTK("probe begin\n"); + for (i = 0; i < host->n_ports; i++) { + struct ata_port *ap = host->ports[i]; + int rc; + + /* probe */ + if (ap->ops->error_handler) { + struct ata_eh_info *ehi = &ap->eh_info; + unsigned long flags; + + ata_port_probe(ap); + + /* kick EH for boot probing */ + spin_lock_irqsave(ap->lock, flags); + + ehi->probe_mask = (1 << ATA_MAX_DEVICES) - 1; + ehi->action |= ATA_EH_SOFTRESET; + ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET; + + ap->pflags |= ATA_PFLAG_LOADING; + ata_port_schedule_eh(ap); + + spin_unlock_irqrestore(ap->lock, flags); + + /* wait for EH to finish */ + ata_port_wait_eh(ap); + } else { + DPRINTK("ata%u: bus probe begin\n", ap->print_id); + rc = ata_bus_probe(ap); + DPRINTK("ata%u: bus probe end\n", ap->print_id); + + if (rc) { + /* FIXME: do something useful here? + * Current libata behavior will + * tear down everything when + * the module is removed + * or the h/w is unplugged. + */ + } + } + } + + /* probes are done, now scan each port's disk(s) */ + DPRINTK("host probe begin\n"); + for (i = 0; i < host->n_ports; i++) { + struct ata_port *ap = host->ports[i]; + + ata_scsi_scan_host(ap); + } + + return 0; +} + /** * ata_device_add - Register hardware device with ATA and SCSI layers * @ent: Probe information describing hardware device to be registered @@ -5948,62 +6073,53 @@ int ata_device_add(const struct ata_probe_ent *ent) return 0; } + if (!ent->port_ops->error_handler && + !(ent->port_flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST))) { + dev_printk(KERN_ERR, dev, "no reset mechanism available\n"); + return 0; + } + if (!devres_open_group(dev, ata_device_add, GFP_KERNEL)) return 0; - /* alloc a container for our list of ATA ports (buses) */ - host = devres_alloc(ata_host_release, sizeof(struct ata_host) + - (ent->n_ports * sizeof(void *)), GFP_KERNEL); - if (!host) - goto err_out; - devres_add(dev, host); - dev_set_drvdata(dev, host); + /* allocate host */ + host = ata_host_alloc(dev, ent->n_ports); - ata_host_init(host, dev, ent->_host_flags, ent->port_ops); - host->n_ports = ent->n_ports; host->irq = ent->irq; host->irq2 = ent->irq2; host->iomap = ent->iomap; host->private_data = ent->private_data; + host->ops = ent->port_ops; + host->flags = ent->_host_flags; - /* register each port bound to this device */ for (i = 0; i < host->n_ports; i++) { - struct ata_port *ap; - unsigned long xfer_mode_mask; - int irq_line = ent->irq; - - ap = ata_port_add(ent, host, i); - host->ports[i] = ap; - if (!ap) - goto err_out; + struct ata_port *ap = host->ports[i]; /* dummy? */ if (ent->dummy_port_mask & (1 << i)) { - ata_port_printk(ap, KERN_INFO, "DUMMY\n"); ap->ops = &ata_dummy_port_ops; continue; } - /* Report the secondary IRQ for second channel legacy */ - if (i == 1 && ent->irq2) - irq_line = ent->irq2; - - xfer_mode_mask =(ap->udma_mask << ATA_SHIFT_UDMA) | - (ap->mwdma_mask << ATA_SHIFT_MWDMA) | - (ap->pio_mask << ATA_SHIFT_PIO); + if (ap->port_no == 1 && ent->pinfo2) { + ap->pio_mask = ent->pinfo2->pio_mask; + ap->mwdma_mask = ent->pinfo2->mwdma_mask; + ap->udma_mask = ent->pinfo2->udma_mask; + ap->flags |= ent->pinfo2->flags; + ap->ops = ent->pinfo2->port_ops; + } else { + ap->pio_mask = ent->pio_mask; + ap->mwdma_mask = ent->mwdma_mask; + ap->udma_mask = ent->udma_mask; + ap->flags |= ent->port_flags; + ap->ops = ent->port_ops; + } - /* print per-port info to dmesg */ - ata_port_printk(ap, KERN_INFO, "%cATA max %s cmd 0x%p " - "ctl 0x%p bmdma 0x%p irq %d\n", - ap->flags & ATA_FLAG_SATA ? 'S' : 'P', - ata_mode_string(xfer_mode_mask), - ap->ioaddr.cmd_addr, - ap->ioaddr.ctl_addr, - ap->ioaddr.bmdma_addr, - irq_line); + memcpy(&ap->ioaddr, &ent->port[ap->port_no], + sizeof(struct ata_ioports)); } - /* start ports */ + /* start and freeze ports before requesting IRQ */ rc = ata_host_start(host); if (rc) goto err_out; @@ -6036,80 +6152,17 @@ int ata_device_add(const struct ata_probe_ent *ent) /* resource acquisition complete */ devres_remove_group(dev, ata_device_add); - /* perform each probe synchronously */ - DPRINTK("probe begin\n"); - for (i = 0; i < host->n_ports; i++) { - struct ata_port *ap = host->ports[i]; - u32 scontrol; - int rc; - - /* init sata_spd_limit to the current value */ - if (sata_scr_read(ap, SCR_CONTROL, &scontrol) == 0) { - int spd = (scontrol >> 4) & 0xf; - ap->hw_sata_spd_limit &= (1 << spd) - 1; - } - ap->sata_spd_limit = ap->hw_sata_spd_limit; - - rc = scsi_add_host(ap->scsi_host, dev); - if (rc) { - ata_port_printk(ap, KERN_ERR, "scsi_add_host failed\n"); - /* FIXME: do something useful here */ - /* FIXME: handle unconditional calls to - * scsi_scan_host and ata_host_remove, below, - * at the very least - */ - } - - if (ap->ops->error_handler) { - struct ata_eh_info *ehi = &ap->eh_info; - unsigned long flags; - - ata_port_probe(ap); - - /* kick EH for boot probing */ - spin_lock_irqsave(ap->lock, flags); - - ehi->probe_mask = (1 << ATA_MAX_DEVICES) - 1; - ehi->action |= ATA_EH_SOFTRESET; - ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET; - - ap->pflags |= ATA_PFLAG_LOADING; - ata_port_schedule_eh(ap); - - spin_unlock_irqrestore(ap->lock, flags); - - /* wait for EH to finish */ - ata_port_wait_eh(ap); - } else { - DPRINTK("ata%u: bus probe begin\n", ap->print_id); - rc = ata_bus_probe(ap); - DPRINTK("ata%u: bus probe end\n", ap->print_id); - - if (rc) { - /* FIXME: do something useful here? - * Current libata behavior will - * tear down everything when - * the module is removed - * or the h/w is unplugged. - */ - } - } - } - - /* probes are done, now scan each port's disk(s) */ - DPRINTK("host probe begin\n"); - for (i = 0; i < host->n_ports; i++) { - struct ata_port *ap = host->ports[i]; - - ata_scsi_scan_host(ap); - } + /* register */ + rc = ata_host_register(host, ent->sht); + if (rc) + goto err_out; - VPRINTK("EXIT, returning %u\n", ent->n_ports); - return ent->n_ports; /* success */ + VPRINTK("EXIT, returning %u\n", host->n_ports); + return host->n_ports; /* success */ err_out: devres_release_group(dev, ata_device_add); - VPRINTK("EXIT, returning %d\n", rc); + VPRINTK("EXIT, returning 0\n"); return 0; } @@ -6493,7 +6546,9 @@ EXPORT_SYMBOL_GPL(ata_dummy_port_ops); EXPORT_SYMBOL_GPL(ata_std_bios_param); EXPORT_SYMBOL_GPL(ata_std_ports); EXPORT_SYMBOL_GPL(ata_host_init); +EXPORT_SYMBOL_GPL(ata_host_alloc); EXPORT_SYMBOL_GPL(ata_host_start); +EXPORT_SYMBOL_GPL(ata_host_register); EXPORT_SYMBOL_GPL(ata_device_add); EXPORT_SYMBOL_GPL(ata_host_detach); EXPORT_SYMBOL_GPL(ata_sg_init); diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 563ef0bfb038..9afba2ba489e 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -104,7 +104,7 @@ static const u8 def_control_mpage[CONTROL_MPAGE_LEN] = { * libata transport template. libata doesn't do real transport stuff. * It just needs the eh_timed_out hook. */ -struct scsi_transport_template ata_scsi_transport_template = { +static struct scsi_transport_template ata_scsi_transport_template = { .eh_strategy_handler = ata_scsi_error, .eh_timed_out = ata_scsi_timed_out, .user_scan = ata_scsi_user_scan, @@ -2961,6 +2961,48 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd, } } +int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht) +{ + int i, rc; + + for (i = 0; i < host->n_ports; i++) { + struct ata_port *ap = host->ports[i]; + struct Scsi_Host *shost; + + rc = -ENOMEM; + shost = scsi_host_alloc(sht, sizeof(struct ata_port *)); + if (!shost) + goto err_alloc; + + *(struct ata_port **)&shost->hostdata[0] = ap; + ap->scsi_host = shost; + + shost->transportt = &ata_scsi_transport_template; + shost->unique_id = ap->print_id; + shost->max_id = 16; + shost->max_lun = 1; + shost->max_channel = 1; + shost->max_cmd_len = 16; + + rc = scsi_add_host(ap->scsi_host, ap->host->dev); + if (rc) + goto err_add; + } + + return 0; + + err_add: + scsi_host_put(host->ports[i]->scsi_host); + err_alloc: + while (--i >= 0) { + struct Scsi_Host *shost = host->ports[i]->scsi_host; + + scsi_remove_host(shost); + scsi_host_put(shost); + } + return rc; +} + void ata_scsi_scan_host(struct ata_port *ap) { unsigned int i; @@ -3237,21 +3279,21 @@ struct ata_port *ata_sas_port_alloc(struct ata_host *host, struct ata_port_info *port_info, struct Scsi_Host *shost) { - struct ata_port *ap = kzalloc(sizeof(*ap), GFP_KERNEL); - struct ata_probe_ent *ent; + struct ata_port *ap; + ap = ata_port_alloc(host); if (!ap) return NULL; - ent = ata_probe_ent_alloc(host->dev, port_info); - if (!ent) { - kfree(ap); - return NULL; - } - - ata_port_init(ap, host, ent, 0); + ap->port_no = 0; ap->lock = shost->host_lock; - devm_kfree(host->dev, ent); + ap->pio_mask = port_info->pio_mask; + ap->mwdma_mask = port_info->mwdma_mask; + ap->udma_mask = port_info->udma_mask; + ap->flags |= port_info->flags; + ap->ops = port_info->port_ops; + ap->cbl = ATA_CBL_SATA; + return ap; } EXPORT_SYMBOL_GPL(ata_sas_port_alloc); @@ -3307,8 +3349,10 @@ int ata_sas_port_init(struct ata_port *ap) { int rc = ap->ops->port_start(ap); - if (!rc) + if (!rc) { + ap->print_id = ata_print_id++; rc = ata_bus_probe(ap); + } return rc; } diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 1f1e3a51f859..b4d5253d627a 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -52,6 +52,7 @@ enum { ATA_DNXFER_QUIET = (1 << 31), }; +extern unsigned int ata_print_id; extern struct workqueue_struct *ata_aux_wq; extern int atapi_enabled; extern int atapi_dmadir; @@ -92,10 +93,9 @@ extern int ata_flush_cache(struct ata_device *dev); extern void ata_dev_init(struct ata_device *dev); extern int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg); extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg); -extern void ata_port_init(struct ata_port *ap, struct ata_host *host, - const struct ata_probe_ent *ent, unsigned int port_no); extern struct ata_probe_ent *ata_probe_ent_alloc(struct device *dev, const struct ata_port_info *port); +extern struct ata_port *ata_port_alloc(struct ata_host *host); /* libata-acpi.c */ #ifdef CONFIG_SATA_ACPI @@ -113,8 +113,8 @@ static inline int ata_acpi_push_id(struct ata_port *ap, unsigned int ix) #endif /* libata-scsi.c */ -extern struct scsi_transport_template ata_scsi_transport_template; - +extern int ata_scsi_add_hosts(struct ata_host *host, + struct scsi_host_template *sht); extern void ata_scsi_scan_host(struct ata_port *ap); extern int ata_scsi_offline_dev(struct ata_device *dev); extern void ata_scsi_hotplug(struct work_struct *work); diff --git a/include/linux/libata.h b/include/linux/libata.h index bda26e86f05f..06cf23f0b3c7 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -733,7 +733,10 @@ extern int ata_pci_device_resume(struct pci_dev *pdev); #endif extern int ata_pci_clear_simplex(struct pci_dev *pdev); #endif /* CONFIG_PCI */ +extern struct ata_host *ata_host_alloc(struct device *dev, int max_ports); extern int ata_host_start(struct ata_host *host); +extern int ata_host_register(struct ata_host *host, + struct scsi_host_template *sht); extern int ata_device_add(const struct ata_probe_ent *ent); extern void ata_host_detach(struct ata_host *host); extern void ata_host_init(struct ata_host *, struct device *, -- cgit v1.2.3-59-g8ed1b