From 68d1d07b510bb57a504588adc2bd2758adea0965 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 25 Mar 2008 12:22:49 +0900 Subject: libata: implement and use SHT initializers libata lets low level drivers build scsi_host_template and register it to the SCSI layer. This allows low level drivers high level of flexibility but also burdens them with lots of boilerplate entries. This patch implements SHT initializers which can be used to initialize all the boilerplate entries in a sht. Three variants of them are implemented - BASE, BMDMA and NCQ - for different types of drivers. Note that entries can be overriden by putting individual initializers after the helper macro. All sht tables are identical before and after this patch. Signed-off-by: Tejun Heo --- drivers/ata/pata_scc.c | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) (limited to 'drivers/ata/pata_scc.c') diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c index 6c016de..1833e9e 100644 --- a/drivers/ata/pata_scc.c +++ b/drivers/ata/pata_scc.c @@ -968,21 +968,7 @@ static void scc_port_stop (struct ata_port *ap) } static struct scsi_host_template scc_sht = { - .module = THIS_MODULE, - .name = DRV_NAME, - .ioctl = ata_scsi_ioctl, - .queuecommand = ata_scsi_queuecmd, - .can_queue = ATA_DEF_QUEUE, - .this_id = ATA_SHT_THIS_ID, - .sg_tablesize = LIBATA_MAX_PRD, - .cmd_per_lun = ATA_SHT_CMD_PER_LUN, - .emulated = ATA_SHT_EMULATED, - .use_clustering = ATA_SHT_USE_CLUSTERING, - .proc_name = DRV_NAME, - .dma_boundary = ATA_DMA_BOUNDARY, - .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, - .bios_param = ata_std_bios_param, + ATA_BMDMA_SHT(DRV_NAME), }; static const struct ata_port_operations scc_pata_ops = { -- cgit v1.1 From 029cfd6b74fc5c517865fad78cf4a3ea8d9b664a Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 25 Mar 2008 12:22:49 +0900 Subject: libata: implement and use ops inheritance libata lets low level drivers build ata_port_operations table and register it with libata core layer. This allows low level drivers high level of flexibility but also burdens them with lots of boilerplate entries. This becomes worse for drivers which support related similar controllers which differ slightly. They share most of the operations except for a few. However, the driver still needs to list all operations for each variant. This results in large number of duplicate entries, which is not only inefficient but also error-prone as it becomes very difficult to tell what the actual differences are. This duplicate boilerplates all over the low level drivers also make updating the core layer exteremely difficult and error-prone. When compounded with multi-branched development model, it ends up accumulating inconsistencies over time. Some of those inconsistencies cause immediate problems and fixed. Others just remain there dormant making maintenance increasingly difficult. To rectify the problem, this patch implements ata_port_operations inheritance. To allow LLDs to easily re-use their own ops tables overriding only specific methods, this patch implements poor man's class inheritance. An ops table has ->inherits field which can be set to any ops table as long as it doesn't create a loop. When the host is started, the inheritance chain is followed and any operation which isn't specified is taken from the nearest ancestor which has it specified. This operation is called finalization and done only once per an ops table and the LLD doesn't have to do anything special about it other than making the ops table non-const such that libata can update it. libata provides four base ops tables lower drivers can inherit from - base, sata, pmp, sff and bmdma. To avoid overriding these ops accidentaly, these ops are declared const and LLDs should always inherit these instead of using them directly. After finalization, all the ops table are identical before and after the patch except for setting .irq_handler to ata_interrupt in drivers which didn't use to. The .irq_handler doesn't have any actual effect and the field will soon be removed by later patch. * sata_sx4 is still using old style EH and currently doesn't take advantage of ops inheritance. Signed-off-by: Tejun Heo --- drivers/ata/pata_scc.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers/ata/pata_scc.c') diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c index 1833e9e..033d1f3 100644 --- a/drivers/ata/pata_scc.c +++ b/drivers/ata/pata_scc.c @@ -972,6 +972,8 @@ static struct scsi_host_template scc_sht = { }; static const struct ata_port_operations scc_pata_ops = { + .inherits = &ata_bmdma_port_ops, + .set_piomode = scc_set_piomode, .set_dmamode = scc_set_dmamode, .mode_filter = scc_mode_filter, @@ -989,12 +991,7 @@ static const struct ata_port_operations scc_pata_ops = { .bmdma_status = scc_bmdma_status, .data_xfer = scc_data_xfer, - .qc_prep = ata_qc_prep, - .qc_issue = ata_qc_issue_prot, - .freeze = scc_bmdma_freeze, - .thaw = ata_bmdma_thaw, - .error_handler = scc_error_handler, .post_internal_cmd = scc_bmdma_stop, -- cgit v1.1 From a1efdaba2dbd6fb89e23a87b66d3f4dd92c9f5af Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 25 Mar 2008 12:22:50 +0900 Subject: libata: make reset related methods proper port operations Currently reset methods are not specified directly in the ata_port_operations table. If a LLD wants to use custom reset methods, it should construct and use a error_handler which uses those reset methods. It's done this way for two reasons. First, the ops table already contained too many methods and adding four more of them would noticeably increase the amount of necessary boilerplate code all over low level drivers. Second, as ->error_handler uses those reset methods, it can get confusing. ie. By overriding ->error_handler, those reset ops can be made useless making layering a bit hazy. Now that ops table uses inheritance, the first problem doesn't exist anymore. The second isn't completely solved but is relieved by providing default values - most drivers can just override what it has implemented and don't have to concern itself about higher level callbacks. In fact, there currently is no driver which actually modifies error handling behavior. Drivers which override ->error_handler just wraps the standard error handler only to prepare the controller for EH. I don't think making ops layering strict has any noticeable benefit. This patch makes ->prereset, ->softreset, ->hardreset, ->postreset and their PMP counterparts propoer ops. Default ops are provided in the base ops tables and drivers are converted to override individual reset methods instead of creating custom error_handler. * ata_std_error_handler() doesn't use sata_std_hardreset() if SCRs aren't accessible. sata_promise doesn't need to use separate error_handlers for PATA and SATA anymore. * softreset is broken for sata_inic162x and sata_sx4. As libata now always prefers hardreset, this doesn't really matter but the ops are forced to NULL using ATA_OP_NULL for documentation purpose. * pata_hpt374 needs to use different prereset for the first and second PCI functions. This used to be done by branching from hpt374_error_handler(). The proper way to do this is to use separate ops and port_info tables for each function. Converted. Signed-off-by: Tejun Heo --- drivers/ata/pata_scc.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) (limited to 'drivers/ata/pata_scc.c') diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c index 033d1f3..07f2d7a 100644 --- a/drivers/ata/pata_scc.c +++ b/drivers/ata/pata_scc.c @@ -905,17 +905,6 @@ static void scc_std_postreset(struct ata_link *link, unsigned int *classes) } /** - * scc_error_handler - Stock error handler for BMDMA controller - * @ap: port to handle error for - */ - -static void scc_error_handler (struct ata_port *ap) -{ - ata_bmdma_drive_eh(ap, scc_pata_prereset, scc_std_softreset, NULL, - scc_std_postreset); -} - -/** * scc_bmdma_irq_clear - Clear PCI IDE BMDMA interrupt. * @ap: Port associated with this ATA transaction. * @@ -992,7 +981,9 @@ static const struct ata_port_operations scc_pata_ops = { .data_xfer = scc_data_xfer, .freeze = scc_bmdma_freeze, - .error_handler = scc_error_handler, + .prereset = scc_pata_prereset, + .softreset = scc_std_softreset, + .postreset = scc_std_postreset, .post_internal_cmd = scc_bmdma_stop, .irq_clear = scc_bmdma_irq_clear, -- cgit v1.1 From 6fd36390117f7844ad147377878ddb52088f583a Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 25 Mar 2008 22:16:44 +0900 Subject: libata: kill ata_chk_status() ata_chk_status() just calls ops->check_status and it only adds confusion with other status functions. Kill it. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/pata_scc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/ata/pata_scc.c') diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c index 07f2d7a..85d3363 100644 --- a/drivers/ata/pata_scc.c +++ b/drivers/ata/pata_scc.c @@ -854,7 +854,7 @@ static void scc_bmdma_freeze (struct ata_port *ap) * ATA_NIEN manipulation. Also, many controllers fail to mask * previously pending IRQ on ATA_NIEN assertion. Clear it. */ - ata_chk_status(ap); + ap->ops->check_status(ap); ap->ops->irq_clear(ap); } -- cgit v1.1 From c1796d9850aaa97ee7492d090499b5508971514b Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 27 Mar 2008 19:44:24 +0900 Subject: pata_scc: fix compile warning Missed one during mass conversion (dc14c0c5). Fix it. Spotted by Stephen Rothwell. Signed-off-by: Tejun Heo Cc: Stephen Rothwell Signed-off-by: Jeff Garzik --- drivers/ata/pata_scc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/ata/pata_scc.c') diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c index 85d3363..2ed480e 100644 --- a/drivers/ata/pata_scc.c +++ b/drivers/ata/pata_scc.c @@ -960,7 +960,7 @@ static struct scsi_host_template scc_sht = { ATA_BMDMA_SHT(DRV_NAME), }; -static const struct ata_port_operations scc_pata_ops = { +static struct ata_port_operations scc_pata_ops = { .inherits = &ata_bmdma_port_ops, .set_piomode = scc_set_piomode, -- cgit v1.1 From 826cd156de6cea1e4982f32238077215cfa4ae63 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 25 Mar 2008 05:18:11 +0000 Subject: libata annotations Signed-off-by: Al Viro Signed-off-by: Jeff Garzik --- drivers/ata/pata_scc.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/ata/pata_scc.c') diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c index 2ed480e..fba5bed 100644 --- a/drivers/ata/pata_scc.c +++ b/drivers/ata/pata_scc.c @@ -782,28 +782,28 @@ static unsigned int scc_data_xfer (struct ata_device *dev, unsigned char *buf, struct ata_port *ap = dev->link->ap; unsigned int words = buflen >> 1; unsigned int i; - u16 *buf16 = (u16 *) buf; + __le16 *buf16 = (__le16 *) buf; void __iomem *mmio = ap->ioaddr.data_addr; /* Transfer multiple of 2 bytes */ if (rw == READ) for (i = 0; i < words; i++) - buf16[i] = le16_to_cpu(in_be32(mmio)); + buf16[i] = cpu_to_le16(in_be32(mmio)); else for (i = 0; i < words; i++) - out_be32(mmio, cpu_to_le16(buf16[i])); + out_be32(mmio, le16_to_cpu(buf16[i])); /* Transfer trailing 1 byte, if any. */ if (unlikely(buflen & 0x01)) { - u16 align_buf[1] = { 0 }; + __le16 align_buf[1] = { 0 }; unsigned char *trailing_buf = buf + buflen - 1; if (rw == READ) { - align_buf[0] = le16_to_cpu(in_be32(mmio)); + align_buf[0] = cpu_to_le16(in_be32(mmio)); memcpy(trailing_buf, align_buf, 1); } else { memcpy(align_buf, trailing_buf, 1); - out_be32(mmio, cpu_to_le16(align_buf[0])); + out_be32(mmio, le16_to_cpu(align_buf[0])); } words++; } -- cgit v1.1 From 9363c3825ea9ad76561eb48a395349dd29211ed6 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 7 Apr 2008 22:47:16 +0900 Subject: libata: rename SFF functions SFF functions have confusing names. Some have sff prefix, some have bmdma, some std, some pci and some none. Unify the naming by... * SFF functions which are common to both BMDMA and non-BMDMA are prefixed with ata_sff_. * SFF functions which are specific to BMDMA are prefixed with ata_bmdma_. * SFF functions which are specific to PCI but apply to both BMDMA and non-BMDMA are prefixed with ata_pci_sff_. * SFF functions which are specific to PCI and BMDMA are prefixed with ata_pci_bmdma_. * Drop generic prefixes from LLD specific routines. For example, bfin_std_dev_select -> bfin_dev_select. The following renames are noteworthy. ata_qc_issue_prot() -> ata_sff_qc_issue() ata_pci_default_filter() -> ata_bmdma_mode_filter() ata_dev_try_classify() -> ata_sff_dev_classify() This rename is in preparation of separating SFF support out of libata core layer. This patch strictly renames functions and doesn't introduce any behavior difference. Signed-off-by: Tejun Heo --- drivers/ata/pata_scc.c | 80 +++++++++++++++++++++++++------------------------- 1 file changed, 40 insertions(+), 40 deletions(-) (limited to 'drivers/ata/pata_scc.c') diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c index fba5bed..701d0ad 100644 --- a/drivers/ata/pata_scc.c +++ b/drivers/ata/pata_scc.c @@ -266,7 +266,7 @@ unsigned long scc_mode_filter(struct ata_device *adev, unsigned long mask) printk(KERN_INFO "%s: limit ATAPI UDMA to UDMA4\n", DRV_NAME); mask &= ~(0xE0 << ATA_SHIFT_UDMA); } - return ata_pci_default_filter(adev, mask); + return ata_bmdma_mode_filter(adev, mask); } /** @@ -274,7 +274,7 @@ unsigned long scc_mode_filter(struct ata_device *adev, unsigned long mask) * @ap: Port to which output is sent * @tf: ATA taskfile register set * - * Note: Original code is ata_tf_load(). + * Note: Original code is ata_sff_tf_load(). */ static void scc_tf_load (struct ata_port *ap, const struct ata_taskfile *tf) @@ -341,7 +341,7 @@ static u8 scc_check_status (struct ata_port *ap) * @ap: Port from which input is read * @tf: ATA taskfile register set for storing input * - * Note: Original code is ata_tf_read(). + * Note: Original code is ata_sff_tf_read(). */ static void scc_tf_read (struct ata_port *ap, struct ata_taskfile *tf) @@ -373,7 +373,7 @@ static void scc_tf_read (struct ata_port *ap, struct ata_taskfile *tf) * @ap: port to which command is being issued * @tf: ATA taskfile register set * - * Note: Original code is ata_exec_command(). + * Note: Original code is ata_sff_exec_command(). */ static void scc_exec_command (struct ata_port *ap, @@ -382,7 +382,7 @@ static void scc_exec_command (struct ata_port *ap, DPRINTK("ata%u: cmd 0x%X\n", ap->print_id, tf->command); out_be32(ap->ioaddr.command_addr, tf->command); - ata_pause(ap); + ata_sff_pause(ap); } /** @@ -396,14 +396,14 @@ static u8 scc_check_altstatus (struct ata_port *ap) } /** - * scc_std_dev_select - Select device 0/1 on ATA bus + * scc_dev_select - Select device 0/1 on ATA bus * @ap: ATA channel to manipulate * @device: ATA device (numbered from zero) to select * - * Note: Original code is ata_std_dev_select(). + * Note: Original code is ata_sff_dev_select(). */ -static void scc_std_dev_select (struct ata_port *ap, unsigned int device) +static void scc_dev_select (struct ata_port *ap, unsigned int device) { u8 tmp; @@ -413,7 +413,7 @@ static void scc_std_dev_select (struct ata_port *ap, unsigned int device) tmp = ATA_DEVICE_OBS | ATA_DEV1; out_be32(ap->ioaddr.device_addr, tmp); - ata_pause(ap); + ata_sff_pause(ap); } /** @@ -514,7 +514,7 @@ static int scc_bus_post_reset(struct ata_port *ap, unsigned int devmask, * BSY bit to clear */ if (dev0) { - rc = ata_wait_ready(ap, deadline); + rc = ata_sff_wait_ready(ap, deadline); if (rc && rc != -ENODEV) return rc; } @@ -535,7 +535,7 @@ static int scc_bus_post_reset(struct ata_port *ap, unsigned int devmask, msleep(50); /* give drive a breather */ } if (dev1) { - rc = ata_wait_ready(ap, deadline); + rc = ata_sff_wait_ready(ap, deadline); if (rc && rc != -ENODEV) return rc; } @@ -571,7 +571,7 @@ static unsigned int scc_bus_softreset(struct ata_port *ap, unsigned int devmask, out_be32(ioaddr->ctl_addr, ap->ctl); /* wait a while before checking status */ - ata_wait_after_reset(ap, deadline); + ata_sff_wait_after_reset(ap, deadline); /* Before we perform post reset processing we want to see if * the bus shows 0xFF because the odd clown forgets the D7 @@ -586,16 +586,16 @@ static unsigned int scc_bus_softreset(struct ata_port *ap, unsigned int devmask, } /** - * scc_std_softreset - reset host port via ATA SRST + * scc_softreset - reset host port via ATA SRST * @ap: port to reset * @classes: resulting classes of attached devices * @deadline: deadline jiffies for the operation * - * Note: Original code is ata_std_softreset(). + * Note: Original code is ata_sff_softreset(). */ -static int scc_std_softreset(struct ata_link *link, unsigned int *classes, - unsigned long deadline) +static int scc_softreset(struct ata_link *link, unsigned int *classes, + unsigned long deadline) { struct ata_port *ap = link->ap; unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS; @@ -628,10 +628,10 @@ static int scc_std_softreset(struct ata_link *link, unsigned int *classes, } /* determine by signature whether we have ATA or ATAPI devices */ - classes[0] = ata_dev_try_classify(&ap->link.device[0], + classes[0] = ata_sff_dev_classify(&ap->link.device[0], devmask & (1 << 0), &err); if (slave_possible && err != 0x81) - classes[1] = ata_dev_try_classify(&ap->link.device[1], + classes[1] = ata_sff_dev_classify(&ap->link.device[1], devmask & (1 << 1), &err); out: @@ -695,7 +695,7 @@ static void scc_bmdma_stop (struct ata_queued_cmd *qc) printk(KERN_WARNING "%s: Internal Bus Error\n", DRV_NAME); out_be32(bmid_base + SCC_DMA_INTST, INTSTS_BMSINT); /* TBD: SW reset */ - scc_std_softreset(&ap->link, &classes, deadline); + scc_softreset(&ap->link, &classes, deadline); continue; } @@ -721,7 +721,7 @@ static void scc_bmdma_stop (struct ata_queued_cmd *qc) in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START); /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */ - ata_altstatus(ap); /* dummy read */ + ata_sff_altstatus(ap); /* dummy read */ } /** @@ -742,7 +742,7 @@ static u8 scc_bmdma_status (struct ata_port *ap) return host_stat; /* errata A252,A308 workaround: Step4 */ - if ((ata_altstatus(ap) & ATA_ERR) && (int_status & INTSTS_INTRQ)) + if ((ata_sff_altstatus(ap) & ATA_ERR) && (int_status & INTSTS_INTRQ)) return (host_stat | ATA_DMA_INTR); /* errata A308 workaround Step5 */ @@ -773,7 +773,7 @@ static u8 scc_bmdma_status (struct ata_port *ap) * @buflen: buffer length * @rw: read/write * - * Note: Original code is ata_data_xfer(). + * Note: Original code is ata_sff_data_xfer(). */ static unsigned int scc_data_xfer (struct ata_device *dev, unsigned char *buf, @@ -815,7 +815,7 @@ static unsigned int scc_data_xfer (struct ata_device *dev, unsigned char *buf, * scc_irq_on - Enable interrupts on a port. * @ap: Port on which interrupts are enabled. * - * Note: Original code is ata_irq_on(). + * Note: Original code is ata_sff_irq_on(). */ static u8 scc_irq_on (struct ata_port *ap) @@ -835,13 +835,13 @@ static u8 scc_irq_on (struct ata_port *ap) } /** - * scc_bmdma_freeze - Freeze BMDMA controller port + * scc_freeze - Freeze BMDMA controller port * @ap: port to freeze * - * Note: Original code is ata_bmdma_freeze(). + * Note: Original code is ata_sff_freeze(). */ -static void scc_bmdma_freeze (struct ata_port *ap) +static void scc_freeze (struct ata_port *ap) { struct ata_ioports *ioaddr = &ap->ioaddr; @@ -868,18 +868,18 @@ static void scc_bmdma_freeze (struct ata_port *ap) static int scc_pata_prereset(struct ata_link *link, unsigned long deadline) { link->ap->cbl = ATA_CBL_PATA80; - return ata_std_prereset(link, deadline); + return ata_sff_prereset(link, deadline); } /** - * scc_std_postreset - standard postreset callback + * scc_postreset - standard postreset callback * @ap: the target ata_port * @classes: classes of attached devices * - * Note: Original code is ata_std_postreset(). + * Note: Original code is ata_sff_postreset(). */ -static void scc_std_postreset(struct ata_link *link, unsigned int *classes) +static void scc_postreset(struct ata_link *link, unsigned int *classes) { struct ata_port *ap = link->ap; @@ -905,13 +905,13 @@ static void scc_std_postreset(struct ata_link *link, unsigned int *classes) } /** - * scc_bmdma_irq_clear - Clear PCI IDE BMDMA interrupt. + * scc_irq_clear - Clear PCI IDE BMDMA interrupt. * @ap: Port associated with this ATA transaction. * - * Note: Original code is ata_bmdma_irq_clear(). + * Note: Original code is ata_sff_irq_clear(). */ -static void scc_bmdma_irq_clear (struct ata_port *ap) +static void scc_irq_clear (struct ata_port *ap) { void __iomem *mmio = ap->ioaddr.bmdma_addr; @@ -972,7 +972,7 @@ static struct ata_port_operations scc_pata_ops = { .exec_command = scc_exec_command, .check_status = scc_check_status, .check_altstatus = scc_check_altstatus, - .dev_select = scc_std_dev_select, + .dev_select = scc_dev_select, .bmdma_setup = scc_bmdma_setup, .bmdma_start = scc_bmdma_start, @@ -980,13 +980,13 @@ static struct ata_port_operations scc_pata_ops = { .bmdma_status = scc_bmdma_status, .data_xfer = scc_data_xfer, - .freeze = scc_bmdma_freeze, + .freeze = scc_freeze, .prereset = scc_pata_prereset, - .softreset = scc_std_softreset, - .postreset = scc_std_postreset, + .softreset = scc_softreset, + .postreset = scc_postreset, .post_internal_cmd = scc_bmdma_stop, - .irq_clear = scc_bmdma_irq_clear, + .irq_clear = scc_irq_clear, .irq_on = scc_irq_on, .port_start = scc_port_start, @@ -1140,8 +1140,8 @@ static int scc_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) if (rc) return rc; - return ata_host_activate(host, pdev->irq, ata_interrupt, IRQF_SHARED, - &scc_sht); + return ata_host_activate(host, pdev->irq, ata_sff_interrupt, + IRQF_SHARED, &scc_sht); } static struct pci_driver scc_pci_driver = { -- cgit v1.1 From 5682ed33aae05d10a25c95633ef9d9c062825888 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 7 Apr 2008 22:47:16 +0900 Subject: libata: rename SFF port ops Add sff_ prefix to SFF specific port ops. This rename is in preparation of separating SFF support out of libata core layer. This patch strictly renames ops and doesn't introduce any behavior difference. Signed-off-by: Tejun Heo --- drivers/ata/pata_scc.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) (limited to 'drivers/ata/pata_scc.c') diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c index 701d0ad..2b9da71 100644 --- a/drivers/ata/pata_scc.c +++ b/drivers/ata/pata_scc.c @@ -441,7 +441,7 @@ static void scc_bmdma_setup (struct ata_queued_cmd *qc) out_be32(mmio + SCC_DMA_CMD, dmactl); /* issue r/w command */ - ap->ops->exec_command(ap, &qc->tf); + ap->ops->sff_exec_command(ap, &qc->tf); } /** @@ -476,7 +476,7 @@ static unsigned int scc_devchk (struct ata_port *ap, struct ata_ioports *ioaddr = &ap->ioaddr; u8 nsect, lbal; - ap->ops->dev_select(ap, device); + ap->ops->sff_dev_select(ap, device); out_be32(ioaddr->nsect_addr, 0x55); out_be32(ioaddr->lbal_addr, 0xaa); @@ -525,7 +525,7 @@ static int scc_bus_post_reset(struct ata_port *ap, unsigned int devmask, while (dev1) { u8 nsect, lbal; - ap->ops->dev_select(ap, 1); + ap->ops->sff_dev_select(ap, 1); nsect = in_be32(ioaddr->nsect_addr); lbal = in_be32(ioaddr->lbal_addr); if ((nsect == 1) && (lbal == 1)) @@ -541,11 +541,11 @@ static int scc_bus_post_reset(struct ata_port *ap, unsigned int devmask, } /* is all this really necessary? */ - ap->ops->dev_select(ap, 0); + ap->ops->sff_dev_select(ap, 0); if (dev1) - ap->ops->dev_select(ap, 1); + ap->ops->sff_dev_select(ap, 1); if (dev0) - ap->ops->dev_select(ap, 0); + ap->ops->sff_dev_select(ap, 0); return 0; } @@ -616,7 +616,7 @@ static int scc_softreset(struct ata_link *link, unsigned int *classes, devmask |= (1 << 1); /* select device 0 again */ - ap->ops->dev_select(ap, 0); + ap->ops->sff_dev_select(ap, 0); /* issue bus reset */ DPRINTK("about to softreset, devmask=%x\n", devmask); @@ -829,7 +829,7 @@ static u8 scc_irq_on (struct ata_port *ap) out_be32(ioaddr->ctl_addr, ap->ctl); tmp = ata_wait_idle(ap); - ap->ops->irq_clear(ap); + ap->ops->sff_irq_clear(ap); return tmp; } @@ -854,9 +854,9 @@ static void scc_freeze (struct ata_port *ap) * ATA_NIEN manipulation. Also, many controllers fail to mask * previously pending IRQ on ATA_NIEN assertion. Clear it. */ - ap->ops->check_status(ap); + ap->ops->sff_check_status(ap); - ap->ops->irq_clear(ap); + ap->ops->sff_irq_clear(ap); } /** @@ -887,9 +887,9 @@ static void scc_postreset(struct ata_link *link, unsigned int *classes) /* is double-select really necessary? */ if (classes[0] != ATA_DEV_NONE) - ap->ops->dev_select(ap, 1); + ap->ops->sff_dev_select(ap, 1); if (classes[1] != ATA_DEV_NONE) - ap->ops->dev_select(ap, 0); + ap->ops->sff_dev_select(ap, 0); /* bail out if no device is present */ if (classes[0] == ATA_DEV_NONE && classes[1] == ATA_DEV_NONE) { @@ -967,18 +967,18 @@ static struct ata_port_operations scc_pata_ops = { .set_dmamode = scc_set_dmamode, .mode_filter = scc_mode_filter, - .tf_load = scc_tf_load, - .tf_read = scc_tf_read, - .exec_command = scc_exec_command, - .check_status = scc_check_status, - .check_altstatus = scc_check_altstatus, - .dev_select = scc_dev_select, + .sff_tf_load = scc_tf_load, + .sff_tf_read = scc_tf_read, + .sff_exec_command = scc_exec_command, + .sff_check_status = scc_check_status, + .sff_check_altstatus = scc_check_altstatus, + .sff_dev_select = scc_dev_select, .bmdma_setup = scc_bmdma_setup, .bmdma_start = scc_bmdma_start, .bmdma_stop = scc_bmdma_stop, .bmdma_status = scc_bmdma_status, - .data_xfer = scc_data_xfer, + .sff_data_xfer = scc_data_xfer, .freeze = scc_freeze, .prereset = scc_pata_prereset, @@ -986,8 +986,8 @@ static struct ata_port_operations scc_pata_ops = { .postreset = scc_postreset, .post_internal_cmd = scc_bmdma_stop, - .irq_clear = scc_irq_clear, - .irq_on = scc_irq_on, + .sff_irq_clear = scc_irq_clear, + .sff_irq_on = scc_irq_on, .port_start = scc_port_start, .port_stop = scc_port_stop, -- cgit v1.1 From 705e76beb90b97421e1f61e857c4246799781bb5 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 7 Apr 2008 22:47:19 +0900 Subject: libata: restructure SFF post-reset readiness waits Previously, post-softreset readiness is waited as follows. 1. ata_sff_wait_after_reset() waits for 150ms and then for ATA_TMOUT_FF_WAIT if status is 0xff and other conditions meet. 2. ata_bus_softreset() finishes with -ENODEV if status is still 0xff. If not, continue to #3. 3. ata_bus_post_reset() waits readiness of dev0 and/or dev1 depending on devmask using ata_sff_wait_ready(). And for post-hardreset readiness, 1. ata_sff_wait_after_reset() waits for 150ms and then for ATA_TMOUT_FF_WAIT if status is 0xff and other conditions meet. 2. sata_sff_hardreset waits for device readiness using ata_sff_wait_ready(). This patch merges and unifies post-reset readiness waits into ata_sff_wait_ready() and ata_sff_wait_after_reset(). ATA_TMOUT_FF_WAIT handling is merged into ata_sff_wait_ready(). If TF status is 0xff, link status is unknown and the port is SATA, it will continue polling till ATA_TMOUT_FF_WAIT. ata_sff_wait_after_reset() is updated to perform the following steps. 1. waits for 150ms. 2. waits for dev0 readiness using ata_sff_wait_ready(). Note that this is done regardless of devmask, as ata_sff_wait_ready() handles 0xff status correctly, this preserves the original behavior except that it may wait longer after softreset if link is online but status is 0xff. This behavior change is very unlikely to cause any actual difference and is intended. It brings softreset behavior to that of hardreset. 3. waits for dev1 readiness just the same way ata_bus_post_reset() did. Now both soft and hard resets call ata_sff_wait_after_reset() after reset to wait for readiness after resets. As ata_sff_wait_after_reset() contains calls to ->sff_dev_select(), explicit call near the end of sata_sff_hardreset() is removed. This change makes reset implementation simpler and more consistent. While at it, make the magical 150ms wait post-reset wait duration a constant and ata_sff_wait_ready() and ata_sff_wait_after_reset() take @link instead of @ap. This is to make them consistent with other reset helpers and ease core changes. pata_scc is updated accordingly. Signed-off-by: Tejun Heo --- drivers/ata/pata_scc.c | 91 ++++++++++++++++++++++++++++---------------------- 1 file changed, 51 insertions(+), 40 deletions(-) (limited to 'drivers/ata/pata_scc.c') diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c index 2b9da71..accc275 100644 --- a/drivers/ata/pata_scc.c +++ b/drivers/ata/pata_scc.c @@ -497,47 +497,68 @@ static unsigned int scc_devchk (struct ata_port *ap, } /** - * scc_bus_post_reset - PATA device post reset + * scc_wait_after_reset - wait for devices to become ready after reset * - * Note: Original code is ata_bus_post_reset(). + * Note: Original code is ata_sff_wait_after_reset */ -static int scc_bus_post_reset(struct ata_port *ap, unsigned int devmask, - unsigned long deadline) +int scc_wait_after_reset(struct ata_link *link, unsigned int devmask, + unsigned long deadline) { + struct ata_port *ap = link->ap; struct ata_ioports *ioaddr = &ap->ioaddr; unsigned int dev0 = devmask & (1 << 0); unsigned int dev1 = devmask & (1 << 1); - int rc; + int rc, ret = 0; + + /* Spec mandates ">= 2ms" before checking status. We wait + * 150ms, because that was the magic delay used for ATAPI + * devices in Hale Landis's ATADRVR, for the period of time + * between when the ATA command register is written, and then + * status is checked. Because waiting for "a while" before + * checking status is fine, post SRST, we perform this magic + * delay here as well. + * + * Old drivers/ide uses the 2mS rule and then waits for ready. + */ + msleep(150); - /* if device 0 was found in ata_devchk, wait for its - * BSY bit to clear + /* always check readiness of the master device */ + rc = ata_sff_wait_ready(link, deadline); + /* -ENODEV means the odd clown forgot the D7 pulldown resistor + * and TF status is 0xff, bail out on it too. */ - if (dev0) { - rc = ata_sff_wait_ready(ap, deadline); - if (rc && rc != -ENODEV) - return rc; - } + if (rc) + return rc; - /* if device 1 was found in ata_devchk, wait for - * register access, then wait for BSY to clear + /* if device 1 was found in ata_devchk, wait for register + * access briefly, then wait for BSY to clear. */ - while (dev1) { - u8 nsect, lbal; + if (dev1) { + int i; ap->ops->sff_dev_select(ap, 1); - nsect = in_be32(ioaddr->nsect_addr); - lbal = in_be32(ioaddr->lbal_addr); - if ((nsect == 1) && (lbal == 1)) - break; - if (time_after(jiffies, deadline)) - return -EBUSY; - msleep(50); /* give drive a breather */ - } - if (dev1) { - rc = ata_sff_wait_ready(ap, deadline); - if (rc && rc != -ENODEV) - return rc; + + /* Wait for register access. Some ATAPI devices fail + * to set nsect/lbal after reset, so don't waste too + * much time on it. We're gonna wait for !BSY anyway. + */ + for (i = 0; i < 2; i++) { + u8 nsect, lbal; + + nsect = in_be32(ioaddr->nsect_addr); + lbal = in_be32(ioaddr->lbal_addr); + if ((nsect == 1) && (lbal == 1)) + break; + msleep(50); /* give drive a breather */ + } + + rc = ata_sff_wait_ready(link, deadline); + if (rc) { + if (rc != -ENODEV) + return rc; + ret = rc; + } } /* is all this really necessary? */ @@ -547,7 +568,7 @@ static int scc_bus_post_reset(struct ata_port *ap, unsigned int devmask, if (dev0) ap->ops->sff_dev_select(ap, 0); - return 0; + return ret; } /** @@ -570,17 +591,7 @@ static unsigned int scc_bus_softreset(struct ata_port *ap, unsigned int devmask, udelay(20); out_be32(ioaddr->ctl_addr, ap->ctl); - /* wait a while before checking status */ - ata_sff_wait_after_reset(ap, deadline); - - /* Before we perform post reset processing we want to see if - * the bus shows 0xFF because the odd clown forgets the D7 - * pulldown resistor. - */ - if (scc_check_status(ap) == 0xFF) - return 0; - - scc_bus_post_reset(ap, devmask, deadline); + scc_wait_after_reset(&ap->link, devmask, deadlien); return 0; } -- cgit v1.1 From e50e3ce5e70e36e6069a8cc8292df76058fa9e23 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Wed, 9 Apr 2008 13:34:40 +1000 Subject: pata_scc: fix build breakage drivers/ata/pata_scc.c: In function 'scc_bus_softreset': drivers/ata/pata_scc.c:594: error: 'deadlien' undeclared (first use in this function) drivers/ata/pata_scc.c:594: error: (Each undeclared identifier is reported only once drivers/ata/pata_scc.c:594: error: for each function it appears in.) Signed-off-by: Stephen Rothwell Signed-off-by: Jeff Garzik --- drivers/ata/pata_scc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/ata/pata_scc.c') diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c index accc275..7bdea8a 100644 --- a/drivers/ata/pata_scc.c +++ b/drivers/ata/pata_scc.c @@ -591,7 +591,7 @@ static unsigned int scc_bus_softreset(struct ata_port *ap, unsigned int devmask, udelay(20); out_be32(ioaddr->ctl_addr, ap->ctl); - scc_wait_after_reset(&ap->link, devmask, deadlien); + scc_wait_after_reset(&ap->link, devmask, deadline); return 0; } -- cgit v1.1 From 45db2f6c95eee7c6622ea1b3edb9abafba58e3ab Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 8 Apr 2008 01:46:56 +0900 Subject: libata: move link onlineness check out of softreset methods Currently, SATA softresets should do link onlineness check before actually performing SRST protocol but it doesn't really belong to softreset. This patch moves onlineness check in softreset to ata_eh_reset() and ata_eh_followup_srst_needed() to clean up code and help future sata_mv changes which need clear separation between SCR and TF accesses. sata_fsl is peculiar in that its softreset really isn't softreset but combination of hardreset and softreset. This patch adds dummy private ->prereset to keep the current behavior but the driver really should implement separate hard and soft resets and return -EAGAIN from hardreset if it should be follwed by softreset. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/pata_scc.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers/ata/pata_scc.c') diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c index 7bdea8a..e965b25 100644 --- a/drivers/ata/pata_scc.c +++ b/drivers/ata/pata_scc.c @@ -615,11 +615,6 @@ static int scc_softreset(struct ata_link *link, unsigned int *classes, DPRINTK("ENTER\n"); - if (ata_link_offline(link)) { - classes[0] = ATA_DEV_NONE; - goto out; - } - /* determine if device 0/1 are present */ if (scc_devchk(ap, 0)) devmask |= (1 << 0); @@ -645,7 +640,6 @@ static int scc_softreset(struct ata_link *link, unsigned int *classes, classes[1] = ata_sff_dev_classify(&ap->link.device[1], devmask & (1 << 1), &err); - out: DPRINTK("EXIT, classes[0]=%u [1]=%u\n", classes[0], classes[1]); return 0; } -- cgit v1.1