From 8b2af8f0ca807eb13b59dc5961d2e99fc2b1bd87 Mon Sep 17 00:00:00 2001 From: Edward Falk Date: Wed, 15 Jun 2005 14:26:39 -0700 Subject: [PATCH] Minor libata documentation patch I fleshed out libata.tmpl a bit while I was taking notes. diff --git a/Documentation/DocBook/libata.tmpl b/Documentation/DocBook/libata.tmpl index 6df1dfd..375ae76 100644 --- a/Documentation/DocBook/libata.tmpl +++ b/Documentation/DocBook/libata.tmpl @@ -84,6 +84,14 @@ void (*port_disable) (struct ata_port *); Called from ata_bus_probe() and ata_bus_reset() error paths, as well as when unregistering from the SCSI module (rmmod, hot unplug). + This function should do whatever needs to be done to take the + port out of use. In most cases, ata_port_disable() can be used + as this hook. + + + Called from ata_bus_probe() on a failed probe. + Called from ata_bus_reset() on a failed bus reset. + Called from ata_scsi_release(). @@ -98,6 +106,13 @@ void (*dev_config) (struct ata_port *, struct ata_device *); found. Typically used to apply device-specific fixups prior to issue of SET FEATURES - XFER MODE, and prior to operation. + + Called by ata_device_add() after ata_dev_identify() determines + a device is present. + + + This entry may be specified as NULL in ata_port_operations. + @@ -135,6 +150,8 @@ void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf); registers / DMA buffers. ->tf_read() is called to read the hardware registers / DMA buffers, to obtain the current set of taskfile register values. + Most drivers for taskfile-based hardware (PIO or MMIO) use + ata_tf_load() and ata_tf_read() for these hooks. @@ -147,6 +164,8 @@ void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf); causes an ATA command, previously loaded with ->tf_load(), to be initiated in hardware. + Most drivers for taskfile-based hardware use ata_exec_command() + for this hook. @@ -161,6 +180,10 @@ Allow low-level driver to filter ATA PACKET commands, returning a status indicating whether or not it is OK to use DMA for the supplied PACKET command. + + This hook may be specified as NULL, in which case libata will + assume that atapi dma can be supported. + @@ -175,6 +198,14 @@ u8 (*check_err)(struct ata_port *ap); Reads the Status/AltStatus/Error ATA shadow register from hardware. On some hardware, reading the Status register has the side effect of clearing the interrupt condition. + Most drivers for taskfile-based hardware use + ata_check_status() for this hook. + + + Note that because this is called from ata_device_add(), at + least a dummy function that clears device interrupts must be + provided for all drivers, even if the controller doesn't + actually have a taskfile status register. @@ -188,7 +219,13 @@ void (*dev_select)(struct ata_port *ap, unsigned int device); Issues the low-level hardware command(s) that causes one of N hardware devices to be considered 'selected' (active and available for use) on the ATA bus. This generally has no -meaning on FIS-based devices. + meaning on FIS-based devices. + + + Most drivers for taskfile-based hardware use + ata_std_dev_select() for this hook. Controllers which do not + support second drives on a port (such as SATA contollers) will + use ata_noop_dev_select(). @@ -204,6 +241,8 @@ void (*phy_reset) (struct ata_port *ap); for device presence (PATA and SATA), typically a soft reset (SRST) will be performed. Drivers typically use the helper functions ata_bus_reset() or sata_phy_reset() for this hook. + Many SATA drivers use sata_phy_reset() or call it from within + their own phy_reset() functions. @@ -227,6 +266,25 @@ PCI IDE DMA Status register. These hooks are typically either no-ops, or simply not implemented, in FIS-based drivers. + +Most legacy IDE drivers use ata_bmdma_setup() for the bmdma_setup() +hook. ata_bmdma_setup() will write the pointer to the PRD table to +the IDE PRD Table Address register, enable DMA in the DMA Command +register, and call exec_command() to begin the transfer. + + +Most legacy IDE drivers use ata_bmdma_start() for the bmdma_start() +hook. ata_bmdma_start() will write the ATA_DMA_START flag to the DMA +Command register. + + +Many legacy IDE drivers use ata_bmdma_stop() for the bmdma_stop() +hook. ata_bmdma_stop() clears the ATA_DMA_START flag in the DMA +command register. + + +Many legacy IDE drivers use ata_bmdma_status() as the bmdma_status() hook. + @@ -250,6 +308,10 @@ int (*qc_issue) (struct ata_queued_cmd *qc); helper function ata_qc_issue_prot() for taskfile protocol-based dispatch. More advanced drivers implement their own ->qc_issue. + + ata_qc_issue_prot() calls ->tf_load(), ->bmdma_setup(), and + ->bmdma_start() as necessary to initiate a transfer. + @@ -279,6 +341,21 @@ void (*irq_clear) (struct ata_port *); before the interrupt handler is registered, to be sure hardware is quiet. + + The second argument, dev_instance, should be cast to a pointer + to struct ata_host_set. + + + Most legacy IDE drivers use ata_interrupt() for the + irq_handler hook, which scans all ports in the host_set, + determines which queued command was active (if any), and calls + ata_host_intr(ap,qc). + + + Most legacy IDE drivers use ata_bmdma_irq_clear() for the + irq_clear() hook, which simply clears the interrupt and error + flags in the DMA status register. + @@ -292,6 +369,7 @@ void (*scr_write) (struct ata_port *ap, unsigned int sc_reg, Read and write standard SATA phy registers. Currently only used if ->phy_reset hook called the sata_phy_reset() helper function. + sc_reg is one of SCR_STATUS, SCR_CONTROL, SCR_ERROR, or SCR_ACTIVE. @@ -307,17 +385,29 @@ void (*host_stop) (struct ata_host_set *host_set); ->port_start() is called just after the data structures for each port are initialized. Typically this is used to alloc per-port DMA buffers / tables / rings, enable DMA engines, and similar - tasks. + tasks. Some drivers also use this entry point as a chance to + allocate driver-private memory for ap->private_data. + + + Many drivers use ata_port_start() as this hook or call + it from their own port_start() hooks. ata_port_start() + allocates space for a legacy IDE PRD table and returns. ->port_stop() is called after ->host_stop(). It's sole function is to release DMA/memory resources, now that they are no longer - actively being used. + actively being used. Many drivers also free driver-private + data from port at this time. + + + Many drivers use ata_port_stop() as this hook, which frees the + PRD table. ->host_stop() is called after all ->port_stop() calls have completed. The hook must finalize hardware shutdown, release DMA and other resources, etc. + This hook may be specified as NULL, in which case it is not called. -- cgit v0.10.2 From e922256ae4bb6ef954bd7e0740d9753460e0ab72 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Tue, 28 Jun 2005 00:03:37 -0400 Subject: libata: update DMA blacklist Contributions from Alan Cox and maximilian attems. diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 36b401f..fd66f56 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c @@ -1920,6 +1920,7 @@ static const char * ata_dma_blacklist [] = { "HITACHI CDR-8335", "HITACHI CDR-8435", "Toshiba CD-ROM XM-6202B", + "TOSHIBA CD-ROM XM-1702BC", "CD-532E-A", "E-IDE CD-ROM CR-840", "CD-ROM Drive/F5A", @@ -1927,7 +1928,6 @@ static const char * ata_dma_blacklist [] = { "SAMSUNG CD-ROM SC-148C", "SAMSUNG CD-ROM SC", "SanDisk SDP3B-64", - "SAMSUNG CD-ROM SN-124", "ATAPI CD-ROM DRIVE 40X MAXIMUM", "_NEC DV5800A", }; -- cgit v0.10.2 From 62ba2841f2a51848f7cb0499edae3f6803764f2c Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 26 Jun 2005 23:27:19 +0900 Subject: [PATCH] libata: lengthen COMMRESET delay This patch lengthens the delay between DET setting and clearing for COMMRESET from 400us to 1ms. I couldn't find any requiremen regarding the duration of COMMRESET in SATA I/II specs but AHCI-1.1 10.4.2 states that it should be at least 1ms. Signed-off-by: Tejun Heo diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index fd66f56..cb535fa 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c @@ -1408,7 +1408,9 @@ void __sata_phy_reset(struct ata_port *ap) if (ap->flags & ATA_FLAG_SATA_RESET) { /* issue phy wake/reset */ scr_write_flush(ap, SCR_CONTROL, 0x301); - udelay(400); /* FIXME: a guess */ + /* Couldn't find anything in SATA I/II specs, but + * AHCI-1.1 10.4.2 says at least 1 ms. */ + mdelay(1); } scr_write_flush(ap, SCR_CONTROL, 0x300); /* phy wake/clear reset */ -- cgit v0.10.2 From 0a139e79976b9eb60517edec63406236a789f812 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 26 Jun 2005 23:52:50 +0900 Subject: [PATCH] libata: ahci: remove ata_port_start/stop() calls This patch removes unnecessary ata_port_start/stop() calls from ahci_port_start/stop(). Signed-off-by: Tejun Heo diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c index 9a547ca..c562369 100644 --- a/drivers/scsi/ahci.c +++ b/drivers/scsi/ahci.c @@ -304,26 +304,19 @@ static int ahci_port_start(struct ata_port *ap) struct device *dev = ap->host_set->dev; struct ahci_host_priv *hpriv = ap->host_set->private_data; struct ahci_port_priv *pp; - int rc; void *mem, *mmio = ap->host_set->mmio_base; void *port_mmio = ahci_port_base(mmio, ap->port_no); dma_addr_t mem_dma; - rc = ata_port_start(ap); - if (rc) - return rc; - pp = kmalloc(sizeof(*pp), GFP_KERNEL); - if (!pp) { - rc = -ENOMEM; - goto err_out; - } + if (!pp) + return -ENOMEM; memset(pp, 0, sizeof(*pp)); mem = dma_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma, GFP_KERNEL); if (!mem) { - rc = -ENOMEM; - goto err_out_kfree; + kfree(pp); + return -ENOMEM; } memset(mem, 0, AHCI_PORT_PRIV_DMA_SZ); @@ -373,12 +366,6 @@ static int ahci_port_start(struct ata_port *ap) readl(port_mmio + PORT_CMD); /* flush */ return 0; - -err_out_kfree: - kfree(pp); -err_out: - ata_port_stop(ap); - return rc; } @@ -404,7 +391,6 @@ static void ahci_port_stop(struct ata_port *ap) dma_free_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, pp->cmd_slot, pp->cmd_slot_dma); kfree(pp); - ata_port_stop(ap); } static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg_in) -- cgit v0.10.2