GIT 471aa5d378eb6e56ad73814121603d351ce90544 git+ssh://master.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev.git#ALL commit Author: Jeff Garzik Date: Mon May 28 06:21:45 2007 -0400 [libata] sata_sx4: convert to new EH Signed-off-by: Jeff Garzik commit 2de8d964ef4f247d1eb89d676ef9920a1add7c3b Author: akpm@linux-foundation.org Date: Tue Jan 15 16:01:52 2008 -0800 [libata] Prefer SCSI_SENSE_BUFFERSIZE to sizeof() Cc: James Bottomley Cc: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik commit cbf4d9800b47bf7c5a4a8fa092c657cdf961d6af Author: Alan Cox Date: Thu Jan 10 14:33:10 2008 -0800 pata_legacy: resychronize with upstream changes and resubmit Update the legacy driver so it can handle VLB ports nicely, and has an internal structure for nailing new ISA/VLB forms in. Anyone got an ALI14xx and a spare day ;) Also adds an "all" parameter so you can load this driver after all the PCI ones in a boot time kernel and tell it to grab anything ST412 compatible even if it is an unknown PCI device. That allows libata to offer the same "just get me a disk somehow" fallback that old IDE did. Obsoletes pata_qdi. Signed-off-by: Alan Cox Cc: Tejun Heo Cc: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik commit 0c84ceb02048c747509ed133570c537531578836 Author: Andrew Morton Date: Tue Jan 15 15:42:37 2008 -0800 [libata] pata_legacy: typo fix Cc: Jeff Garzik Cc: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik commit 2204ae913e2642fbcfcebe6dc20e19c133391620 Author: Andrew Morton Date: Thu Jan 10 14:33:04 2008 -0800 [libata] pata_winbond: update for new ->data_xfer hook drivers/spi/Kconfig:156:warning: 'select' used by config symbol 'SPI_PXA2XX' refers to undefined symbol 'PXA_SSP' drivers/ata/pata_winbond.c: In function 'winbond_data_xfer': drivers/ata/pata_winbond.c:109: error: 'read' undeclared (first use in this function) drivers/ata/pata_winbond.c:109: error: (Each undeclared identifier is reported only once drivers/ata/pata_winbond.c:109: error: for each function it appears in.) drivers/ata/pata_winbond.c:123: warning: 'return' with a value, in function returning void drivers/ata/pata_winbond.c: At top level: drivers/ata/pata_winbond.c:162: warning: initialization from incompatible pointer type distcc[29718] ERROR: compile drivers/ata/pata_winbond.c on bix/8 failed make[1]: *** [drivers/ata/pata_winbond.o] Error 1 make: *** [drivers/ata/pata_winbond.o] Error 2 Cc: Jeff Garzik Cc: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik commit 0f46b3d01a4e58e8c6eba72b5bc3acfa53453cc5 Author: Tejun Heo Date: Wed Jan 2 20:12:47 2008 +0900 pata_pcmcia: convert to new data_xfer prototype While merging data_xfer prototype change, pata_pcmcia was left out. Convert it. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik commit d0455867ce74f43a5be58759b38d515f51daab4c Author: Al Viro Date: Sun Dec 30 09:32:22 2007 +0000 libata annotations and fixes Signed-off-by: Al Viro Signed-off-by: Jeff Garzik commit d262fb6d279835530be8305146ab4c31a5f666f4 Author: Tejun Heo Date: Fri Jan 4 18:42:21 2008 +0900 libata: use dev_driver_string() instead of "libata" in libata-sff.c libata-sff code used DRV_NAME which is hardcoded to "libata" when requesting resources. Use dev_driver_string() such that low level driver names are used in resource listing. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik commit eb775564cb4932137a7ecbc31853c520980b59bd Author: Tejun Heo Date: Fri Jan 4 18:42:20 2008 +0900 ata_piix: kill unused constants and flags Kill PIIX_FLAG_SCR, PIIX_PORT_ENABLED and PIIX_PORT_PRESENT. These are unused. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik commit dfcdf4d0e7008f6654703b3d0ea66e80f23b5bc0 Author: Jeff Garzik Date: Wed Dec 19 04:25:10 2007 -0500 libata: make ata_port_queue_task() an internal function ata_port_queue_task() served a single user: ata_pio_task() Rename to ata_pio_queue_task() and un-export it, as nobody outside of libata-core.c uses it. Signed-off-by: Jeff Garzik commit b8388eb5483667e1697c29efe62b2228a81dc983 Author: Alan Cox Date: Mon Nov 19 14:43:07 2007 +0000 pata_pcmcia: Minor cleanups and support for dual channel cards Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik commit c8f8b76954204b90b3e3f587c275c0d72b90483b Author: Alan Cox Date: Thu Oct 25 14:21:16 2007 +0100 libata/pata_it821x: Improve handling of poorly compatible emulations Some it821x RAID firmwares return 0 for the err return off both devices. A similar issue occurs with the slave returning 0 not 1 if you plug a gigabyte sata ramdisk into a controller that fakes two SATA ports as master/slave on an SFF channel. The patch does the following - Allow the 'failed diagnostics' case on both master and slave - Move the HORKAGE_DIAGNOSTIC check after ->dev_config This second change also allows IT821x to fix up a problem where we report drive diagnostic failures when in fact the drive is fine but the microcontroller firmware doesn't appear to get it right. IT821x clears the flag again to avoid giving the user bogus warnings about their disk. The other IT821x change is a bit ugly, we slightly abuse the cable type hook to fiddle with the identify data for the devices. We could add a new hook for this but as we have only one offender and no more seeming likely it seems better to keep libata-core clean. Please let this sit in -mm briefly, just in case the relaxed checking breaks some other emulated interface. Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik commit 6714119eb394b796ea2fc294ff722a724f3569db Author: Alan Cox Date: Mon Oct 15 20:44:11 2007 +0100 pata_pcmcia: Add support for dumb 8bit IDE emulations Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik commit 44edf26f037049eeb7c9dfab059c4d81f762a4bd Author: Alan Date: Tue Oct 2 13:53:05 2007 -0700 libata: fix (hopefully) all the remaining problems with devices failing setup/identify Two fixes in this test patch. One of them allows old CF cards to refuse pio mode setting, and one to wait for the drive to settle after a set features changes the speed settings, which is based upon the workarounds used by drivers/ide. Please test and report back if you have an afflicted system. This patch isn't for merging just testing. The CF card fix will still display errors when the card works (got fixes for that once I know the cure works) but should then be found/usable. Not signed off by anyone, not for merging Signed-off-by: Andrew Morton commit 00c3557776a7fa354c53b85fbb895c2474a1c3fe Author: Tejun Heo Date: Wed Dec 5 16:43:12 2007 +0900 libata: make qc->nbytes include extra buffers qc->nbytes didn't use to include extra buffers setup by libata core layer and my be odd. This patch makes qc->nbytes include any extra buffers setup by libata core layer and guaranteed to be aligned on 4 byte boundary. This value is to be used to program the host controller. As this represents the actual length of buffer available to the controller and the controller must be able to deal with short transfers for ATAPI commands which can transfer variable length, this shouldn't break any controllers while making problems like rounding-down and controllers choking up on odd transfer bytes much less likely. The unmodified value is stored in new field qc->raw_nbytes. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik commit a3a0798d47cfb0c87e6444000879fdcfb6ee33e3 Author: Tejun Heo Date: Wed Dec 5 16:43:11 2007 +0900 libata: convert to chained sg libata used private sg iterator to handle padding sg. Now that sg can be chained, padding can be handled using standard sg ops. Convert to chained sg. * s/qc->__sg/qc->sg/ * s/qc->pad_sgent/qc->extra_sg[]/. Because chaining consumes one sg entry. There need to be two extra sg entries. The renaming is also for future addition of other extra sg entries. * Padding setup is moved into ata_sg_setup_extra() which is organized in a way that future addition of other extra sg entries is easy. * qc->orig_n_elem is unused and removed. * qc->n_elem now contains the number of sg entries that LLDs should map. qc->mapped_n_elem is added to carry the original number of mapped sgs for unmapping. * The last sg of the original sg list is used to chain to extra sg list. The original last sg is pointed to by qc->last_sg and the content is stored in qc->saved_last_sg. It's restored during ata_sg_clean(). * All sg walking code has been updated. Unnecessary assertions and checks for conditions the core layer already guarantees are removed. Signed-off-by: Tejun Heo Cc: Jens Axboe Signed-off-by: Jeff Garzik commit 105b6f57bd6e0c21d46495f1907d0addd66f1de5 Author: Tejun Heo Date: Wed Dec 5 16:43:10 2007 +0900 libata: change ATA_QCFLAG_DMAMAP semantics ATA_QCFLAG_DMAMAP was a bit peculiar in that it got set during qc initialization and cleared if DMA mapping wasn't necessary. Make it more straight forward by making the following changes. * Don't set it during initialization. Set it after DMA is actually mapped. * Add BUG_ON() to guarantee that there is data to transfer if DMAMAP is set. This always holds for the current code. The BUG_ON() is for docummentation and sanity check. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik commit 994e0b9e4f31548edb989eff0726341a213a9c49 Author: Tejun Heo Date: Wed Dec 5 16:43:09 2007 +0900 libata: kill non-sg DMA interface With atapi_request_sense() converted to use sg, there's no user of non-sg interface. Kill non-sg interface. * ATA_QCFLAG_SINGLE and ATA_QCFLAG_SG are removed. ATA_QCFLAG_DMAMAP is used instead. (this way no LLD change is necessary) * qc->buf_virt is removed. * ata_sg_init_one() and ata_sg_setup_one() are removed. Signed-off-by: Tejun Heo Cc: Rusty Russel Signed-off-by: Jeff Garzik commit a55dd8a3e89c175c727b9cf9199b3d044d076c13 Author: Tejun Heo Date: Wed Dec 5 16:43:07 2007 +0900 libata: update ->data_xfer hook for ATAPI Depending on how many bytes are transferred as a unit, PIO data transfer may consume more bytes than requested. Knowing how much data is consumed is necessary to determine how much is left for draining. This patch update ->data_xfer such that it returns the number of consumed bytes. While at it, it also makes the following changes. * s/adev/dev/ * use READ/WRITE constants for rw indication * misc clean ups Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik commit b6680fc327903c1c95f13fef2c1be6941ec205e5 Author: Tejun Heo Date: Wed Dec 5 16:43:06 2007 +0900 libata: add ATAPI_* cmd types and implement atapi_cmd_type() Add ATAPI command types - ATAPI_READ, WRITE, RW_BUF, READ_CD and MISC, and implement atapi_cmd_type() which takes SCSI opcode and returns to which class the opcode belongs. This will be used later to improve ATAPI handling. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik commit c8d0c3877c1e026e264bb35f49ae0ee8f927b1a4 Author: Tejun Heo Date: Tue Dec 18 16:34:43 2007 -0500 libata: rename ATA_PROT_ATAPI_* to ATAPI_PROT_* ATA_PROT_ATAPI_* are ugly and naming schemes between ATA_PROT_* and ATA_PROT_ATAPI_* are inconsistent causing confusion. Rename them to ATAPI_PROT_* and make them consistent with ATA counterpart. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik commit 284f32eb0c5c526a833ac164e756e6123e6b9f23 Author: Tejun Heo Date: Wed Dec 5 16:43:04 2007 +0900 cdrom: add more GPCMD_* constants Add GPCMD_* constants for READ_BUFFER, WRITE_12 and WRITE_BUFFER for completeness. These will be used libata. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik commit db6014b494ce1c55818c7e8c02411d838a39405f Author: Albert Lee Date: Wed Dec 5 16:43:02 2007 +0900 libata: zero xfer length on ATAPI data xfer IRQ is HSM violation Treat zero xfer length as HSM violation. While at it, add unlikely()'s to ATAPI ireason and transfer length checks. tj: Formatted patch and added unlikely()'s. Signed-off-by: Albert Lee Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik commit 3c7ca173b981f4a2a812b2fd149db8886f798d96 Author: Tejun Heo Date: Wed Dec 5 16:43:01 2007 +0900 libata: make atapi_request_sense() use sg atapi_request_sense() is now the only left user of ata_sg_init_one(). Convert it to use sg interface. Signed-off-by: Tejun Heo Cc: Rusty Russel Signed-off-by: Jeff Garzik commit a9c895707c426ca0acbf192ceba091d2a921857e Author: Tejun Heo Date: Wed Dec 5 10:36:13 2007 +0900 libata: convert NCQ test in ata_qc_issue() to ata_is_ncq() I missed one while converting to ata_is_*() protocol test helpers. Convert it. Pointed out by Jeff Garzik. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik commit e3e506e050b80abed9277aebde7a958695a7d6bf Author: Andrew Morton Date: Thu Dec 13 16:01:38 2007 -0800 pata_hpt37x: checkpatch fixes WARNING: line over 80 characters #70: FILE: drivers/ata/pata_hpt37x.c:850: + struct pci_dev *pdev_0 = pci_get_slot(pdev->bus, pdev->devfn - 1); ERROR: else should follow close brace '}' #78: FILE: drivers/ata/pata_hpt37x.c:858: + } + else total: 1 errors, 1 warnings, 100 lines checked Your patch has style problems, please review. If any of these errors are false positives report them to the maintainer, see CHECKPATCH in MAINTAINERS. Please run checkpatch prior to sending patches Cc: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik commit c996a508118e7f012398bd4c749c1b29ecf44fd0 Author: Andrew Morton Date: Thu Dec 13 16:01:37 2007 -0800 drivers/ata/libata-eh.c: fix printk warning drivers/ata/libata-eh.c: In function `ata_port_pbar_desc': drivers/ata/libata-eh.c:215: warning: long long unsigned int format, long unsigned int arg (arg 4) Cc: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik commit 0321e3f4c183c5fba224cfb2d6795cd51f1ffd00 Author: Tejun Heo Date: Tue Dec 18 16:33:07 2007 +0900 pata_amd: update mode selection for NV PATAs Cable detection on NV PATA hosts isn't implemented and the CBLID- cable isn't wired according to the sepc either, so both host-side and generic drive-side cable detections are broken. Till now, nv_cable_detect() relied on peeking BIOS and ACPI configurations to upgrade to 80C but this often results in misdetection of 40C cable as 80C. Also, the original implementation was broken in that by the time BIOS configuration is read it has already been cleared by programming PIO0 during reset. This patch reimplements NV mode selection such that... * BIOS configuration value is stored during driver attach and restored on detach. * Cable type is fixed to ATA_CBL_PATA_IGN and mode selection is soley done by nv_mode_filter() which peeks both BIOS and ACPI configurations and filter accordingly. Signed-off-by: Tejun Heo Cc: Alan Cox Signed-off-by: Jeff Garzik commit 2ff18d5e17c58a3414ddc5b530cf7d6ca2547201 Author: Tejun Heo Date: Tue Dec 18 16:33:06 2007 +0900 libata: reimplement ata_acpi_cbl_80wire() using ata_acpi_gtm_xfermask() Reimplement ata_acpi_cbl_80wire() using ata_acpi_gtm_xfermask() and while at it relocate the function below ata_acpi_gtm_xfermask(). New ata_acpi_cbl_80wire() implementation takes @gtm, in both pata_via and pata_amd, use the initial GTM value. Both are trying to peek initial BIOS configuration, so using initial caching value makes sense. This fixes ACPI part of cable detection in pata_amd which previously always returned 0 because configuring PIO0 during reset clears DMA configuration. Signed-off-by: Tejun Heo Cc: Alan Cox Signed-off-by: Jeff Garzik commit 8ca04f83d8e6252407b45d8546eb930bf5e1f9d6 Author: Tejun Heo Date: Tue Dec 18 16:33:05 2007 +0900 libata: implement ata_timing_cycle2mode() and use it in libata-acpi and pata_acpi libata-acpi is using separate timing tables for transfer modes although libata-core has the complete ata_timing table. Implement ata_timing_cycle2mode() to look for matching mode given transfer type and cycle duration and use it in libata-acpi and pata_acpi to replace private timing tables. Signed-off-by: Tejun Heo Cc: Alan Cox Signed-off-by: Jeff Garzik commit 00c260b306b9a81f8d20827deddce8587616b5a5 Author: Tejun Heo Date: Tue Dec 18 16:33:04 2007 +0900 libata: fix ata_acpi_gtm_xfermask() ata_acpi_gtm_xfermask() as separated out from pacpi_discover_modes() has various bugs. Fix them. * The wrong comparison operator is used when finding for matching cycle resulting totally bogus result. * With the comparion operator fixed, boundary condtion handling is clumsy. * Setting of any DMA mask bit set all bits in PIO mask. * MWDMA and UDMA blocks are swapped. Signed-off-by: Tejun Heo Cc: Alan Cox Signed-off-by: Jeff Garzik commit 9eafdeb75605ccaef90ae5eeaf91a4149cafbe09 Author: Tejun Heo Date: Tue Dec 18 16:33:03 2007 +0900 libata: separate out ata_acpi_gtm_xfermask() from pacpi_discover_modes() Finding out matching transfer mode from ACPI GTM values is useful for other purposes too. Separate out the function and timing tables from pata_acpi::pacpi_discover_modes(). Other than checking shared-configuration bit after doing ata_acpi_gtm() in pacpi_discover_modes() which should be safe, this patch doesn't introduce any behavior change. Signed-off-by: Tejun Heo Cc: Alan Cox Signed-off-by: Jeff Garzik commit cf946ac2005b619df75397ff14aa1e4d4ad45485 Author: Tejun Heo Date: Sat Nov 24 21:16:07 2007 +0900 ata_piix: separate controller IDs into separate enum Separate controller IDs into a separate enum as Jeff requested. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik commit 4a76f47b202d216a4f512754917d459e0f9ad487 Author: Tejun Heo Date: Tue Dec 4 13:33:30 2007 +0900 sata_promise: make pdc_atapi_pkt() use values from qc->tf Make pdc_atapi_pkt() use values from qc->tf instead of creating its own. This is to ease future ATAPI handling changes. Signed-off-by: Tejun Heo Cc: Mikael Pettersson Signed-off-by: Jeff Garzik commit 496f18aa8f634e2208aa37984f58f6b838fae1fb Author: Tejun Heo Date: Tue Nov 27 19:43:48 2007 +0900 libata: add ATA_CBL_PATA_IGN ATA_CBL_PATA_UNK indicates that the cable type can't be determined from the host side and might be either 80c or 40c. libata applies drive or other generic limit in this case. However, there are controllers where both host and drive side detections are misimplemented and the driver has to rely solely on private method - peeking BIOS or ACPI configuration or using some other private mechanism. This patch adds ATA_CBL_PATA_IGN which tells libata to ignore the cable type completely and just let the LLD determine the transfer mode via host transfer mode masks and ->mode_filter(). Signed-off-by: Tejun Heo Cc: Alan Cox Signed-off-by: Jeff Garzik commit b1809e79ab3e931535c851b6b891a61a07818b79 Author: Tejun Heo Date: Tue Nov 27 19:43:42 2007 +0900 libata: xfer_mask is unsigned long not unsigned int Jeff says xfer_mask is unsigned long not unsigned int. Convert all xfermask fields and handling functions to deal with unsigned longs. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik commit d79b1ff561c4507019f545019df11ee45e43a40e Author: Tejun Heo Date: Tue Nov 27 19:43:41 2007 +0900 libata: kill ata_id_to_dma_mode() ata_id_to_dma_mode() isn't quite generic. The function is basically privately implemented ata_id_xfermask() combined with hardcoded mode printing and configuration which are specific to ata_generic. Kill the function and open code it in generic_set_mode() using generic xfermode handling functions. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik commit 7e01a2d43781028de0243bbd456d84b214c8bb45 Author: Tejun Heo Date: Tue Nov 27 19:43:40 2007 +0900 libata: clean up xfermode / PATA timing related stuff * s/ATA_BITS_(PIO|MWDMA|UDMA)/ATA_NR_\1_MODES/g * Consistently use 0xff to indicate invalid transfer mode (0x00 is valid for PIO_SLOW). * Make ata_xfer_mode2mask() return proper mode mask instead of just the highest bit. * Sort ata_timing table in increasing xfermode order and update ata_timing_find_mode() accordingly. This patch doesn't introduce any behavior change. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik commit 2a3ba6e57af39ba492325465ba0405dddffee6cf Author: Tejun Heo Date: Tue Nov 27 19:43:39 2007 +0900 libata: export xfermode / PATA timing related functions Export the following xfermode related functions. * ata_pack_xfermask() * ata_unpack_xfermask() * ata_xfer_mask2mode() * ata_xfer_mode2mask() * ata_xfer_mode2shift() * ata_mode_string() * ata_id_xfermask() * ata_timing_find_mode() These functions will be used later by LLD updates. While at it, change unsigned short @speed to u8 @xfer_mode in ata_timing_find_mode() for consistency. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik commit 8d0d94c16e18427d634b18eacbeeb17661a2d821 Author: Tejun Heo Date: Tue Nov 27 19:43:38 2007 +0900 ata_generic: unindent loop in generic_set_mode() Unindent loop body in generic_set_mode(). This is to ease future change. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik commit cbce856b61e55f43413e33f3c94a00138aaad230 Author: Jeff Garzik Date: Sat Dec 1 18:05:39 2007 -0500 [libata] Build fix WRT ata_is_xxx() new API introduction Signed-off-by: Jeff Garzik commit 30a8d8d4901c5813cfb8c92d5b629310cb17930f Author: Tejun Heo Date: Tue Nov 27 19:28:59 2007 +0900 libata: implement fast speed down for unverified data transfer mode It's very likely that the configured data transfer mode is the wrong one if device fails data transfers right after initial data transfer mode configuration (including NCQ on/off and xfermode). libata EH needs to speed down fast before upper layers give up on probing. This patch implement fast speed down rules to handle such cases better. Error occured while data transfer hasn't been verified trigger fast back-to-back speed down actions until data transfer works. This change will make cable mis-detection and other initial configuration problems corrected before partition scanning code gives up. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik commit 05a30668155b70178901c07c34f7ff9c142ec308 Author: Tejun Heo Date: Tue Nov 27 19:28:58 2007 +0900 libata: implement ATA_DFLAG_DUBIOUS_XFER ATA_DFLAG_DUBIOUS_XFER is set whenever data transfer speed or method changes and gets cleared when data transfer command succeeds in the newly configured transfer mode. This will be used to improve speed down logic. Signed-off-by: Tejun Heo commit 2380f7be175494b4571d1c9a3afc1b932afbcce3 Author: Tejun Heo Date: Tue Nov 27 19:28:57 2007 +0900 libata: adjust speed down rules Speed down rules were too conservative. Adjust them a bit. * More than 10 timeouts can't happen in 5 minutes as command timeout is 30secs. Lower the limit for rule #1 to 6. * 10 timeouts is too high for rule #3 too. Lower it to 6. * SATAPI can benefit from falling back to PIO too. Allow SATAPI devices to fall back to PIO. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik commit 0146f978b9bffa62f480bf14deb033f143b40282 Author: Tejun Heo Date: Tue Nov 27 19:28:56 2007 +0900 libata: clean up EH speed down implementation Clean up EH speed down implementation. * is_io boolean variable is replaced eflags. is_io is ATA_EFLAG_IS_IO. * Error categories now have names. * Better comments. * Reorder 5min and 10min rules in ata_eh_speed_down_verdict() * Use local variable @link to cache @dev->link in ata_eh_speed_down() These changes are to improve readability and ease further changes. This patch doesn't introduce any behavior change. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik commit cb5fe1b850b6330f4f014e03af7905ef202df49a Author: Tejun Heo Date: Tue Nov 27 19:28:55 2007 +0900 libata: move ata_set_mode() to libata-eh.c Move ata_set_mode() to libata-eh.c. ata_set_mode() is surely an EH action and will be more tightly coupled with the rest of error handling. Move it to libata-eh.c. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik commit b7e395734a4fe91491edb19d35abe1443253cdda Author: Tejun Heo Date: Tue Nov 27 19:28:54 2007 +0900 libata: factor out ata_eh_schedule_probe() Factor out ata_eh_schedule_probe() from ata_eh_handle_dev_fail() and ata_eh_recover(). This is to improve maintainability and make future changes easier. In the previous revision, ata_dev_enabled() test was accidentally dropped while factoring out. This problem was spotted by Bartlomiej. Signed-off-by: Tejun Heo Cc: Bartlomiej Zolnierkiewicz Signed-off-by: Jeff Garzik commit 4cc8645267b99842ed474db87e3671244823d620 Author: Tejun Heo Date: Tue Nov 27 19:28:53 2007 +0900 libata: implement protocol tests Implement protocol tests - ata_is_atapi(), ata_is_nodata(), ata_is_pio(), ata_is_dma(), ata_is_ncq() and ata_is_data() and use them to replace is_atapi_taskfile() and hard coded protocol tests. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik commit 8ad1e8b0f06cdc6710c26d83af8ddf95d4dbe648 Author: Tejun Heo Date: Tue Nov 27 19:28:52 2007 +0900 libata: rearrange ATA_DFLAG_* Area for DFLAGs which are cleared on INIT is full. Extend it by 8 bits. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik commit b6b41dbdcf53d31e2f4ec50905d001ab0e0d13c7 Author: Jeff Garzik Date: Fri Nov 23 21:12:14 2007 -0500 libata: checkpatch fixes Signed-off-by: Jeff Garzik commit d774bf1b8dcb7480b2ecbd55686a8e9c363ddcd4 Author: Tejun Heo Date: Mon Nov 19 16:03:44 2007 +0900 ahci: update PCS programming For intel ones, ahci unconditionally OR'd 0xf to PCS. This isn't correct for the following cases. * ich6/7m's which only implement P0 and P2 (0xf works fine tho) * ich8/9's which have six ports and needs 0x3f to enable all ports This patch updates PCS programming such that... * port_map determined by ahci_save_initial_config() is OR'd instead of 0xf * PCS is updated only if necessary (there are turned off enable bits) port_map is determined from PORTS_IMPL PCI register which is implemented as write or write-once register. If the register isn't programmed, ahci automatically generates it from number of ports, which is good enough for PCS programming. ICH6/7M are probably the only ones where non-contiguous enable bits are necessary && PORTS_IMPL isn't programmed properly but they're proven to work reliably with 0xf anyway. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik commit 1daa006d5d5ef24563fab266ef34b4fe661ce183 Author: Alan Cox Date: Mon Nov 19 14:45:53 2007 +0000 pata_ninja32: Cardbus ATA initial support Lots of work needed to bring it up to scratch but it does work so you can now use the card. That makes it at least useful, especially as the other cardbus cards are usually INIC162x which aren't yet supported well. Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik commit 9bf8bc6dee4b1158ec8379ed5d88f6132e6782e7 Author: Alan Cox Date: Mon Nov 19 14:34:56 2007 +0000 libata-sff: tf_load Jeff said he preferred that the SFF tf_load followed the spec and we documented that anyone who needed different overrode it, rather than it using the ->check_status methods. No driver relies on the current behaviour. Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik commit 9d83f4361ad982ee98446fcd23b61f1627e46ac7 Author: Alan Cox Date: Mon Nov 19 14:33:11 2007 +0000 libata: IORDY handling I believe this version meets all Sergei's objections Correct the logic for when we issue a set features for transfer mode - If the device has IORDY and the controller has IORDY - set the mode - If the device has IORDY and the controller does not - turn IORDY off - If neither has IORDY do nothing Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik commit 9cffba823d8ff0d0bf9899309fd6ddb07eb3a55c Author: Shaohua Li Date: Fri Nov 2 09:32:38 2007 +0800 libata-acpi: add ACPI _PSx method ACPI spec (ver 3.0a, p289) requires IDE power on/off executes ACPI _PSx methods. As recently most PATA drivers use libata, this patch adds _PSx method support in libata. ACPI spec doesn't mention if SATA requires the same _PSx method. Signed-off-by: Shaohua Li Acked-by: Len Brown Signed-off-by: Jeff Garzik commit 8c9fe95a0b9bc9c188b8b6908659546f276314d8 Author: Alan Cox Date: Sun Nov 4 22:05:49 2007 -0500 libata: Disable ATA8-ACS proposed Trusted Computing features by default Historically word 48 in the identify data was used to mean 32bit I/O was supported for VLB IDE etc. ATA8 reassigns this word to the Trusted Computing Group, where it is used for TCG features. This means that an ATA8 TCG drive is going to trigger 32bit I/O on some systems which will be funny. Anyway we need to sort this out ready for ATA8 so: - Reorder the ata.h header a bit so the ata_version function occurs early in it - Make dword_io check the ATA version - Add an ATA8 version checking TCG presence test While we are at it the current drafts have a flaw where it may not be possible to disable TCG features at boot (and opt out of the trusted model) as TCG intends because it relies on presence of a different optional feature (DCS). Handle this in software by refusing the TCG commands if libata.allow_tpm is not set. (We must make it possible as some environments such as proprietary VDR devices will doubtless want to use it to lock up content) Finally as with CPRM print a warning so that the user knows they may not be able to full access and use the device. Signed-off-by: Alan Cox drivers/ata/Kconfig | 9 + drivers/ata/Makefile | 1 + drivers/ata/ahci.c | 45 +-- drivers/ata/ata_generic.c | 44 ++- drivers/ata/ata_piix.c | 61 ++-- drivers/ata/libata-acpi.c | 117 +++++-- drivers/ata/libata-core.c | 819 +++++++++++++++++++-------------------- drivers/ata/libata-eh.c | 300 +++++++++++---- drivers/ata/libata-scsi.c | 38 ++- drivers/ata/libata-sff.c | 20 +- drivers/ata/libata.h | 6 +- drivers/ata/pata_acpi.c | 67 +--- drivers/ata/pata_ali.c | 2 +- drivers/ata/pata_amd.c | 128 +++++-- drivers/ata/pata_bf54x.c | 41 ++- drivers/ata/pata_cs5520.c | 2 +- drivers/ata/pata_hpt37x.c | 7 +- drivers/ata/pata_icside.c | 3 +- drivers/ata/pata_it821x.c | 35 ++- drivers/ata/pata_ixp4xx_cf.c | 26 +- drivers/ata/pata_legacy.c | 784 +++++++++++++++++++++++++++++-------- drivers/ata/pata_ninja32.c | 214 ++++++++++ drivers/ata/pata_pcmcia.c | 101 +++++- drivers/ata/pata_pdc2027x.c | 2 +- drivers/ata/pata_pdc202xx_old.c | 5 +- drivers/ata/pata_qdi.c | 30 +- drivers/ata/pata_scc.c | 30 +- drivers/ata/pata_via.c | 3 +- drivers/ata/pata_winbond.c | 28 +- drivers/ata/pdc_adma.c | 5 +- drivers/ata/sata_fsl.c | 6 +- drivers/ata/sata_inic162x.c | 2 +- drivers/ata/sata_mv.c | 3 +- drivers/ata/sata_nv.c | 25 +- drivers/ata/sata_promise.c | 98 ++--- drivers/ata/sata_promise.h | 2 +- drivers/ata/sata_qstor.c | 15 +- drivers/ata/sata_sil.c | 10 +- drivers/ata/sata_sil24.c | 30 +-- drivers/ata/sata_sx4.c | 111 ++++-- drivers/scsi/ipr.c | 9 +- drivers/scsi/libsas/sas_ata.c | 14 +- include/linux/ata.h | 110 +++++- include/linux/cdrom.h | 3 + include/linux/libata.h | 181 ++++++---- 45 files changed, 2378 insertions(+), 1214 deletions(-) diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index ba63619..2478cca 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -459,6 +459,15 @@ config PATA_NETCELL If unsure, say N. +config PATA_NINJA32 + tristate "Ninja32/Delkin Cardbus ATA support (Experimental)" + depends on PCI && EXPERIMENTAL + help + This option enables support for the Ninja32, Delkin and + possibly other brands of Cardbus ATA adapter + + If unsure, say N. + config PATA_NS87410 tristate "Nat Semi NS87410 PATA support (Experimental)" depends on PCI && EXPERIMENTAL diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index b13feb2..82550c1 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile @@ -41,6 +41,7 @@ obj-$(CONFIG_PATA_IT821X) += pata_it821x.o obj-$(CONFIG_PATA_IT8213) += pata_it8213.o obj-$(CONFIG_PATA_JMICRON) += pata_jmicron.o obj-$(CONFIG_PATA_NETCELL) += pata_netcell.o +obj-$(CONFIG_PATA_NINJA32) += pata_ninja32.o obj-$(CONFIG_PATA_NS87410) += pata_ns87410.o obj-$(CONFIG_PATA_NS87415) += pata_ns87415.o obj-$(CONFIG_PATA_OPTI) += pata_opti.o diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 54f38c2..49761bc 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -198,18 +198,18 @@ enum { }; struct ahci_cmd_hdr { - u32 opts; - u32 status; - u32 tbl_addr; - u32 tbl_addr_hi; - u32 reserved[4]; + __le32 opts; + __le32 status; + __le32 tbl_addr; + __le32 tbl_addr_hi; + __le32 reserved[4]; }; struct ahci_sg { - u32 addr; - u32 addr_hi; - u32 reserved; - u32 flags_size; + __le32 addr; + __le32 addr_hi; + __le32 reserved; + __le32 flags_size; }; struct ahci_host_priv { @@ -1036,6 +1036,7 @@ static int ahci_deinit_port(struct ata_port *ap, const char **emsg) static int ahci_reset_controller(struct ata_host *host) { struct pci_dev *pdev = to_pci_dev(host->dev); + struct ahci_host_priv *hpriv = host->private_data; void __iomem *mmio = host->iomap[AHCI_PCI_BAR]; u32 tmp; @@ -1078,8 +1079,10 @@ static int ahci_reset_controller(struct ata_host *host) /* configure PCS */ pci_read_config_word(pdev, 0x92, &tmp16); - tmp16 |= 0xf; - pci_write_config_word(pdev, 0x92, tmp16); + if ((tmp16 & hpriv->port_map) != hpriv->port_map) { + tmp16 |= hpriv->port_map; + pci_write_config_word(pdev, 0x92, tmp16); + } } return 0; @@ -1480,35 +1483,31 @@ static void ahci_tf_read(struct ata_port *ap, struct ata_taskfile *tf) static unsigned int ahci_fill_sg(struct ata_queued_cmd *qc, void *cmd_tbl) { struct scatterlist *sg; - struct ahci_sg *ahci_sg; - unsigned int n_sg = 0; + struct ahci_sg *ahci_sg = cmd_tbl + AHCI_CMD_TBL_HDR_SZ; + unsigned int si; VPRINTK("ENTER\n"); /* * Next, the S/G list. */ - ahci_sg = cmd_tbl + AHCI_CMD_TBL_HDR_SZ; - ata_for_each_sg(sg, qc) { + for_each_sg(qc->sg, sg, qc->n_elem, si) { dma_addr_t addr = sg_dma_address(sg); u32 sg_len = sg_dma_len(sg); - ahci_sg->addr = cpu_to_le32(addr & 0xffffffff); - ahci_sg->addr_hi = cpu_to_le32((addr >> 16) >> 16); - ahci_sg->flags_size = cpu_to_le32(sg_len - 1); - - ahci_sg++; - n_sg++; + ahci_sg[si].addr = cpu_to_le32(addr & 0xffffffff); + ahci_sg[si].addr_hi = cpu_to_le32((addr >> 16) >> 16); + ahci_sg[si].flags_size = cpu_to_le32(sg_len - 1); } - return n_sg; + return si; } static void ahci_qc_prep(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; struct ahci_port_priv *pp = ap->private_data; - int is_atapi = is_atapi_taskfile(&qc->tf); + int is_atapi = ata_is_atapi(qc->tf.protocol); void *cmd_tbl; u32 opts; const u32 cmd_fis_len = 5; /* five dwords */ diff --git a/drivers/ata/ata_generic.c b/drivers/ata/ata_generic.c index 9032998..d11a4f1 100644 --- a/drivers/ata/ata_generic.c +++ b/drivers/ata/ata_generic.c @@ -54,21 +54,37 @@ static int generic_set_mode(struct ata_link *link, struct ata_device **unused) dma_enabled = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS); ata_link_for_each_dev(dev, link) { - if (ata_dev_enabled(dev)) { - /* We don't really care */ - dev->pio_mode = XFER_PIO_0; - dev->dma_mode = XFER_MW_DMA_0; - /* We do need the right mode information for DMA or PIO - and this comes from the current configuration flags */ - if (dma_enabled & (1 << (5 + dev->devno))) { - ata_id_to_dma_mode(dev, XFER_MW_DMA_0); - dev->flags &= ~ATA_DFLAG_PIO; - } else { - ata_dev_printk(dev, KERN_INFO, "configured for PIO\n"); - dev->xfer_mode = XFER_PIO_0; - dev->xfer_shift = ATA_SHIFT_PIO; - dev->flags |= ATA_DFLAG_PIO; + if (!ata_dev_enabled(dev)) + continue; + + /* We don't really care */ + dev->pio_mode = XFER_PIO_0; + dev->dma_mode = XFER_MW_DMA_0; + /* We do need the right mode information for DMA or PIO + and this comes from the current configuration flags */ + if (dma_enabled & (1 << (5 + dev->devno))) { + unsigned int xfer_mask = ata_id_xfermask(dev->id); + const char *name; + + if (xfer_mask & (ATA_MASK_MWDMA | ATA_MASK_UDMA)) + name = ata_mode_string(xfer_mask); + else { + /* SWDMA perhaps? */ + name = "DMA"; + xfer_mask |= ata_xfer_mode2mask(XFER_MW_DMA_0); } + + ata_dev_printk(dev, KERN_INFO, "configured for %s\n", + name); + + dev->xfer_mode = ata_xfer_mask2mode(xfer_mask); + dev->xfer_shift = ata_xfer_mode2shift(dev->xfer_mode); + dev->flags &= ~ATA_DFLAG_PIO; + } else { + ata_dev_printk(dev, KERN_INFO, "configured for PIO\n"); + dev->xfer_mode = XFER_PIO_0; + dev->xfer_shift = ATA_SHIFT_PIO; + dev->flags |= ATA_DFLAG_PIO; } } return 0; diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index b406b39..ba10520 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -102,38 +102,15 @@ enum { ICH5_PCS = 0x92, /* port control and status */ PIIX_SCC = 0x0A, /* sub-class code register */ - PIIX_FLAG_SCR = (1 << 26), /* SCR available */ PIIX_FLAG_AHCI = (1 << 27), /* AHCI possible */ PIIX_FLAG_CHECKINTR = (1 << 28), /* make sure PCI INTx enabled */ PIIX_PATA_FLAGS = ATA_FLAG_SLAVE_POSS, PIIX_SATA_FLAGS = ATA_FLAG_SATA | PIIX_FLAG_CHECKINTR, - /* combined mode. if set, PATA is channel 0. - * if clear, PATA is channel 1. - */ - PIIX_PORT_ENABLED = (1 << 0), - PIIX_PORT_PRESENT = (1 << 4), - PIIX_80C_PRI = (1 << 5) | (1 << 4), PIIX_80C_SEC = (1 << 7) | (1 << 6), - /* controller IDs */ - piix_pata_mwdma = 0, /* PIIX3 MWDMA only */ - piix_pata_33, /* PIIX4 at 33Mhz */ - ich_pata_33, /* ICH up to UDMA 33 only */ - ich_pata_66, /* ICH up to 66 Mhz */ - ich_pata_100, /* ICH up to UDMA 100 */ - ich5_sata, - ich6_sata, - ich6_sata_ahci, - ich6m_sata_ahci, - ich8_sata_ahci, - ich8_2port_sata, - ich8m_apple_sata_ahci, /* locks up on second port enable */ - tolapai_sata_ahci, - piix_pata_vmw, /* PIIX4 for VMware, spurious DMA_ERR */ - /* constants for mapping table */ P0 = 0, /* port 0 */ P1 = 1, /* port 1 */ @@ -149,6 +126,24 @@ enum { PIIX_HOST_BROKEN_SUSPEND = (1 << 24), }; +enum piix_controller_ids { + /* controller IDs */ + piix_pata_mwdma, /* PIIX3 MWDMA only */ + piix_pata_33, /* PIIX4 at 33Mhz */ + ich_pata_33, /* ICH up to UDMA 33 only */ + ich_pata_66, /* ICH up to 66 Mhz */ + ich_pata_100, /* ICH up to UDMA 100 */ + ich5_sata, + ich6_sata, + ich6_sata_ahci, + ich6m_sata_ahci, + ich8_sata_ahci, + ich8_2port_sata, + ich8m_apple_sata_ahci, /* locks up on second port enable */ + tolapai_sata_ahci, + piix_pata_vmw, /* PIIX4 for VMware, spurious DMA_ERR */ +}; + struct piix_map_db { const u32 mask; const u16 port_enable; @@ -586,7 +581,7 @@ static struct ata_port_info piix_port_info[] = { [ich6_sata] = { .sht = &piix_sht, - .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SCR, + .flags = PIIX_SATA_FLAGS, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = ATA_UDMA6, @@ -596,8 +591,7 @@ static struct ata_port_info piix_port_info[] = { [ich6_sata_ahci] = { .sht = &piix_sht, - .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SCR | - PIIX_FLAG_AHCI, + .flags = PIIX_SATA_FLAGS | PIIX_FLAG_AHCI, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = ATA_UDMA6, @@ -607,8 +601,7 @@ static struct ata_port_info piix_port_info[] = { [ich6m_sata_ahci] = { .sht = &piix_sht, - .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SCR | - PIIX_FLAG_AHCI, + .flags = PIIX_SATA_FLAGS | PIIX_FLAG_AHCI, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = ATA_UDMA6, @@ -618,8 +611,7 @@ static struct ata_port_info piix_port_info[] = { [ich8_sata_ahci] = { .sht = &piix_sht, - .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SCR | - PIIX_FLAG_AHCI, + .flags = PIIX_SATA_FLAGS | PIIX_FLAG_AHCI, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = ATA_UDMA6, @@ -629,8 +621,7 @@ static struct ata_port_info piix_port_info[] = { [ich8_2port_sata] = { .sht = &piix_sht, - .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SCR | - PIIX_FLAG_AHCI, + .flags = PIIX_SATA_FLAGS | PIIX_FLAG_AHCI, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = ATA_UDMA6, @@ -640,8 +631,7 @@ static struct ata_port_info piix_port_info[] = { [tolapai_sata_ahci] = { .sht = &piix_sht, - .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SCR | - PIIX_FLAG_AHCI, + .flags = PIIX_SATA_FLAGS | PIIX_FLAG_AHCI, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = ATA_UDMA6, @@ -651,8 +641,7 @@ static struct ata_port_info piix_port_info[] = { [ich8m_apple_sata_ahci] = { .sht = &piix_sht, - .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SCR | - PIIX_FLAG_AHCI, + .flags = PIIX_SATA_FLAGS | PIIX_FLAG_AHCI, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = ATA_UDMA6, diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 7bf4bef..9e8ec19 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -442,40 +442,77 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf) } /** + * ata_acpi_gtm_xfermode - determine xfermode from GTM parameter + * @dev: target device + * @gtm: GTM parameter to use + * + * Determine xfermask for @dev from @gtm. + * + * LOCKING: + * None. + * + * RETURNS: + * Determined xfermask. + */ +unsigned long ata_acpi_gtm_xfermask(struct ata_device *dev, + const struct ata_acpi_gtm *gtm) +{ + unsigned long xfer_mask = 0; + unsigned int type; + int unit; + u8 mode; + + /* we always use the 0 slot for crap hardware */ + unit = dev->devno; + if (!(gtm->flags & 0x10)) + unit = 0; + + /* PIO */ + mode = ata_timing_cycle2mode(ATA_SHIFT_PIO, gtm->drive[unit].pio); + xfer_mask |= ata_xfer_mode2mask(mode); + + /* See if we have MWDMA or UDMA data. We don't bother with + * MWDMA if UDMA is available as this means the BIOS set UDMA + * and our error changedown if it works is UDMA to PIO anyway. + */ + if (!(gtm->flags & (1 << (2 * unit)))) + type = ATA_SHIFT_MWDMA; + else + type = ATA_SHIFT_UDMA; + + mode = ata_timing_cycle2mode(type, gtm->drive[unit].dma); + xfer_mask |= ata_xfer_mode2mask(mode); + + return xfer_mask; +} +EXPORT_SYMBOL_GPL(ata_acpi_gtm_xfermask); + +/** * ata_acpi_cbl_80wire - Check for 80 wire cable * @ap: Port to check + * @gtm: GTM data to use * - * Return 1 if the ACPI mode data for this port indicates the BIOS selected - * an 80wire mode. + * Return 1 if the @gtm indicates the BIOS selected an 80wire mode. */ - -int ata_acpi_cbl_80wire(struct ata_port *ap) +int ata_acpi_cbl_80wire(struct ata_port *ap, const struct ata_acpi_gtm *gtm) { - const struct ata_acpi_gtm *gtm = ata_acpi_init_gtm(ap); - int valid = 0; + struct ata_device *dev; - if (!gtm) - return 0; + ata_link_for_each_dev(dev, &ap->link) { + unsigned long xfer_mask, udma_mask; + + if (!ata_dev_enabled(dev)) + continue; + + xfer_mask = ata_acpi_gtm_xfermask(dev, gtm); + ata_unpack_xfermask(xfer_mask, NULL, NULL, &udma_mask); + + if (udma_mask & ~ATA_UDMA_MASK_40C) + return 1; + } - /* Split timing, DMA enabled */ - if ((gtm->flags & 0x11) == 0x11 && gtm->drive[0].dma < 55) - valid |= 1; - if ((gtm->flags & 0x14) == 0x14 && gtm->drive[1].dma < 55) - valid |= 2; - /* Shared timing, DMA enabled */ - if ((gtm->flags & 0x11) == 0x01 && gtm->drive[0].dma < 55) - valid |= 1; - if ((gtm->flags & 0x14) == 0x04 && gtm->drive[0].dma < 55) - valid |= 2; - - /* Drive check */ - if ((valid & 1) && ata_dev_enabled(&ap->link.device[0])) - return 1; - if ((valid & 2) && ata_dev_enabled(&ap->link.device[1])) - return 1; return 0; } - EXPORT_SYMBOL_GPL(ata_acpi_cbl_80wire); static void ata_acpi_gtf_to_tf(struct ata_device *dev, @@ -776,6 +813,36 @@ void ata_acpi_on_resume(struct ata_port *ap) } /** + * ata_acpi_set_state - set the port power state + * @ap: target ATA port + * @state: state, on/off + * + * This function executes the _PS0/_PS3 ACPI method to set the power state. + * ACPI spec requires _PS0 when IDE power on and _PS3 when power off + */ +void ata_acpi_set_state(struct ata_port *ap, pm_message_t state) +{ + struct ata_device *dev; + + if (!ap->acpi_handle || (ap->flags & ATA_FLAG_ACPI_SATA)) + return; + + /* channel first and then drives for power on and vica versa + for power off */ + if (state.event == PM_EVENT_ON) + acpi_bus_set_power(ap->acpi_handle, ACPI_STATE_D0); + + ata_link_for_each_dev(dev, &ap->link) { + if (dev->acpi_handle && ata_dev_enabled(dev)) + acpi_bus_set_power(dev->acpi_handle, + state.event == PM_EVENT_ON ? + ACPI_STATE_D0 : ACPI_STATE_D3); + } + if (state.event != PM_EVENT_ON) + acpi_bus_set_power(ap->acpi_handle, ACPI_STATE_D3); +} + +/** * ata_acpi_on_devcfg - ATA ACPI hook called on device donfiguration * @dev: target ATA device * diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 6380726..06ff781 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -119,6 +119,10 @@ int libata_noacpi = 0; module_param_named(noacpi, libata_noacpi, int, 0444); MODULE_PARM_DESC(noacpi, "Disables the use of ACPI in probe/suspend/resume when set"); +int libata_allow_tpm = 0; +module_param_named(allow_tpm, libata_allow_tpm, int, 0444); +MODULE_PARM_DESC(allow_tpm, "Permit the use of TPM commands"); + MODULE_AUTHOR("Jeff Garzik"); MODULE_DESCRIPTION("Library module for ATA devices"); MODULE_LICENSE("GPL"); @@ -450,9 +454,9 @@ int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev, * RETURNS: * Packed xfer_mask. */ -static unsigned int ata_pack_xfermask(unsigned int pio_mask, - unsigned int mwdma_mask, - unsigned int udma_mask) +unsigned long ata_pack_xfermask(unsigned long pio_mask, + unsigned long mwdma_mask, + unsigned long udma_mask) { return ((pio_mask << ATA_SHIFT_PIO) & ATA_MASK_PIO) | ((mwdma_mask << ATA_SHIFT_MWDMA) & ATA_MASK_MWDMA) | @@ -469,10 +473,8 @@ static unsigned int ata_pack_xfermask(unsigned int pio_mask, * Unpack @xfer_mask into @pio_mask, @mwdma_mask and @udma_mask. * Any NULL distination masks will be ignored. */ -static void ata_unpack_xfermask(unsigned int xfer_mask, - unsigned int *pio_mask, - unsigned int *mwdma_mask, - unsigned int *udma_mask) +void ata_unpack_xfermask(unsigned long xfer_mask, unsigned long *pio_mask, + unsigned long *mwdma_mask, unsigned long *udma_mask) { if (pio_mask) *pio_mask = (xfer_mask & ATA_MASK_PIO) >> ATA_SHIFT_PIO; @@ -486,9 +488,9 @@ static const struct ata_xfer_ent { int shift, bits; u8 base; } ata_xfer_tbl[] = { - { ATA_SHIFT_PIO, ATA_BITS_PIO, XFER_PIO_0 }, - { ATA_SHIFT_MWDMA, ATA_BITS_MWDMA, XFER_MW_DMA_0 }, - { ATA_SHIFT_UDMA, ATA_BITS_UDMA, XFER_UDMA_0 }, + { ATA_SHIFT_PIO, ATA_NR_PIO_MODES, XFER_PIO_0 }, + { ATA_SHIFT_MWDMA, ATA_NR_MWDMA_MODES, XFER_MW_DMA_0 }, + { ATA_SHIFT_UDMA, ATA_NR_UDMA_MODES, XFER_UDMA_0 }, { -1, }, }; @@ -503,9 +505,9 @@ static const struct ata_xfer_ent { * None. * * RETURNS: - * Matching XFER_* value, 0 if no match found. + * Matching XFER_* value, 0xff if no match found. */ -static u8 ata_xfer_mask2mode(unsigned int xfer_mask) +u8 ata_xfer_mask2mode(unsigned long xfer_mask) { int highbit = fls(xfer_mask) - 1; const struct ata_xfer_ent *ent; @@ -513,7 +515,7 @@ static u8 ata_xfer_mask2mode(unsigned int xfer_mask) for (ent = ata_xfer_tbl; ent->shift >= 0; ent++) if (highbit >= ent->shift && highbit < ent->shift + ent->bits) return ent->base + highbit - ent->shift; - return 0; + return 0xff; } /** @@ -528,13 +530,14 @@ static u8 ata_xfer_mask2mode(unsigned int xfer_mask) * RETURNS: * Matching xfer_mask, 0 if no match found. */ -static unsigned int ata_xfer_mode2mask(u8 xfer_mode) +unsigned long ata_xfer_mode2mask(u8 xfer_mode) { const struct ata_xfer_ent *ent; for (ent = ata_xfer_tbl; ent->shift >= 0; ent++) if (xfer_mode >= ent->base && xfer_mode < ent->base + ent->bits) - return 1 << (ent->shift + xfer_mode - ent->base); + return ((2 << (ent->shift + xfer_mode - ent->base)) - 1) + & ~((1 << ent->shift) - 1); return 0; } @@ -550,7 +553,7 @@ static unsigned int ata_xfer_mode2mask(u8 xfer_mode) * RETURNS: * Matching xfer_shift, -1 if no match found. */ -static int ata_xfer_mode2shift(unsigned int xfer_mode) +int ata_xfer_mode2shift(unsigned long xfer_mode) { const struct ata_xfer_ent *ent; @@ -574,7 +577,7 @@ static int ata_xfer_mode2shift(unsigned int xfer_mode) * Constant C string representing highest speed listed in * @mode_mask, or the constant C string "". */ -static const char *ata_mode_string(unsigned int xfer_mask) +const char *ata_mode_string(unsigned long xfer_mask) { static const char * const xfer_mode_str[] = { "PIO0", @@ -947,8 +950,8 @@ unsigned int ata_dev_try_classify(struct ata_device *dev, int present, if (r_err) *r_err = err; - /* see if device passed diags: if master then continue and warn later */ - if (err == 0 && dev->devno == 0) + /* see if device passed diags: continue and warn later */ + if (err == 0) /* diagnostic fail : do nothing _YET_ */ dev->horkage |= ATA_HORKAGE_DIAGNOSTIC; else if (err == 1) @@ -1286,48 +1289,6 @@ static int ata_hpa_resize(struct ata_device *dev) } /** - * ata_id_to_dma_mode - Identify DMA mode from id block - * @dev: device to identify - * @unknown: mode to assume if we cannot tell - * - * Set up the timing values for the device based upon the identify - * reported values for the DMA mode. This function is used by drivers - * which rely upon firmware configured modes, but wish to report the - * mode correctly when possible. - * - * In addition we emit similarly formatted messages to the default - * ata_dev_set_mode handler, in order to provide consistency of - * presentation. - */ - -void ata_id_to_dma_mode(struct ata_device *dev, u8 unknown) -{ - unsigned int mask; - u8 mode; - - /* Pack the DMA modes */ - mask = ((dev->id[63] >> 8) << ATA_SHIFT_MWDMA) & ATA_MASK_MWDMA; - if (dev->id[53] & 0x04) - mask |= ((dev->id[88] >> 8) << ATA_SHIFT_UDMA) & ATA_MASK_UDMA; - - /* Select the mode in use */ - mode = ata_xfer_mask2mode(mask); - - if (mode != 0) { - ata_dev_printk(dev, KERN_INFO, "configured for %s\n", - ata_mode_string(mask)); - } else { - /* SWDMA perhaps ? */ - mode = unknown; - ata_dev_printk(dev, KERN_INFO, "configured for DMA\n"); - } - - /* Configure the device reporting */ - dev->xfer_mode = mode; - dev->xfer_shift = ata_xfer_mode2shift(mode); -} - -/** * ata_noop_dev_select - Select device 0/1 on ATA bus * @ap: ATA channel to manipulate * @device: ATA device (numbered from zero) to select @@ -1464,9 +1425,9 @@ static inline void ata_dump_id(const u16 *id) * RETURNS: * Computed xfermask */ -static unsigned int ata_id_xfermask(const u16 *id) +unsigned long ata_id_xfermask(const u16 *id) { - unsigned int pio_mask, mwdma_mask, udma_mask; + unsigned long pio_mask, mwdma_mask, udma_mask; /* Usual case. Word 53 indicates word 64 is valid */ if (id[ATA_ID_FIELD_VALID] & (1 << 1)) { @@ -1519,7 +1480,7 @@ static unsigned int ata_id_xfermask(const u16 *id) } /** - * ata_port_queue_task - Queue port_task + * ata_pio_queue_task - Queue port_task * @ap: The ata_port to queue port_task for * @fn: workqueue function to be scheduled * @data: data for @fn to use @@ -1531,16 +1492,15 @@ static unsigned int ata_id_xfermask(const u16 *id) * one task is active at any given time. * * libata core layer takes care of synchronization between - * port_task and EH. ata_port_queue_task() may be ignored for EH + * port_task and EH. ata_pio_queue_task() may be ignored for EH * synchronization. * * LOCKING: * Inherited from caller. */ -void ata_port_queue_task(struct ata_port *ap, work_func_t fn, void *data, - unsigned long delay) +static void ata_pio_queue_task(struct ata_port *ap, void *data, + unsigned long delay) { - PREPARE_DELAYED_WORK(&ap->port_task, fn); ap->port_task_data = data; /* may fail if ata_port_flush_task() in progress */ @@ -2090,7 +2050,7 @@ int ata_dev_configure(struct ata_device *dev) struct ata_eh_context *ehc = &dev->link->eh_context; int print_info = ehc->i.flags & ATA_EHI_PRINTINFO; const u16 *id = dev->id; - unsigned int xfer_mask; + unsigned long xfer_mask; char revbuf[7]; /* XYZ-99\0 */ char fwrevbuf[ATA_ID_FW_REV_LEN+1]; char modelbuf[ATA_ID_PROD_LEN+1]; @@ -2161,8 +2121,14 @@ int ata_dev_configure(struct ata_device *dev) "supports DRM functions and may " "not be fully accessable.\n"); snprintf(revbuf, 7, "CFA"); - } else + } else { snprintf(revbuf, 7, "ATA-%d", ata_id_major_version(id)); + /* Warn the user if the device has TPM extensions */ + if (ata_id_has_tpm(id)) + ata_dev_printk(dev, KERN_WARNING, + "supports DRM functions and may " + "not be fully accessable.\n"); + } dev->n_sectors = ata_id_n_sectors(id); @@ -2295,19 +2261,8 @@ int ata_dev_configure(struct ata_device *dev) dev->flags |= ATA_DFLAG_DIPM; } - if (dev->horkage & ATA_HORKAGE_DIAGNOSTIC) { - /* Let the user know. We don't want to disallow opens for - rescue purposes, or in case the vendor is just a blithering - idiot */ - if (print_info) { - ata_dev_printk(dev, KERN_WARNING, -"Drive reports diagnostics failure. This may indicate a drive\n"); - ata_dev_printk(dev, KERN_WARNING, -"fault or invalid emulation. Contact drive vendor for information.\n"); - } - } - - /* limit bridge transfers to udma5, 200 sectors */ + /* Limit PATA drive on SATA cable bridge transfers to udma5, + 200 sectors */ if (ata_dev_knobble(dev)) { if (ata_msg_drv(ap) && print_info) ata_dev_printk(dev, KERN_INFO, @@ -2336,6 +2291,21 @@ int ata_dev_configure(struct ata_device *dev) if (ap->ops->dev_config) ap->ops->dev_config(dev); + if (dev->horkage & ATA_HORKAGE_DIAGNOSTIC) { + /* Let the user know. We don't want to disallow opens for + rescue purposes, or in case the vendor is just a blithering + idiot. Do this after the dev_config call as some controllers + with buggy firmware may want to avoid reporting false device + bugs */ + + if (print_info) { + ata_dev_printk(dev, KERN_WARNING, +"Drive reports diagnostics failure. This may indicate a drive\n"); + ata_dev_printk(dev, KERN_WARNING, +"fault or invalid emulation. Contact drive vendor for information.\n"); + } + } + if (ata_msg_probe(ap)) ata_dev_printk(dev, KERN_DEBUG, "%s: EXIT, drv_stat = 0x%x\n", __FUNCTION__, ata_chk_status(ap)); @@ -2387,6 +2357,18 @@ int ata_cable_unknown(struct ata_port *ap) } /** + * ata_cable_ignore - return ignored PATA cable. + * @ap: port + * + * Helper method for drivers which don't use cable type to limit + * transfer mode. + */ +int ata_cable_ignore(struct ata_port *ap) +{ + return ATA_CBL_PATA_IGN; +} + +/** * ata_cable_sata - return SATA cable type * @ap: port * @@ -2781,38 +2763,33 @@ int sata_set_spd(struct ata_link *link) */ static const struct ata_timing ata_timing[] = { +/* { XFER_PIO_SLOW, 120, 290, 240, 960, 290, 240, 960, 0 }, */ + { XFER_PIO_0, 70, 290, 240, 600, 165, 150, 600, 0 }, + { XFER_PIO_1, 50, 290, 93, 383, 125, 100, 383, 0 }, + { XFER_PIO_2, 30, 290, 40, 330, 100, 90, 240, 0 }, + { XFER_PIO_3, 30, 80, 70, 180, 80, 70, 180, 0 }, + { XFER_PIO_4, 25, 70, 25, 120, 70, 25, 120, 0 }, + { XFER_PIO_5, 15, 65, 25, 100, 65, 25, 100, 0 }, + { XFER_PIO_6, 10, 55, 20, 80, 55, 20, 80, 0 }, - { XFER_UDMA_6, 0, 0, 0, 0, 0, 0, 0, 15 }, - { XFER_UDMA_5, 0, 0, 0, 0, 0, 0, 0, 20 }, - { XFER_UDMA_4, 0, 0, 0, 0, 0, 0, 0, 30 }, - { XFER_UDMA_3, 0, 0, 0, 0, 0, 0, 0, 45 }, + { XFER_SW_DMA_0, 120, 0, 0, 0, 480, 480, 960, 0 }, + { XFER_SW_DMA_1, 90, 0, 0, 0, 240, 240, 480, 0 }, + { XFER_SW_DMA_2, 60, 0, 0, 0, 120, 120, 240, 0 }, - { XFER_MW_DMA_4, 25, 0, 0, 0, 55, 20, 80, 0 }, + { XFER_MW_DMA_0, 60, 0, 0, 0, 215, 215, 480, 0 }, + { XFER_MW_DMA_1, 45, 0, 0, 0, 80, 50, 150, 0 }, + { XFER_MW_DMA_2, 25, 0, 0, 0, 70, 25, 120, 0 }, { XFER_MW_DMA_3, 25, 0, 0, 0, 65, 25, 100, 0 }, - { XFER_UDMA_2, 0, 0, 0, 0, 0, 0, 0, 60 }, - { XFER_UDMA_1, 0, 0, 0, 0, 0, 0, 0, 80 }, - { XFER_UDMA_0, 0, 0, 0, 0, 0, 0, 0, 120 }, + { XFER_MW_DMA_4, 25, 0, 0, 0, 55, 20, 80, 0 }, /* { XFER_UDMA_SLOW, 0, 0, 0, 0, 0, 0, 0, 150 }, */ - - { XFER_MW_DMA_2, 25, 0, 0, 0, 70, 25, 120, 0 }, - { XFER_MW_DMA_1, 45, 0, 0, 0, 80, 50, 150, 0 }, - { XFER_MW_DMA_0, 60, 0, 0, 0, 215, 215, 480, 0 }, - - { XFER_SW_DMA_2, 60, 0, 0, 0, 120, 120, 240, 0 }, - { XFER_SW_DMA_1, 90, 0, 0, 0, 240, 240, 480, 0 }, - { XFER_SW_DMA_0, 120, 0, 0, 0, 480, 480, 960, 0 }, - - { XFER_PIO_6, 10, 55, 20, 80, 55, 20, 80, 0 }, - { XFER_PIO_5, 15, 65, 25, 100, 65, 25, 100, 0 }, - { XFER_PIO_4, 25, 70, 25, 120, 70, 25, 120, 0 }, - { XFER_PIO_3, 30, 80, 70, 180, 80, 70, 180, 0 }, - - { XFER_PIO_2, 30, 290, 40, 330, 100, 90, 240, 0 }, - { XFER_PIO_1, 50, 290, 93, 383, 125, 100, 383, 0 }, - { XFER_PIO_0, 70, 290, 240, 600, 165, 150, 600, 0 }, - -/* { XFER_PIO_SLOW, 120, 290, 240, 960, 290, 240, 960, 0 }, */ + { XFER_UDMA_0, 0, 0, 0, 0, 0, 0, 0, 120 }, + { XFER_UDMA_1, 0, 0, 0, 0, 0, 0, 0, 80 }, + { XFER_UDMA_2, 0, 0, 0, 0, 0, 0, 0, 60 }, + { XFER_UDMA_3, 0, 0, 0, 0, 0, 0, 0, 45 }, + { XFER_UDMA_4, 0, 0, 0, 0, 0, 0, 0, 30 }, + { XFER_UDMA_5, 0, 0, 0, 0, 0, 0, 0, 20 }, + { XFER_UDMA_6, 0, 0, 0, 0, 0, 0, 0, 15 }, { 0xFF } }; @@ -2845,14 +2822,16 @@ void ata_timing_merge(const struct ata_timing *a, const struct ata_timing *b, if (what & ATA_TIMING_UDMA ) m->udma = max(a->udma, b->udma); } -static const struct ata_timing *ata_timing_find_mode(unsigned short speed) +const struct ata_timing *ata_timing_find_mode(u8 xfer_mode) { - const struct ata_timing *t; + const struct ata_timing *t = ata_timing; + + while (xfer_mode > t->mode) + t++; - for (t = ata_timing; t->mode != speed; t++) - if (t->mode == 0xFF) - return NULL; - return t; + if (xfer_mode == t->mode) + return t; + return NULL; } int ata_timing_compute(struct ata_device *adev, unsigned short speed, @@ -2927,6 +2906,57 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed, } /** + * ata_timing_cycle2mode - find xfer mode for the specified cycle duration + * @xfer_shift: ATA_SHIFT_* value for transfer type to examine. + * @cycle: cycle duration in ns + * + * Return matching xfer mode for @cycle. The returned mode is of + * the transfer type specified by @xfer_shift. If @cycle is too + * slow for @xfer_shift, 0xff is returned. If @cycle is faster + * than the fastest known mode, the fasted mode is returned. + * + * LOCKING: + * None. + * + * RETURNS: + * Matching xfer_mode, 0xff if no match found. + */ +u8 ata_timing_cycle2mode(unsigned int xfer_shift, int cycle) +{ + u8 base_mode = 0xff, last_mode = 0xff; + const struct ata_xfer_ent *ent; + const struct ata_timing *t; + + for (ent = ata_xfer_tbl; ent->shift >= 0; ent++) + if (ent->shift == xfer_shift) + base_mode = ent->base; + + for (t = ata_timing_find_mode(base_mode); + t && ata_xfer_mode2shift(t->mode) == xfer_shift; t++) { + unsigned short this_cycle; + + switch (xfer_shift) { + case ATA_SHIFT_PIO: + case ATA_SHIFT_MWDMA: + this_cycle = t->cycle; + break; + case ATA_SHIFT_UDMA: + this_cycle = t->udma; + break; + default: + return 0xff; + } + + if (cycle > this_cycle) + break; + + last_mode = t->mode; + } + + return last_mode; +} + +/** * ata_down_xfermask_limit - adjust dev xfer masks downward * @dev: Device to adjust xfer masks * @sel: ATA_DNXFER_* selector @@ -2944,8 +2974,8 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed, int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel) { char buf[32]; - unsigned int orig_mask, xfer_mask; - unsigned int pio_mask, mwdma_mask, udma_mask; + unsigned long orig_mask, xfer_mask; + unsigned long pio_mask, mwdma_mask, udma_mask; int quiet, highbit; quiet = !!(sel & ATA_DNXFER_QUIET); @@ -3039,7 +3069,7 @@ static int ata_dev_set_mode(struct ata_device *dev) /* Early MWDMA devices do DMA but don't allow DMA mode setting. Don't fail an MWDMA0 set IFF the device indicates it is in MWDMA0 */ - if (dev->xfer_shift == ATA_SHIFT_MWDMA && + if (dev->xfer_shift == ATA_SHIFT_MWDMA && dev->dma_mode == XFER_MW_DMA_0 && (dev->id[63] >> 8) & 1) err_mask &= ~AC_ERR_DEV; @@ -3089,7 +3119,7 @@ int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev) /* step 1: calculate xfer_mask */ ata_link_for_each_dev(dev, link) { - unsigned int pio_mask, dma_mask; + unsigned long pio_mask, dma_mask; unsigned int mode_mask; if (!ata_dev_enabled(dev)) @@ -3115,7 +3145,7 @@ int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev) dev->dma_mode = ata_xfer_mask2mode(dma_mask); found = 1; - if (dev->dma_mode) + if (dev->dma_mode != 0xff) used_dma = 1; } if (!found) @@ -3126,7 +3156,7 @@ int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev) if (!ata_dev_enabled(dev)) continue; - if (!dev->pio_mode) { + if (dev->pio_mode == 0xff) { ata_dev_printk(dev, KERN_WARNING, "no PIO support\n"); rc = -EINVAL; goto out; @@ -3140,7 +3170,7 @@ int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev) /* step 3: set host DMA timings */ ata_link_for_each_dev(dev, link) { - if (!ata_dev_enabled(dev) || !dev->dma_mode) + if (!ata_dev_enabled(dev) || dev->dma_mode == 0xff) continue; dev->xfer_mode = dev->dma_mode; @@ -3173,31 +3203,6 @@ int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev) } /** - * ata_set_mode - Program timings and issue SET FEATURES - XFER - * @link: link on which timings will be programmed - * @r_failed_dev: out paramter for failed device - * - * Set ATA device disk transfer mode (PIO3, UDMA6, etc.). If - * ata_set_mode() fails, pointer to the failing device is - * returned in @r_failed_dev. - * - * LOCKING: - * PCI/etc. bus probe sem. - * - * RETURNS: - * 0 on success, negative errno otherwise - */ -int ata_set_mode(struct ata_link *link, struct ata_device **r_failed_dev) -{ - struct ata_port *ap = link->ap; - - /* has private set_mode? */ - if (ap->ops->set_mode) - return ap->ops->set_mode(link, r_failed_dev); - return ata_do_set_mode(link, r_failed_dev); -} - -/** * ata_tf_to_host - issue ATA taskfile to host controller * @ap: port to which command is being issued * @tf: ATA taskfile register set @@ -4363,7 +4368,14 @@ static unsigned int ata_dev_set_xfermode(struct ata_device *dev) tf.feature = SETFEATURES_XFER; tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE | ATA_TFLAG_POLLING; tf.protocol = ATA_PROT_NODATA; - tf.nsect = dev->xfer_mode; + /* If we are using IORDY we must send the mode setting command */ + if (ata_pio_need_iordy(dev)) + tf.nsect = dev->xfer_mode; + /* If the device has IORDY and the controller does not - turn it off */ + else if (ata_id_has_iordy(dev->id)) + tf.nsect = 0x01; + else /* In the ancient relic department - skip all of this */ + return 0; err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0); @@ -4462,17 +4474,13 @@ static unsigned int ata_dev_init_params(struct ata_device *dev, void ata_sg_clean(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; - struct scatterlist *sg = qc->__sg; + struct scatterlist *sg = qc->sg; int dir = qc->dma_dir; void *pad_buf = NULL; - WARN_ON(!(qc->flags & ATA_QCFLAG_DMAMAP)); WARN_ON(sg == NULL); - if (qc->flags & ATA_QCFLAG_SINGLE) - WARN_ON(qc->n_elem > 1); - - VPRINTK("unmapping %u sg elements\n", qc->n_elem); + VPRINTK("unmapping %u sg elements\n", qc->mapped_n_elem); /* if we padded the buffer out to 32-bit bound, and data * xfer direction is from-device, we must copy from the @@ -4481,31 +4489,20 @@ void ata_sg_clean(struct ata_queued_cmd *qc) if (qc->pad_len && !(qc->tf.flags & ATA_TFLAG_WRITE)) pad_buf = ap->pad + (qc->tag * ATA_DMA_PAD_SZ); - if (qc->flags & ATA_QCFLAG_SG) { - if (qc->n_elem) - dma_unmap_sg(ap->dev, sg, qc->n_elem, dir); - /* restore last sg */ - sg_last(sg, qc->orig_n_elem)->length += qc->pad_len; - if (pad_buf) { - struct scatterlist *psg = &qc->pad_sgent; - void *addr = kmap_atomic(sg_page(psg), KM_IRQ0); - memcpy(addr + psg->offset, pad_buf, qc->pad_len); - kunmap_atomic(addr, KM_IRQ0); - } - } else { - if (qc->n_elem) - dma_unmap_single(ap->dev, - sg_dma_address(&sg[0]), sg_dma_len(&sg[0]), - dir); - /* restore sg */ - sg->length += qc->pad_len; - if (pad_buf) - memcpy(qc->buf_virt + sg->length - qc->pad_len, - pad_buf, qc->pad_len); + if (qc->mapped_n_elem) + dma_unmap_sg(ap->dev, sg, qc->mapped_n_elem, dir); + /* restore last sg */ + if (qc->last_sg) + *qc->last_sg = qc->saved_last_sg; + if (pad_buf) { + struct scatterlist *psg = &qc->extra_sg[1]; + void *addr = kmap_atomic(sg_page(psg), KM_IRQ0); + memcpy(addr + psg->offset, pad_buf, qc->pad_len); + kunmap_atomic(addr, KM_IRQ0); } qc->flags &= ~ATA_QCFLAG_DMAMAP; - qc->__sg = NULL; + qc->sg = NULL; } /** @@ -4523,13 +4520,10 @@ static void ata_fill_sg(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; struct scatterlist *sg; - unsigned int idx; - - WARN_ON(qc->__sg == NULL); - WARN_ON(qc->n_elem == 0 && qc->pad_len == 0); + unsigned int si, pi; - idx = 0; - ata_for_each_sg(sg, qc) { + pi = 0; + for_each_sg(qc->sg, sg, qc->n_elem, si) { u32 addr, offset; u32 sg_len, len; @@ -4546,18 +4540,17 @@ static void ata_fill_sg(struct ata_queued_cmd *qc) if ((offset + sg_len) > 0x10000) len = 0x10000 - offset; - ap->prd[idx].addr = cpu_to_le32(addr); - ap->prd[idx].flags_len = cpu_to_le32(len & 0xffff); - VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", idx, addr, len); + ap->prd[pi].addr = cpu_to_le32(addr); + ap->prd[pi].flags_len = cpu_to_le32(len & 0xffff); + VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", pi, addr, len); - idx++; + pi++; sg_len -= len; addr += len; } } - if (idx) - ap->prd[idx - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT); + ap->prd[pi - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT); } /** @@ -4577,13 +4570,10 @@ static void ata_fill_sg_dumb(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; struct scatterlist *sg; - unsigned int idx; - - WARN_ON(qc->__sg == NULL); - WARN_ON(qc->n_elem == 0 && qc->pad_len == 0); + unsigned int si, pi; - idx = 0; - ata_for_each_sg(sg, qc) { + pi = 0; + for_each_sg(qc->sg, sg, qc->n_elem, si) { u32 addr, offset; u32 sg_len, len, blen; @@ -4601,25 +4591,24 @@ static void ata_fill_sg_dumb(struct ata_queued_cmd *qc) len = 0x10000 - offset; blen = len & 0xffff; - ap->prd[idx].addr = cpu_to_le32(addr); + ap->prd[pi].addr = cpu_to_le32(addr); if (blen == 0) { /* Some PATA chipsets like the CS5530 can't cope with 0x0000 meaning 64K as the spec says */ - ap->prd[idx].flags_len = cpu_to_le32(0x8000); + ap->prd[pi].flags_len = cpu_to_le32(0x8000); blen = 0x8000; - ap->prd[++idx].addr = cpu_to_le32(addr + 0x8000); + ap->prd[++pi].addr = cpu_to_le32(addr + 0x8000); } - ap->prd[idx].flags_len = cpu_to_le32(blen); - VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", idx, addr, len); + ap->prd[pi].flags_len = cpu_to_le32(blen); + VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", pi, addr, len); - idx++; + pi++; sg_len -= len; addr += len; } } - if (idx) - ap->prd[idx - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT); + ap->prd[pi - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT); } /** @@ -4669,8 +4658,8 @@ int ata_check_atapi_dma(struct ata_queued_cmd *qc) */ static int atapi_qc_may_overflow(struct ata_queued_cmd *qc) { - if (qc->tf.protocol != ATA_PROT_ATAPI && - qc->tf.protocol != ATA_PROT_ATAPI_DMA) + if (qc->tf.protocol != ATAPI_PROT_PIO && + qc->tf.protocol != ATAPI_PROT_DMA) return 0; if (qc->tf.flags & ATA_TFLAG_WRITE) @@ -4756,33 +4745,6 @@ void ata_dumb_qc_prep(struct ata_queued_cmd *qc) void ata_noop_qc_prep(struct ata_queued_cmd *qc) { } /** - * ata_sg_init_one - Associate command with memory buffer - * @qc: Command to be associated - * @buf: Memory buffer - * @buflen: Length of memory buffer, in bytes. - * - * Initialize the data-related elements of queued_cmd @qc - * to point to a single memory buffer, @buf of byte length @buflen. - * - * LOCKING: - * spin_lock_irqsave(host lock) - */ - -void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen) -{ - qc->flags |= ATA_QCFLAG_SINGLE; - - qc->__sg = &qc->sgent; - qc->n_elem = 1; - qc->orig_n_elem = 1; - qc->buf_virt = buf; - qc->nbytes = buflen; - qc->cursg = qc->__sg; - - sg_init_one(&qc->sgent, buf, buflen); -} - -/** * ata_sg_init - Associate command with scatter-gather table. * @qc: Command to be associated * @sg: Scatter-gather table. @@ -4795,84 +4757,103 @@ void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen) * LOCKING: * spin_lock_irqsave(host lock) */ - void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg, unsigned int n_elem) { - qc->flags |= ATA_QCFLAG_SG; - qc->__sg = sg; + qc->sg = sg; qc->n_elem = n_elem; - qc->orig_n_elem = n_elem; - qc->cursg = qc->__sg; + qc->cursg = qc->sg; } -/** - * ata_sg_setup_one - DMA-map the memory buffer associated with a command. - * @qc: Command with memory buffer to be mapped. - * - * DMA-map the memory buffer associated with queued_cmd @qc. - * - * LOCKING: - * spin_lock_irqsave(host lock) - * - * RETURNS: - * Zero on success, negative on error. - */ - -static int ata_sg_setup_one(struct ata_queued_cmd *qc) +static unsigned int ata_sg_setup_extra(struct ata_queued_cmd *qc, + unsigned int *n_elem_extra, + unsigned int *nbytes_extra) { struct ata_port *ap = qc->ap; - int dir = qc->dma_dir; - struct scatterlist *sg = qc->__sg; - dma_addr_t dma_address; - int trim_sg = 0; + unsigned int n_elem = qc->n_elem; + struct scatterlist *lsg, *copy_lsg = NULL, *tsg = NULL, *esg = NULL; + + *n_elem_extra = 0; + *nbytes_extra = 0; + + /* needs padding? */ + qc->pad_len = qc->nbytes & 3; + + if (likely(!qc->pad_len)) + return n_elem; + + /* locate last sg and save it */ + lsg = sg_last(qc->sg, n_elem); + qc->last_sg = lsg; + qc->saved_last_sg = *lsg; + + sg_init_table(qc->extra_sg, ARRAY_SIZE(qc->extra_sg)); - /* we must lengthen transfers to end on a 32-bit boundary */ - qc->pad_len = sg->length & 3; if (qc->pad_len) { + struct scatterlist *psg = &qc->extra_sg[1]; void *pad_buf = ap->pad + (qc->tag * ATA_DMA_PAD_SZ); - struct scatterlist *psg = &qc->pad_sgent; + unsigned int offset; WARN_ON(qc->dev->class != ATA_DEV_ATAPI); memset(pad_buf, 0, ATA_DMA_PAD_SZ); - if (qc->tf.flags & ATA_TFLAG_WRITE) - memcpy(pad_buf, qc->buf_virt + sg->length - qc->pad_len, - qc->pad_len); + /* psg->page/offset are used to copy to-be-written + * data in this function or read data in ata_sg_clean. + */ + offset = lsg->offset + lsg->length - qc->pad_len; + sg_set_page(psg, nth_page(sg_page(lsg), offset >> PAGE_SHIFT), + qc->pad_len, offset_in_page(offset)); + + if (qc->tf.flags & ATA_TFLAG_WRITE) { + void *addr = kmap_atomic(sg_page(psg), KM_IRQ0); + memcpy(pad_buf, addr + psg->offset, qc->pad_len); + kunmap_atomic(addr, KM_IRQ0); + } sg_dma_address(psg) = ap->pad_dma + (qc->tag * ATA_DMA_PAD_SZ); sg_dma_len(psg) = ATA_DMA_PAD_SZ; - /* trim sg */ - sg->length -= qc->pad_len; - if (sg->length == 0) - trim_sg = 1; - DPRINTK("padding done, sg->length=%u pad_len=%u\n", - sg->length, qc->pad_len); - } + /* Trim the last sg entry and chain the original and + * padding sg lists. + * + * Because chaining consumes one sg entry, one extra + * sg entry is allocated and the last sg entry is + * copied to it if the length isn't zero after padded + * amount is removed. + * + * If the last sg entry is completely replaced by + * padding sg entry, the first sg entry is skipped + * while chaining. + */ + lsg->length -= qc->pad_len; + if (lsg->length) { + copy_lsg = &qc->extra_sg[0]; + tsg = &qc->extra_sg[0]; + } else { + n_elem--; + tsg = &qc->extra_sg[1]; + } - if (trim_sg) { - qc->n_elem--; - goto skip_map; - } + esg = &qc->extra_sg[1]; - dma_address = dma_map_single(ap->dev, qc->buf_virt, - sg->length, dir); - if (dma_mapping_error(dma_address)) { - /* restore sg */ - sg->length += qc->pad_len; - return -1; + (*n_elem_extra)++; + (*nbytes_extra) += 4 - qc->pad_len; } - sg_dma_address(sg) = dma_address; - sg_dma_len(sg) = sg->length; + if (copy_lsg) + sg_set_page(copy_lsg, sg_page(lsg), lsg->length, lsg->offset); -skip_map: - DPRINTK("mapped buffer of %d bytes for %s\n", sg_dma_len(sg), - qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read"); + sg_chain(lsg, 1, tsg); + sg_mark_end(esg); - return 0; + /* sglist can't start with chaining sg entry, fast forward */ + if (qc->sg == lsg) { + qc->sg = tsg; + qc->cursg = tsg; + } + + return n_elem; } /** @@ -4888,75 +4869,30 @@ skip_map: * Zero on success, negative on error. * */ - static int ata_sg_setup(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; - struct scatterlist *sg = qc->__sg; - struct scatterlist *lsg = sg_last(qc->__sg, qc->n_elem); - int n_elem, pre_n_elem, dir, trim_sg = 0; + unsigned int n_elem, n_elem_extra, nbytes_extra; 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 */ - qc->pad_len = lsg->length & 3; - if (qc->pad_len) { - void *pad_buf = ap->pad + (qc->tag * ATA_DMA_PAD_SZ); - struct scatterlist *psg = &qc->pad_sgent; - unsigned int offset; - - WARN_ON(qc->dev->class != ATA_DEV_ATAPI); - - memset(pad_buf, 0, ATA_DMA_PAD_SZ); - /* - * psg->page/offset are used to copy to-be-written - * data in this function or read data in ata_sg_clean. - */ - offset = lsg->offset + lsg->length - qc->pad_len; - sg_init_table(psg, 1); - sg_set_page(psg, nth_page(sg_page(lsg), offset >> PAGE_SHIFT), - qc->pad_len, offset_in_page(offset)); + n_elem = ata_sg_setup_extra(qc, &n_elem_extra, &nbytes_extra); - if (qc->tf.flags & ATA_TFLAG_WRITE) { - void *addr = kmap_atomic(sg_page(psg), KM_IRQ0); - memcpy(pad_buf, addr + psg->offset, qc->pad_len); - kunmap_atomic(addr, KM_IRQ0); + if (n_elem) { + n_elem = dma_map_sg(ap->dev, qc->sg, n_elem, qc->dma_dir); + if (n_elem < 1) { + /* restore last sg */ + if (qc->last_sg) + *qc->last_sg = qc->saved_last_sg; + return -1; } - - sg_dma_address(psg) = ap->pad_dma + (qc->tag * ATA_DMA_PAD_SZ); - sg_dma_len(psg) = ATA_DMA_PAD_SZ; - /* trim last sg */ - lsg->length -= qc->pad_len; - if (lsg->length == 0) - trim_sg = 1; - - DPRINTK("padding done, sg[%d].length=%u pad_len=%u\n", - qc->n_elem - 1, lsg->length, qc->pad_len); + DPRINTK("%d sg elements mapped\n", n_elem); } - pre_n_elem = qc->n_elem; - if (trim_sg && pre_n_elem) - pre_n_elem--; - - if (!pre_n_elem) { - n_elem = 0; - goto skip_map; - } - - dir = qc->dma_dir; - n_elem = dma_map_sg(ap->dev, sg, pre_n_elem, dir); - if (n_elem < 1) { - /* restore last sg */ - lsg->length += qc->pad_len; - return -1; - } - - DPRINTK("%d sg elements mapped\n", n_elem); - -skip_map: - qc->n_elem = n_elem; + qc->n_elem = qc->mapped_n_elem = n_elem; + qc->n_elem += n_elem_extra; + qc->nbytes += nbytes_extra; + qc->flags |= ATA_QCFLAG_DMAMAP; return 0; } @@ -4985,7 +4921,7 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words) /** * ata_data_xfer - Transfer data by PIO - * @adev: device to target + * @dev: device to target * @buf: data buffer * @buflen: buffer length * @write_data: read/write @@ -4994,37 +4930,44 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words) * * LOCKING: * Inherited from caller. + * + * RETURNS: + * Bytes consumed. */ -void ata_data_xfer(struct ata_device *adev, unsigned char *buf, - unsigned int buflen, int write_data) +unsigned int ata_data_xfer(struct ata_device *dev, unsigned char *buf, + unsigned int buflen, int rw) { - struct ata_port *ap = adev->link->ap; + struct ata_port *ap = dev->link->ap; + void __iomem *data_addr = ap->ioaddr.data_addr; unsigned int words = buflen >> 1; /* Transfer multiple of 2 bytes */ - if (write_data) - iowrite16_rep(ap->ioaddr.data_addr, buf, words); + if (rw == READ) + ioread16_rep(data_addr, buf, words); else - ioread16_rep(ap->ioaddr.data_addr, buf, words); + iowrite16_rep(data_addr, buf, words); /* 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 (write_data) { - memcpy(align_buf, trailing_buf, 1); - iowrite16(le16_to_cpu(align_buf[0]), ap->ioaddr.data_addr); - } else { - align_buf[0] = cpu_to_le16(ioread16(ap->ioaddr.data_addr)); + if (rw == READ) { + align_buf[0] = cpu_to_le16(ioread16(data_addr)); memcpy(trailing_buf, align_buf, 1); + } else { + memcpy(align_buf, trailing_buf, 1); + iowrite16(le16_to_cpu(align_buf[0]), data_addr); } + words++; } + + return words << 1; } /** * ata_data_xfer_noirq - Transfer data by PIO - * @adev: device to target + * @dev: device to target * @buf: data buffer * @buflen: buffer length * @write_data: read/write @@ -5034,14 +4977,21 @@ void ata_data_xfer(struct ata_device *adev, unsigned char *buf, * * LOCKING: * Inherited from caller. + * + * RETURNS: + * Bytes consumed. */ -void ata_data_xfer_noirq(struct ata_device *adev, unsigned char *buf, - unsigned int buflen, int write_data) +unsigned int ata_data_xfer_noirq(struct ata_device *dev, unsigned char *buf, + unsigned int buflen, int rw) { unsigned long flags; + unsigned int consumed; + local_irq_save(flags); - ata_data_xfer(adev, buf, buflen, write_data); + consumed = ata_data_xfer(dev, buf, buflen, rw); local_irq_restore(flags); + + return consumed; } @@ -5152,13 +5102,13 @@ static void atapi_send_cdb(struct ata_port *ap, struct ata_queued_cmd *qc) ata_altstatus(ap); /* flush */ switch (qc->tf.protocol) { - case ATA_PROT_ATAPI: + case ATAPI_PROT_PIO: ap->hsm_task_state = HSM_ST; break; - case ATA_PROT_ATAPI_NODATA: + case ATAPI_PROT_NODATA: ap->hsm_task_state = HSM_ST_LAST; break; - case ATA_PROT_ATAPI_DMA: + case ATAPI_PROT_DMA: ap->hsm_task_state = HSM_ST_LAST; /* initiate bmdma */ ap->ops->bmdma_start(qc); @@ -5300,12 +5250,15 @@ static void atapi_pio_bytes(struct ata_queued_cmd *qc) bytes = (bc_hi << 8) | bc_lo; /* shall be cleared to zero, indicating xfer of data */ - if (ireason & (1 << 0)) + if (unlikely(ireason & (1 << 0))) goto err_out; /* make sure transfer direction matches expected */ i_write = ((ireason & (1 << 1)) == 0) ? 1 : 0; - if (do_write != i_write) + if (unlikely(do_write != i_write)) + goto err_out; + + if (unlikely(!bytes)) goto err_out; VPRINTK("ata%u: xfering %d bytes\n", ap->print_id, bytes); @@ -5341,7 +5294,7 @@ static inline int ata_hsm_ok_in_wq(struct ata_port *ap, struct ata_queued_cmd *q (qc->tf.flags & ATA_TFLAG_WRITE)) return 1; - if (is_atapi_taskfile(&qc->tf) && + if (ata_is_atapi(qc->tf.protocol) && !(qc->dev->flags & ATA_DFLAG_CDB_INTR)) return 1; } @@ -5506,7 +5459,7 @@ fsm_start: case HSM_ST: /* complete command or read/write the data register */ - if (qc->tf.protocol == ATA_PROT_ATAPI) { + if (qc->tf.protocol == ATAPI_PROT_PIO) { /* ATAPI PIO protocol */ if ((status & ATA_DRQ) == 0) { /* No more data to transfer or device error. @@ -5664,7 +5617,7 @@ fsm_start: msleep(2); status = ata_busy_wait(ap, ATA_BUSY, 10); if (status & ATA_BUSY) { - ata_port_queue_task(ap, ata_pio_task, qc, ATA_SHORT_PAUSE); + ata_pio_queue_task(ap, qc, ATA_SHORT_PAUSE); return; } } @@ -5805,6 +5758,22 @@ static void fill_result_tf(struct ata_queued_cmd *qc) ap->ops->tf_read(ap, &qc->result_tf); } +static void ata_verify_xfer(struct ata_queued_cmd *qc) +{ + struct ata_device *dev = qc->dev; + + if (ata_tag_internal(qc->tag)) + return; + + if (ata_is_nodata(qc->tf.protocol)) + return; + + if ((dev->mwdma_mask || dev->udma_mask) && ata_is_pio(qc->tf.protocol)) + return; + + dev->flags &= ~ATA_DFLAG_DUBIOUS_XFER; +} + /** * ata_qc_complete - Complete an active ATA command * @qc: Command to complete @@ -5876,6 +5845,9 @@ void ata_qc_complete(struct ata_queued_cmd *qc) break; } + if (unlikely(dev->flags & ATA_DFLAG_DUBIOUS_XFER)) + ata_verify_xfer(qc); + __ata_qc_complete(qc); } else { if (qc->flags & ATA_QCFLAG_EH_SCHEDULED) @@ -5938,30 +5910,6 @@ int ata_qc_complete_multiple(struct ata_port *ap, u32 qc_active, return nr_done; } -static inline int ata_should_dma_map(struct ata_queued_cmd *qc) -{ - struct ata_port *ap = qc->ap; - - switch (qc->tf.protocol) { - case ATA_PROT_NCQ: - case ATA_PROT_DMA: - case ATA_PROT_ATAPI_DMA: - return 1; - - case ATA_PROT_ATAPI: - case ATA_PROT_PIO: - if (ap->flags & ATA_FLAG_PIO_DMA) - return 1; - - /* fall through */ - - default: - return 0; - } - - /* never reached */ -} - /** * ata_qc_issue - issue taskfile to device * @qc: command to issue to device @@ -5978,6 +5926,7 @@ void ata_qc_issue(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; struct ata_link *link = qc->dev->link; + u8 prot = qc->tf.protocol; /* Make sure only one non-NCQ command is outstanding. The * check is skipped for old EH because it reuses active qc to @@ -5985,7 +5934,7 @@ void ata_qc_issue(struct ata_queued_cmd *qc) */ WARN_ON(ap->ops->error_handler && ata_tag_valid(link->active_tag)); - if (qc->tf.protocol == ATA_PROT_NCQ) { + if (ata_is_ncq(prot)) { WARN_ON(link->sactive & (1 << qc->tag)); if (!link->sactive) @@ -6001,17 +5950,18 @@ void ata_qc_issue(struct ata_queued_cmd *qc) qc->flags |= ATA_QCFLAG_ACTIVE; ap->qc_active |= 1 << qc->tag; - if (ata_should_dma_map(qc)) { - if (qc->flags & ATA_QCFLAG_SG) { - if (ata_sg_setup(qc)) - goto sg_err; - } else if (qc->flags & ATA_QCFLAG_SINGLE) { - if (ata_sg_setup_one(qc)) - goto sg_err; - } - } else { - qc->flags &= ~ATA_QCFLAG_DMAMAP; - } + /* We guarantee to LLDs that they will have at least one + * non-zero sg if the command is a data command. + */ + BUG_ON(ata_is_data(prot) && (!qc->sg || !qc->n_elem || !qc->nbytes)); + + /* ata_sg_setup() may update nbytes */ + qc->raw_nbytes = qc->nbytes; + + if (ata_is_dma(prot) || (ata_is_pio(prot) && + (ap->flags & ATA_FLAG_PIO_DMA))) + if (ata_sg_setup(qc)) + goto sg_err; /* if device is sleeping, schedule softreset and abort the link */ if (unlikely(qc->dev->flags & ATA_DFLAG_SLEEPING)) { @@ -6029,7 +5979,6 @@ void ata_qc_issue(struct ata_queued_cmd *qc) return; sg_err: - qc->flags &= ~ATA_QCFLAG_DMAMAP; qc->err_mask |= AC_ERR_SYSTEM; err: ata_qc_complete(qc); @@ -6064,11 +6013,11 @@ unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc) switch (qc->tf.protocol) { case ATA_PROT_PIO: case ATA_PROT_NODATA: - case ATA_PROT_ATAPI: - case ATA_PROT_ATAPI_NODATA: + case ATAPI_PROT_PIO: + case ATAPI_PROT_NODATA: qc->tf.flags |= ATA_TFLAG_POLLING; break; - case ATA_PROT_ATAPI_DMA: + case ATAPI_PROT_DMA: if (qc->dev->flags & ATA_DFLAG_CDB_INTR) /* see ata_dma_blacklisted() */ BUG(); @@ -6091,7 +6040,7 @@ unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc) ap->hsm_task_state = HSM_ST_LAST; if (qc->tf.flags & ATA_TFLAG_POLLING) - ata_port_queue_task(ap, ata_pio_task, qc, 0); + ata_pio_queue_task(ap, qc, 0); break; @@ -6113,7 +6062,7 @@ unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc) if (qc->tf.flags & ATA_TFLAG_WRITE) { /* PIO data out protocol */ ap->hsm_task_state = HSM_ST_FIRST; - ata_port_queue_task(ap, ata_pio_task, qc, 0); + ata_pio_queue_task(ap, qc, 0); /* always send first data block using * the ata_pio_task() codepath. @@ -6123,7 +6072,7 @@ unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc) ap->hsm_task_state = HSM_ST; if (qc->tf.flags & ATA_TFLAG_POLLING) - ata_port_queue_task(ap, ata_pio_task, qc, 0); + ata_pio_queue_task(ap, qc, 0); /* if polling, ata_pio_task() handles the rest. * otherwise, interrupt handler takes over from here. @@ -6132,8 +6081,8 @@ unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc) break; - case ATA_PROT_ATAPI: - case ATA_PROT_ATAPI_NODATA: + case ATAPI_PROT_PIO: + case ATAPI_PROT_NODATA: if (qc->tf.flags & ATA_TFLAG_POLLING) ata_qc_set_polling(qc); @@ -6144,10 +6093,10 @@ unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc) /* send cdb by polling if no cdb interrupt */ if ((!(qc->dev->flags & ATA_DFLAG_CDB_INTR)) || (qc->tf.flags & ATA_TFLAG_POLLING)) - ata_port_queue_task(ap, ata_pio_task, qc, 0); + ata_pio_queue_task(ap, qc, 0); break; - case ATA_PROT_ATAPI_DMA: + case ATAPI_PROT_DMA: WARN_ON(qc->tf.flags & ATA_TFLAG_POLLING); ap->ops->tf_load(ap, &qc->tf); /* load tf registers */ @@ -6156,7 +6105,7 @@ unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc) /* send cdb by polling if no cdb interrupt */ if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR)) - ata_port_queue_task(ap, ata_pio_task, qc, 0); + ata_pio_queue_task(ap, qc, 0); break; default: @@ -6188,6 +6137,7 @@ inline unsigned int ata_host_intr(struct ata_port *ap, { struct ata_eh_info *ehi = &ap->link.eh_info; u8 status, host_stat = 0; + int i; VPRINTK("ata%u: protocol %d task_state %d\n", ap->print_id, qc->tf.protocol, ap->hsm_task_state); @@ -6200,15 +6150,15 @@ inline unsigned int ata_host_intr(struct ata_port *ap, */ /* Check the ATA_DFLAG_CDB_INTR flag is enough here. - * The flag was turned on only for atapi devices. - * No need to check is_atapi_taskfile(&qc->tf) again. + * The flag was turned on only for atapi devices. No + * need to check ata_is_atapi(qc->tf.protocol) again. */ if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR)) goto idle_irq; break; case HSM_ST_LAST: if (qc->tf.protocol == ATA_PROT_DMA || - qc->tf.protocol == ATA_PROT_ATAPI_DMA) { + qc->tf.protocol == ATAPI_PROT_DMA) { /* check status of DMA engine */ host_stat = ap->ops->bmdma_status(ap); VPRINTK("ata%u: host_stat 0x%X\n", @@ -6244,13 +6194,27 @@ inline unsigned int ata_host_intr(struct ata_port *ap, if (unlikely(status & ATA_BUSY)) goto idle_irq; + if (unlikely(qc->tf.command == ATA_CMD_SET_FEATURES && + qc->tf.feature == SETFEATURES_XFER)) { + /* Let the timings change settle and the drive catch up as + some hardware needs up to 10uS to get its brain back in + gear. Taken from the workarounds in drivers/ide done by + Matthew Faupel/Niccolo Rigacci */ + for (i = 0; i < 10; i++) { + if ((status & (ATA_BUSY | ATA_DRQ | ATA_ERR)) == 0) + break; + udelay(1); + status = ata_chk_status(ap); + } + } + /* ack bmdma irq events */ ap->ops->irq_clear(ap); ata_hsm_move(ap, qc, status, 0); if (unlikely(qc->err_mask) && (qc->tf.protocol == ATA_PROT_DMA || - qc->tf.protocol == ATA_PROT_ATAPI_DMA)) + qc->tf.protocol == ATAPI_PROT_DMA)) ata_ehi_push_desc(ehi, "BMDMA stat 0x%x", host_stat); return 1; /* irq handled */ @@ -6772,7 +6736,7 @@ struct ata_port *ata_port_alloc(struct ata_host *host) ap->msg_enable = ATA_MSG_DRV | ATA_MSG_ERR | ATA_MSG_WARN; #endif - INIT_DELAYED_WORK(&ap->port_task, NULL); + INIT_DELAYED_WORK(&ap->port_task, ata_pio_task); INIT_DELAYED_WORK(&ap->hotplug_task, ata_scsi_hotplug); INIT_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan); INIT_LIST_HEAD(&ap->eh_done_q); @@ -7589,7 +7553,6 @@ EXPORT_SYMBOL_GPL(ata_host_register); EXPORT_SYMBOL_GPL(ata_host_activate); EXPORT_SYMBOL_GPL(ata_host_detach); EXPORT_SYMBOL_GPL(ata_sg_init); -EXPORT_SYMBOL_GPL(ata_sg_init_one); EXPORT_SYMBOL_GPL(ata_hsm_move); EXPORT_SYMBOL_GPL(ata_qc_complete); EXPORT_SYMBOL_GPL(ata_qc_complete_multiple); @@ -7601,6 +7564,13 @@ EXPORT_SYMBOL_GPL(ata_std_dev_select); EXPORT_SYMBOL_GPL(sata_print_link_status); EXPORT_SYMBOL_GPL(ata_tf_to_fis); EXPORT_SYMBOL_GPL(ata_tf_from_fis); +EXPORT_SYMBOL_GPL(ata_pack_xfermask); +EXPORT_SYMBOL_GPL(ata_unpack_xfermask); +EXPORT_SYMBOL_GPL(ata_xfer_mask2mode); +EXPORT_SYMBOL_GPL(ata_xfer_mode2mask); +EXPORT_SYMBOL_GPL(ata_xfer_mode2shift); +EXPORT_SYMBOL_GPL(ata_mode_string); +EXPORT_SYMBOL_GPL(ata_id_xfermask); EXPORT_SYMBOL_GPL(ata_check_status); EXPORT_SYMBOL_GPL(ata_altstatus); EXPORT_SYMBOL_GPL(ata_exec_command); @@ -7643,7 +7613,6 @@ EXPORT_SYMBOL_GPL(ata_wait_register); EXPORT_SYMBOL_GPL(ata_busy_sleep); EXPORT_SYMBOL_GPL(ata_wait_after_reset); EXPORT_SYMBOL_GPL(ata_wait_ready); -EXPORT_SYMBOL_GPL(ata_port_queue_task); EXPORT_SYMBOL_GPL(ata_scsi_ioctl); EXPORT_SYMBOL_GPL(ata_scsi_queuecmd); EXPORT_SYMBOL_GPL(ata_scsi_slave_config); @@ -7662,12 +7631,13 @@ 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); EXPORT_SYMBOL_GPL(ata_scsi_simulate); EXPORT_SYMBOL_GPL(ata_pio_need_iordy); +EXPORT_SYMBOL_GPL(ata_timing_find_mode); EXPORT_SYMBOL_GPL(ata_timing_compute); EXPORT_SYMBOL_GPL(ata_timing_merge); +EXPORT_SYMBOL_GPL(ata_timing_cycle2mode); #ifdef CONFIG_PCI EXPORT_SYMBOL_GPL(pci_test_config_bits); @@ -7715,4 +7685,5 @@ EXPORT_SYMBOL_GPL(ata_dev_try_classify); EXPORT_SYMBOL_GPL(ata_cable_40wire); EXPORT_SYMBOL_GPL(ata_cable_80wire); EXPORT_SYMBOL_GPL(ata_cable_unknown); +EXPORT_SYMBOL_GPL(ata_cable_ignore); EXPORT_SYMBOL_GPL(ata_cable_sata); diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 21a81cd..4195526 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -46,9 +46,27 @@ #include "libata.h" enum { + /* speed down verdicts */ ATA_EH_SPDN_NCQ_OFF = (1 << 0), ATA_EH_SPDN_SPEED_DOWN = (1 << 1), ATA_EH_SPDN_FALLBACK_TO_PIO = (1 << 2), + ATA_EH_SPDN_KEEP_ERRORS = (1 << 3), + + /* error flags */ + ATA_EFLAG_IS_IO = (1 << 0), + ATA_EFLAG_DUBIOUS_XFER = (1 << 1), + + /* error categories */ + ATA_ECAT_NONE = 0, + ATA_ECAT_ATA_BUS = 1, + ATA_ECAT_TOUT_HSM = 2, + ATA_ECAT_UNK_DEV = 3, + ATA_ECAT_DUBIOUS_ATA_BUS = 4, + ATA_ECAT_DUBIOUS_TOUT_HSM = 5, + ATA_ECAT_DUBIOUS_UNK_DEV = 6, + ATA_ECAT_NR = 7, + + ATA_ECAT_DUBIOUS_BASE = ATA_ECAT_DUBIOUS_ATA_BUS, }; /* Waiting in ->prereset can never be reliable. It's sometimes nice @@ -213,12 +231,13 @@ void ata_port_pbar_desc(struct ata_port *ap, int bar, ssize_t offset, if (offset < 0) ata_port_desc(ap, "%s %s%llu@0x%llx", name, type, len, start); else - ata_port_desc(ap, "%s 0x%llx", name, start + offset); + ata_port_desc(ap, "%s 0x%llx", name, + start + (unsigned long long)offset); } #endif /* CONFIG_PCI */ -static void ata_ering_record(struct ata_ering *ering, int is_io, +static void ata_ering_record(struct ata_ering *ering, unsigned int eflags, unsigned int err_mask) { struct ata_ering_entry *ent; @@ -229,11 +248,20 @@ static void ata_ering_record(struct ata_ering *ering, int is_io, ering->cursor %= ATA_ERING_SIZE; ent = &ering->ring[ering->cursor]; - ent->is_io = is_io; + ent->eflags = eflags; ent->err_mask = err_mask; ent->timestamp = get_jiffies_64(); } +static struct ata_ering_entry *ata_ering_top(struct ata_ering *ering) +{ + struct ata_ering_entry *ent = &ering->ring[ering->cursor]; + + if (ent->err_mask) + return ent; + return NULL; +} + static void ata_ering_clear(struct ata_ering *ering) { memset(ering, 0, sizeof(*ering)); @@ -445,9 +473,20 @@ void ata_scsi_error(struct Scsi_Host *host) spin_lock_irqsave(ap->lock, flags); __ata_port_for_each_link(link, ap) { + struct ata_eh_context *ehc = &link->eh_context; + struct ata_device *dev; + memset(&link->eh_context, 0, sizeof(link->eh_context)); link->eh_context.i = link->eh_info; memset(&link->eh_info, 0, sizeof(link->eh_info)); + + ata_link_for_each_dev(dev, link) { + int devno = dev->devno; + + ehc->saved_xfer_mode[devno] = dev->xfer_mode; + if (ata_ncq_enabled(dev)) + ehc->saved_ncq_enabled |= 1 << devno; + } } ap->pflags |= ATA_PFLAG_EH_IN_PROGRESS; @@ -1260,10 +1299,10 @@ static unsigned int atapi_eh_request_sense(struct ata_queued_cmd *qc) /* is it pointless to prefer PIO for "safety reasons"? */ if (ap->flags & ATA_FLAG_PIO_DMA) { - tf.protocol = ATA_PROT_ATAPI_DMA; + tf.protocol = ATAPI_PROT_DMA; tf.feature |= ATAPI_PKT_DMA; } else { - tf.protocol = ATA_PROT_ATAPI; + tf.protocol = ATAPI_PROT_PIO; tf.lbam = SCSI_SENSE_BUFFERSIZE; tf.lbah = 0; } @@ -1451,20 +1490,29 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc, return action; } -static int ata_eh_categorize_error(int is_io, unsigned int err_mask) +static int ata_eh_categorize_error(unsigned int eflags, unsigned int err_mask, + int *xfer_ok) { + int base = 0; + + if (!(eflags & ATA_EFLAG_DUBIOUS_XFER)) + *xfer_ok = 1; + + if (!*xfer_ok) + base = ATA_ECAT_DUBIOUS_BASE; + if (err_mask & AC_ERR_ATA_BUS) - return 1; + return base + ATA_ECAT_ATA_BUS; if (err_mask & AC_ERR_TIMEOUT) - return 2; + return base + ATA_ECAT_TOUT_HSM; - if (is_io) { + if (eflags & ATA_EFLAG_IS_IO) { if (err_mask & AC_ERR_HSM) - return 2; + return base + ATA_ECAT_TOUT_HSM; if ((err_mask & (AC_ERR_DEV|AC_ERR_MEDIA|AC_ERR_INVALID)) == AC_ERR_DEV) - return 3; + return base + ATA_ECAT_UNK_DEV; } return 0; @@ -1472,18 +1520,22 @@ static int ata_eh_categorize_error(int is_io, unsigned int err_mask) struct speed_down_verdict_arg { u64 since; - int nr_errors[4]; + int xfer_ok; + int nr_errors[ATA_ECAT_NR]; }; static int speed_down_verdict_cb(struct ata_ering_entry *ent, void *void_arg) { struct speed_down_verdict_arg *arg = void_arg; - int cat = ata_eh_categorize_error(ent->is_io, ent->err_mask); + int cat; if (ent->timestamp < arg->since) return -1; + cat = ata_eh_categorize_error(ent->eflags, ent->err_mask, + &arg->xfer_ok); arg->nr_errors[cat]++; + return 0; } @@ -1495,22 +1547,48 @@ static int speed_down_verdict_cb(struct ata_ering_entry *ent, void *void_arg) * whether NCQ needs to be turned off, transfer speed should be * stepped down, or falling back to PIO is necessary. * - * Cat-1 is ATA_BUS error for any command. + * ECAT_ATA_BUS : ATA_BUS error for any command + * + * ECAT_TOUT_HSM : TIMEOUT for any command or HSM violation for + * IO commands + * + * ECAT_UNK_DEV : Unknown DEV error for IO commands + * + * ECAT_DUBIOUS_* : Identical to above three but occurred while + * data transfer hasn't been verified. + * + * Verdicts are + * + * NCQ_OFF : Turn off NCQ. + * + * SPEED_DOWN : Speed down transfer speed but don't fall back + * to PIO. + * + * FALLBACK_TO_PIO : Fall back to PIO. + * + * Even if multiple verdicts are returned, only one action is + * taken per error. An action triggered by non-DUBIOUS errors + * clears ering, while one triggered by DUBIOUS_* errors doesn't. + * This is to expedite speed down decisions right after device is + * initially configured. * - * Cat-2 is TIMEOUT for any command or HSM violation for known - * supported commands. + * The followings are speed down rules. #1 and #2 deal with + * DUBIOUS errors. * - * Cat-3 is is unclassified DEV error for known supported - * command. + * 1. If more than one DUBIOUS_ATA_BUS or DUBIOUS_TOUT_HSM errors + * occurred during last 5 mins, SPEED_DOWN and FALLBACK_TO_PIO. * - * NCQ needs to be turned off if there have been more than 3 - * Cat-2 + Cat-3 errors during last 10 minutes. + * 2. If more than one DUBIOUS_TOUT_HSM or DUBIOUS_UNK_DEV errors + * occurred during last 5 mins, NCQ_OFF. * - * Speed down is necessary if there have been more than 3 Cat-1 + - * Cat-2 errors or 10 Cat-3 errors during last 10 minutes. + * 3. If more than 8 ATA_BUS, TOUT_HSM or UNK_DEV errors + * ocurred during last 5 mins, FALLBACK_TO_PIO * - * Falling back to PIO mode is necessary if there have been more - * than 10 Cat-1 + Cat-2 + Cat-3 errors during last 5 minutes. + * 4. If more than 3 TOUT_HSM or UNK_DEV errors occurred + * during last 10 mins, NCQ_OFF. + * + * 5. If more than 3 ATA_BUS or TOUT_HSM errors, or more than 6 + * UNK_DEV errors occurred during last 10 mins, SPEED_DOWN. * * LOCKING: * Inherited from caller. @@ -1525,23 +1603,38 @@ static unsigned int ata_eh_speed_down_verdict(struct ata_device *dev) struct speed_down_verdict_arg arg; unsigned int verdict = 0; - /* scan past 10 mins of error history */ + /* scan past 5 mins of error history */ memset(&arg, 0, sizeof(arg)); - arg.since = j64 - min(j64, j10mins); + arg.since = j64 - min(j64, j5mins); ata_ering_map(&dev->ering, speed_down_verdict_cb, &arg); - if (arg.nr_errors[2] + arg.nr_errors[3] > 3) - verdict |= ATA_EH_SPDN_NCQ_OFF; - if (arg.nr_errors[1] + arg.nr_errors[2] > 3 || arg.nr_errors[3] > 10) - verdict |= ATA_EH_SPDN_SPEED_DOWN; + if (arg.nr_errors[ATA_ECAT_DUBIOUS_ATA_BUS] + + arg.nr_errors[ATA_ECAT_DUBIOUS_TOUT_HSM] > 1) + verdict |= ATA_EH_SPDN_SPEED_DOWN | + ATA_EH_SPDN_FALLBACK_TO_PIO | ATA_EH_SPDN_KEEP_ERRORS; - /* scan past 3 mins of error history */ + if (arg.nr_errors[ATA_ECAT_DUBIOUS_TOUT_HSM] + + arg.nr_errors[ATA_ECAT_DUBIOUS_UNK_DEV] > 1) + verdict |= ATA_EH_SPDN_NCQ_OFF | ATA_EH_SPDN_KEEP_ERRORS; + + if (arg.nr_errors[ATA_ECAT_ATA_BUS] + + arg.nr_errors[ATA_ECAT_TOUT_HSM] + + arg.nr_errors[ATA_ECAT_UNK_DEV] > 6) + verdict |= ATA_EH_SPDN_FALLBACK_TO_PIO; + + /* scan past 10 mins of error history */ memset(&arg, 0, sizeof(arg)); - arg.since = j64 - min(j64, j5mins); + arg.since = j64 - min(j64, j10mins); ata_ering_map(&dev->ering, speed_down_verdict_cb, &arg); - if (arg.nr_errors[1] + arg.nr_errors[2] + arg.nr_errors[3] > 10) - verdict |= ATA_EH_SPDN_FALLBACK_TO_PIO; + if (arg.nr_errors[ATA_ECAT_TOUT_HSM] + + arg.nr_errors[ATA_ECAT_UNK_DEV] > 3) + verdict |= ATA_EH_SPDN_NCQ_OFF; + + if (arg.nr_errors[ATA_ECAT_ATA_BUS] + + arg.nr_errors[ATA_ECAT_TOUT_HSM] > 3 || + arg.nr_errors[ATA_ECAT_UNK_DEV] > 6) + verdict |= ATA_EH_SPDN_SPEED_DOWN; return verdict; } @@ -1549,7 +1642,7 @@ static unsigned int ata_eh_speed_down_verdict(struct ata_device *dev) /** * ata_eh_speed_down - record error and speed down if necessary * @dev: Failed device - * @is_io: Did the device fail during normal IO? + * @eflags: mask of ATA_EFLAG_* flags * @err_mask: err_mask of the error * * Record error and examine error history to determine whether @@ -1563,18 +1656,20 @@ static unsigned int ata_eh_speed_down_verdict(struct ata_device *dev) * RETURNS: * Determined recovery action. */ -static unsigned int ata_eh_speed_down(struct ata_device *dev, int is_io, - unsigned int err_mask) +static unsigned int ata_eh_speed_down(struct ata_device *dev, + unsigned int eflags, unsigned int err_mask) { + struct ata_link *link = dev->link; + int xfer_ok = 0; unsigned int verdict; unsigned int action = 0; /* don't bother if Cat-0 error */ - if (ata_eh_categorize_error(is_io, err_mask) == 0) + if (ata_eh_categorize_error(eflags, err_mask, &xfer_ok) == 0) return 0; /* record error and determine whether speed down is necessary */ - ata_ering_record(&dev->ering, is_io, err_mask); + ata_ering_record(&dev->ering, eflags, err_mask); verdict = ata_eh_speed_down_verdict(dev); /* turn off NCQ? */ @@ -1590,7 +1685,7 @@ static unsigned int ata_eh_speed_down(struct ata_device *dev, int is_io, /* speed down? */ if (verdict & ATA_EH_SPDN_SPEED_DOWN) { /* speed down SATA link speed if possible */ - if (sata_down_spd_limit(dev->link) == 0) { + if (sata_down_spd_limit(link) == 0) { action |= ATA_EH_HARDRESET; goto done; } @@ -1618,10 +1713,10 @@ static unsigned int ata_eh_speed_down(struct ata_device *dev, int is_io, } /* Fall back to PIO? Slowing down to PIO is meaningless for - * SATA. Consider it only for PATA. + * SATA ATA devices. Consider it only for PATA and SATAPI. */ if ((verdict & ATA_EH_SPDN_FALLBACK_TO_PIO) && (dev->spdn_cnt >= 2) && - (dev->link->ap->cbl != ATA_CBL_SATA) && + (link->ap->cbl != ATA_CBL_SATA || dev->class == ATA_DEV_ATAPI) && (dev->xfer_shift != ATA_SHIFT_PIO)) { if (ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO) == 0) { dev->spdn_cnt = 0; @@ -1633,7 +1728,8 @@ static unsigned int ata_eh_speed_down(struct ata_device *dev, int is_io, return 0; done: /* device has been slowed down, blow error history */ - ata_ering_clear(&dev->ering); + if (!(verdict & ATA_EH_SPDN_KEEP_ERRORS)) + ata_ering_clear(&dev->ering); return action; } @@ -1653,8 +1749,8 @@ static void ata_eh_link_autopsy(struct ata_link *link) struct ata_port *ap = link->ap; struct ata_eh_context *ehc = &link->eh_context; struct ata_device *dev; - unsigned int all_err_mask = 0; - int tag, is_io = 0; + unsigned int all_err_mask = 0, eflags = 0; + int tag; u32 serror; int rc; @@ -1713,15 +1809,15 @@ static void ata_eh_link_autopsy(struct ata_link *link) ehc->i.dev = qc->dev; all_err_mask |= qc->err_mask; if (qc->flags & ATA_QCFLAG_IO) - is_io = 1; + eflags |= ATA_EFLAG_IS_IO; } /* enforce default EH actions */ if (ap->pflags & ATA_PFLAG_FROZEN || all_err_mask & (AC_ERR_HSM | AC_ERR_TIMEOUT)) ehc->i.action |= ATA_EH_SOFTRESET; - else if ((is_io && all_err_mask) || - (!is_io && (all_err_mask & ~AC_ERR_DEV))) + else if (((eflags & ATA_EFLAG_IS_IO) && all_err_mask) || + (!(eflags & ATA_EFLAG_IS_IO) && (all_err_mask & ~AC_ERR_DEV))) ehc->i.action |= ATA_EH_REVALIDATE; /* If we have offending qcs and the associated failed device, @@ -1743,8 +1839,11 @@ static void ata_eh_link_autopsy(struct ata_link *link) ata_dev_enabled(link->device)))) dev = link->device; - if (dev) - ehc->i.action |= ata_eh_speed_down(dev, is_io, all_err_mask); + if (dev) { + if (dev->flags & ATA_DFLAG_DUBIOUS_XFER) + eflags |= ATA_EFLAG_DUBIOUS_XFER; + ehc->i.action |= ata_eh_speed_down(dev, eflags, all_err_mask); + } DPRINTK("EXIT\n"); } @@ -1880,8 +1979,8 @@ static void ata_eh_link_report(struct ata_link *link) [ATA_PROT_PIO] = "pio", [ATA_PROT_DMA] = "dma", [ATA_PROT_NCQ] = "ncq", - [ATA_PROT_ATAPI] = "pio", - [ATA_PROT_ATAPI_DMA] = "dma", + [ATAPI_PROT_PIO] = "pio", + [ATAPI_PROT_DMA] = "dma", }; snprintf(data_buf, sizeof(data_buf), " %s %u %s", @@ -1889,7 +1988,7 @@ static void ata_eh_link_report(struct ata_link *link) dma_str[qc->dma_dir]); } - if (is_atapi_taskfile(&qc->tf)) + if (ata_is_atapi(qc->tf.protocol)) snprintf(cdb_buf, sizeof(cdb_buf), "cdb %02x %02x %02x %02x %02x %02x %02x %02x " "%02x %02x %02x %02x %02x %02x %02x %02x\n ", @@ -2329,6 +2428,58 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link, return rc; } +/** + * ata_set_mode - Program timings and issue SET FEATURES - XFER + * @link: link on which timings will be programmed + * @r_failed_dev: out paramter for failed device + * + * Set ATA device disk transfer mode (PIO3, UDMA6, etc.). If + * ata_set_mode() fails, pointer to the failing device is + * returned in @r_failed_dev. + * + * LOCKING: + * PCI/etc. bus probe sem. + * + * RETURNS: + * 0 on success, negative errno otherwise + */ +int ata_set_mode(struct ata_link *link, struct ata_device **r_failed_dev) +{ + struct ata_port *ap = link->ap; + struct ata_device *dev; + int rc; + + /* if data transfer is verified, clear DUBIOUS_XFER on ering top */ + ata_link_for_each_dev(dev, link) { + if (!(dev->flags & ATA_DFLAG_DUBIOUS_XFER)) { + struct ata_ering_entry *ent; + + ent = ata_ering_top(&dev->ering); + if (ent) + ent->eflags &= ~ATA_EFLAG_DUBIOUS_XFER; + } + } + + /* has private set_mode? */ + if (ap->ops->set_mode) + rc = ap->ops->set_mode(link, r_failed_dev); + else + rc = ata_do_set_mode(link, r_failed_dev); + + /* if transfer mode has changed, set DUBIOUS_XFER on device */ + ata_link_for_each_dev(dev, link) { + struct ata_eh_context *ehc = &link->eh_context; + u8 saved_xfer_mode = ehc->saved_xfer_mode[dev->devno]; + u8 saved_ncq = !!(ehc->saved_ncq_enabled & (1 << dev->devno)); + + if (dev->xfer_mode != saved_xfer_mode || + ata_ncq_enabled(dev) != saved_ncq) + dev->flags |= ATA_DFLAG_DUBIOUS_XFER; + } + + return rc; +} + static int ata_link_nr_enabled(struct ata_link *link) { struct ata_device *dev; @@ -2375,6 +2526,24 @@ static int ata_eh_skip_recovery(struct ata_link *link) return 1; } +static int ata_eh_schedule_probe(struct ata_device *dev) +{ + struct ata_eh_context *ehc = &dev->link->eh_context; + + if (!(ehc->i.probe_mask & (1 << dev->devno)) || + (ehc->did_probe_mask & (1 << dev->devno))) + return 0; + + ata_eh_detach_dev(dev); + ata_dev_init(dev); + ehc->did_probe_mask |= (1 << dev->devno); + ehc->i.action |= ATA_EH_SOFTRESET; + ehc->saved_xfer_mode[dev->devno] = 0; + ehc->saved_ncq_enabled &= ~(1 << dev->devno); + + return 1; +} + static int ata_eh_handle_dev_fail(struct ata_device *dev, int err) { struct ata_eh_context *ehc = &dev->link->eh_context; @@ -2406,16 +2575,9 @@ static int ata_eh_handle_dev_fail(struct ata_device *dev, int err) if (ata_link_offline(dev->link)) ata_eh_detach_dev(dev); - /* probe if requested */ - if ((ehc->i.probe_mask & (1 << dev->devno)) && - !(ehc->did_probe_mask & (1 << dev->devno))) { - ata_eh_detach_dev(dev); - ata_dev_init(dev); - + /* schedule probe if necessary */ + if (ata_eh_schedule_probe(dev)) ehc->tries[dev->devno] = ATA_EH_DEV_TRIES; - ehc->did_probe_mask |= (1 << dev->devno); - ehc->i.action |= ATA_EH_SOFTRESET; - } return 1; } else { @@ -2492,14 +2654,9 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, if (dev->flags & ATA_DFLAG_DETACH) ata_eh_detach_dev(dev); - if (!ata_dev_enabled(dev) && - ((ehc->i.probe_mask & (1 << dev->devno)) && - !(ehc->did_probe_mask & (1 << dev->devno)))) { - ata_eh_detach_dev(dev); - ata_dev_init(dev); - ehc->did_probe_mask |= (1 << dev->devno); - ehc->i.action |= ATA_EH_SOFTRESET; - } + /* schedule probe if necessary */ + if (!ata_dev_enabled(dev)) + ata_eh_schedule_probe(dev); } } @@ -2747,6 +2904,7 @@ static void ata_eh_handle_port_suspend(struct ata_port *ap) if (ap->ops->port_suspend) rc = ap->ops->port_suspend(ap, ap->pm_mesg); + ata_acpi_set_state(ap, PMSG_SUSPEND); out: /* report result */ spin_lock_irqsave(ap->lock, flags); @@ -2792,6 +2950,8 @@ static void ata_eh_handle_port_resume(struct ata_port *ap) WARN_ON(!(ap->pflags & ATA_PFLAG_SUSPENDED)); + ata_acpi_set_state(ap, PMSG_ON); + if (ap->ops->port_resume) rc = ap->ops->port_resume(ap); diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 14daf48..989b775 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -517,7 +517,7 @@ static struct ata_queued_cmd *ata_scsi_qc_new(struct ata_device *dev, qc->scsicmd = cmd; qc->scsidone = done; - qc->__sg = scsi_sglist(cmd); + qc->sg = scsi_sglist(cmd); qc->n_elem = scsi_sg_count(cmd); } else { cmd->result = (DID_OK << 16) | (QUEUE_FULL << 1); @@ -2210,7 +2210,7 @@ unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf, /* sector size */ ATA_SCSI_RBUF_SET(6, ATA_SECT_SIZE >> 8); - ATA_SCSI_RBUF_SET(7, ATA_SECT_SIZE); + ATA_SCSI_RBUF_SET(7, ATA_SECT_SIZE & 0xff); } else { /* sector count, 64-bit */ ATA_SCSI_RBUF_SET(0, last_lba >> (8 * 7)); @@ -2224,7 +2224,7 @@ unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf, /* sector size */ ATA_SCSI_RBUF_SET(10, ATA_SECT_SIZE >> 8); - ATA_SCSI_RBUF_SET(11, ATA_SECT_SIZE); + ATA_SCSI_RBUF_SET(11, ATA_SECT_SIZE & 0xff); } return 0; @@ -2341,7 +2341,9 @@ static void atapi_request_sense(struct ata_queued_cmd *qc) ata_qc_reinit(qc); - ata_sg_init_one(qc, cmd->sense_buffer, sizeof(cmd->sense_buffer)); + /* setup sg table and init transfer direction */ + sg_init_one(&qc->sgent, cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE); + ata_sg_init(qc, &qc->sgent, 1); qc->dma_dir = DMA_FROM_DEVICE; memset(&qc->cdb, 0, qc->dev->cdb_len); @@ -2352,10 +2354,10 @@ static void atapi_request_sense(struct ata_queued_cmd *qc) qc->tf.command = ATA_CMD_PACKET; if (ata_pio_use_silly(ap)) { - qc->tf.protocol = ATA_PROT_ATAPI_DMA; + qc->tf.protocol = ATAPI_PROT_DMA; qc->tf.feature |= ATAPI_PKT_DMA; } else { - qc->tf.protocol = ATA_PROT_ATAPI; + qc->tf.protocol = ATAPI_PROT_PIO; qc->tf.lbam = SCSI_SENSE_BUFFERSIZE; qc->tf.lbah = 0; } @@ -2526,12 +2528,12 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc) if (using_pio || nodata) { /* no data, or PIO data xfer */ if (nodata) - qc->tf.protocol = ATA_PROT_ATAPI_NODATA; + qc->tf.protocol = ATAPI_PROT_NODATA; else - qc->tf.protocol = ATA_PROT_ATAPI; + qc->tf.protocol = ATAPI_PROT_PIO; } else { /* DMA data xfer */ - qc->tf.protocol = ATA_PROT_ATAPI_DMA; + qc->tf.protocol = ATAPI_PROT_DMA; qc->tf.feature |= ATAPI_PKT_DMA; if (atapi_dmadir && (scmd->sc_data_direction != DMA_TO_DEVICE)) @@ -2690,6 +2692,24 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) if ((tf->protocol = ata_scsi_map_proto(cdb[1])) == ATA_PROT_UNKNOWN) goto invalid_fld; + /* + * Filter TPM commands by default. These provide an + * essentially uncontrolled encrypted "back door" between + * applications and the disk. Set libata.allow_tpm=1 if you + * have a real reason for wanting to use them. This ensures + * that installed software cannot easily mess stuff up without + * user intent. DVR type users will probably ship with this enabled + * for movie content management. + * + * Note that for ATA8 we can issue a DCS change and DCS freeze lock + * for this and should do in future but that it is not sufficient as + * DCS is an optional feature set. Thus we also do the software filter + * so that we comply with the TC consortium stated goal that the user + * can turn off TC features of their system. + */ + if (tf->command >= 0x5C && tf->command <= 0x5F && !libata_allow_tpm) + goto invalid_fld; + /* We may not issue DMA commands if no DMA mode is set */ if (tf->protocol == ATA_PROT_DMA && dev->dma_mode == 0) goto invalid_fld; diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index b7ac80b..97dd8f2 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -147,7 +147,9 @@ void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf) * @tf: ATA taskfile register set for storing input * * Reads ATA taskfile registers for currently-selected device - * into @tf. + * into @tf. Assumes the device has a fully SFF compliant task file + * layout and behaviour. If you device does not (eg has a different + * status method) then you will need to provide a replacement tf_read * * LOCKING: * Inherited from caller. @@ -156,7 +158,7 @@ void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf) { struct ata_ioports *ioaddr = &ap->ioaddr; - tf->command = ata_chk_status(ap); + tf->command = ata_check_status(ap); tf->feature = ioread8(ioaddr->error_addr); tf->nsect = ioread8(ioaddr->nsect_addr); tf->lbal = ioread8(ioaddr->lbal_addr); @@ -415,7 +417,7 @@ void ata_bmdma_drive_eh(struct ata_port *ap, ata_prereset_fn_t prereset, ap->hsm_task_state = HSM_ST_IDLE; if (qc && (qc->tf.protocol == ATA_PROT_DMA || - qc->tf.protocol == ATA_PROT_ATAPI_DMA)) { + qc->tf.protocol == ATAPI_PROT_DMA)) { u8 host_stat; host_stat = ap->ops->bmdma_status(ap); @@ -549,7 +551,7 @@ int ata_pci_init_bmdma(struct ata_host *host) return rc; /* request and iomap DMA region */ - rc = pcim_iomap_regions(pdev, 1 << 4, DRV_NAME); + rc = pcim_iomap_regions(pdev, 1 << 4, dev_driver_string(gdev)); if (rc) { dev_printk(KERN_ERR, gdev, "failed to request/iomap BAR4\n"); return -ENOMEM; @@ -619,7 +621,8 @@ int ata_pci_init_sff_host(struct ata_host *host) continue; } - rc = pcim_iomap_regions(pdev, 0x3 << base, DRV_NAME); + rc = pcim_iomap_regions(pdev, 0x3 << base, + dev_driver_string(gdev)); if (rc) { dev_printk(KERN_WARNING, gdev, "failed to request/iomap BARs for port %d " @@ -739,6 +742,7 @@ int ata_pci_init_one(struct pci_dev *pdev, struct device *dev = &pdev->dev; const struct ata_port_info *pi = NULL; struct ata_host *host = NULL; + const char *drv_name = dev_driver_string(&pdev->dev); u8 mask; int legacy_mode = 0; int i, rc; @@ -811,7 +815,7 @@ int ata_pci_init_one(struct pci_dev *pdev, shouldn't happen on a sane system but robustness is cheap in this case */ rc = devm_request_irq(dev, pdev->irq, pi->port_ops->irq_handler, - IRQF_SHARED, DRV_NAME, host); + IRQF_SHARED, drv_name, host); if (rc) goto err_out; @@ -821,7 +825,7 @@ int ata_pci_init_one(struct pci_dev *pdev, if (!ata_port_is_dummy(host->ports[0])) { rc = devm_request_irq(dev, ATA_PRIMARY_IRQ(pdev), pi->port_ops->irq_handler, - IRQF_SHARED, DRV_NAME, host); + IRQF_SHARED, drv_name, host); if (rc) goto err_out; @@ -832,7 +836,7 @@ int ata_pci_init_one(struct pci_dev *pdev, if (!ata_port_is_dummy(host->ports[1])) { rc = devm_request_irq(dev, ATA_SECONDARY_IRQ(pdev), pi->port_ops->irq_handler, - IRQF_SHARED, DRV_NAME, host); + IRQF_SHARED, drv_name, host); if (rc) goto err_out; diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index bbe59c2..409ffb9 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -60,6 +60,7 @@ extern int atapi_dmadir; extern int atapi_passthru16; extern int libata_fua; extern int libata_noacpi; +extern int libata_allow_tpm; extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev); extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev, u64 block, u32 n_block, unsigned int tf_flags, @@ -85,7 +86,6 @@ extern int ata_dev_configure(struct ata_device *dev); extern int sata_down_spd_limit(struct ata_link *link); extern int sata_set_spd_needed(struct ata_link *link); extern int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel); -extern int ata_set_mode(struct ata_link *link, struct ata_device **r_failed_dev); extern void ata_sg_clean(struct ata_queued_cmd *qc); extern void ata_qc_free(struct ata_queued_cmd *qc); extern void ata_qc_issue(struct ata_queued_cmd *qc); @@ -113,6 +113,7 @@ extern int ata_acpi_on_suspend(struct ata_port *ap); extern void ata_acpi_on_resume(struct ata_port *ap); extern int ata_acpi_on_devcfg(struct ata_device *dev); extern void ata_acpi_on_disable(struct ata_device *dev); +extern void ata_acpi_set_state(struct ata_port *ap, pm_message_t state); #else static inline void ata_acpi_associate_sata_port(struct ata_port *ap) { } static inline void ata_acpi_associate(struct ata_host *host) { } @@ -121,6 +122,8 @@ static inline int ata_acpi_on_suspend(struct ata_port *ap) { return 0; } static inline void ata_acpi_on_resume(struct ata_port *ap) { } static inline int ata_acpi_on_devcfg(struct ata_device *dev) { return 0; } static inline void ata_acpi_on_disable(struct ata_device *dev) { } +static inline void ata_acpi_set_state(struct ata_port *ap, + pm_message_t state) { } #endif /* libata-scsi.c */ @@ -183,6 +186,7 @@ extern void ata_eh_report(struct ata_port *ap); extern int ata_eh_reset(struct ata_link *link, int classify, ata_prereset_fn_t prereset, ata_reset_fn_t softreset, ata_reset_fn_t hardreset, ata_postreset_fn_t postreset); +extern int ata_set_mode(struct ata_link *link, struct ata_device **r_failed_dev); extern int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, ata_reset_fn_t softreset, ata_reset_fn_t hardreset, ata_postreset_fn_t postreset, diff --git a/drivers/ata/pata_acpi.c b/drivers/ata/pata_acpi.c index e4542ab..244098a 100644 --- a/drivers/ata/pata_acpi.c +++ b/drivers/ata/pata_acpi.c @@ -81,17 +81,6 @@ static void pacpi_error_handler(struct ata_port *ap) NULL, ata_std_postreset); } -/* Welcome to ACPI, bring a bucket */ -static const unsigned int pio_cycle[7] = { - 600, 383, 240, 180, 120, 100, 80 -}; -static const unsigned int mwdma_cycle[5] = { - 480, 150, 120, 100, 80 -}; -static const unsigned int udma_cycle[7] = { - 120, 80, 60, 45, 30, 20, 15 -}; - /** * pacpi_discover_modes - filter non ACPI modes * @adev: ATA device @@ -103,56 +92,20 @@ static const unsigned int udma_cycle[7] = { static unsigned long pacpi_discover_modes(struct ata_port *ap, struct ata_device *adev) { - int unit = adev->devno; struct pata_acpi *acpi = ap->private_data; - int i; - u32 t; - unsigned long mask = (0x7f << ATA_SHIFT_UDMA) | (0x7 << ATA_SHIFT_MWDMA) | (0x1F << ATA_SHIFT_PIO); - struct ata_acpi_gtm probe; + unsigned int xfer_mask; probe = acpi->gtm; - /* We always use the 0 slot for crap hardware */ - if (!(probe.flags & 0x10)) - unit = 0; - ata_acpi_gtm(ap, &probe); - /* Start by scanning for PIO modes */ - for (i = 0; i < 7; i++) { - t = probe.drive[unit].pio; - if (t <= pio_cycle[i]) { - mask |= (2 << (ATA_SHIFT_PIO + i)) - 1; - break; - } - } + xfer_mask = ata_acpi_gtm_xfermask(adev, &probe); - /* See if we have MWDMA or UDMA data. We don't bother with MWDMA - if UDMA is availabe as this means the BIOS set UDMA and our - error changedown if it works is UDMA to PIO anyway */ - if (probe.flags & (1 << (2 * unit))) { - /* MWDMA */ - for (i = 0; i < 5; i++) { - t = probe.drive[unit].dma; - if (t <= mwdma_cycle[i]) { - mask |= (2 << (ATA_SHIFT_MWDMA + i)) - 1; - break; - } - } - } else { - /* UDMA */ - for (i = 0; i < 7; i++) { - t = probe.drive[unit].dma; - if (t <= udma_cycle[i]) { - mask |= (2 << (ATA_SHIFT_UDMA + i)) - 1; - break; - } - } - } - if (mask & (0xF8 << ATA_SHIFT_UDMA)) + if (xfer_mask & (0xF8 << ATA_SHIFT_UDMA)) ap->cbl = ATA_CBL_PATA80; - return mask; + + return xfer_mask; } /** @@ -180,12 +133,14 @@ static void pacpi_set_piomode(struct ata_port *ap, struct ata_device *adev) { int unit = adev->devno; struct pata_acpi *acpi = ap->private_data; + const struct ata_timing *t; if (!(acpi->gtm.flags & 0x10)) unit = 0; /* Now stuff the nS values into the structure */ - acpi->gtm.drive[unit].pio = pio_cycle[adev->pio_mode - XFER_PIO_0]; + t = ata_timing_find_mode(adev->pio_mode); + acpi->gtm.drive[unit].pio = t->cycle; ata_acpi_stm(ap, &acpi->gtm); /* See what mode we actually got */ ata_acpi_gtm(ap, &acpi->gtm); @@ -201,16 +156,18 @@ static void pacpi_set_dmamode(struct ata_port *ap, struct ata_device *adev) { int unit = adev->devno; struct pata_acpi *acpi = ap->private_data; + const struct ata_timing *t; if (!(acpi->gtm.flags & 0x10)) unit = 0; /* Now stuff the nS values into the structure */ + t = ata_timing_find_mode(adev->dma_mode); if (adev->dma_mode >= XFER_UDMA_0) { - acpi->gtm.drive[unit].dma = udma_cycle[adev->dma_mode - XFER_UDMA_0]; + acpi->gtm.drive[unit].dma = t->udma; acpi->gtm.flags |= (1 << (2 * unit)); } else { - acpi->gtm.drive[unit].dma = mwdma_cycle[adev->dma_mode - XFER_MW_DMA_0]; + acpi->gtm.drive[unit].dma = t->cycle; acpi->gtm.flags &= ~(1 << (2 * unit)); } ata_acpi_stm(ap, &acpi->gtm); diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c index 8caf9af..7e68edf 100644 --- a/drivers/ata/pata_ali.c +++ b/drivers/ata/pata_ali.c @@ -64,7 +64,7 @@ static int ali_cable_override(struct pci_dev *pdev) if (pdev->subsystem_vendor == 0x10CF && pdev->subsystem_device == 0x10AF) return 1; /* Mitac 8317 (Winbook-A) and relatives */ - if (pdev->subsystem_vendor == 0x1071 && pdev->subsystem_device == 0x8317) + if (pdev->subsystem_vendor == 0x1071 && pdev->subsystem_device == 0x8317) return 1; /* Systems by DMI */ if (dmi_check_system(cable_dmi_table)) diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c index 3cc27b5..761a666 100644 --- a/drivers/ata/pata_amd.c +++ b/drivers/ata/pata_amd.c @@ -220,6 +220,62 @@ static void amd133_set_dmamode(struct ata_port *ap, struct ata_device *adev) timing_setup(ap, adev, 0x40, adev->dma_mode, 4); } +/* Both host-side and drive-side detection results are worthless on NV + * PATAs. Ignore them and just follow what BIOS configured. Both the + * current configuration in PCI config reg and ACPI GTM result are + * cached during driver attach and are consulted to select transfer + * mode. + */ +static unsigned long nv_mode_filter(struct ata_device *dev, + unsigned long xfer_mask) +{ + static const unsigned int udma_mask_map[] = + { ATA_UDMA2, ATA_UDMA1, ATA_UDMA0, 0, + ATA_UDMA3, ATA_UDMA4, ATA_UDMA5, ATA_UDMA6 }; + struct ata_port *ap = dev->link->ap; + char acpi_str[32] = ""; + u32 saved_udma, udma; + const struct ata_acpi_gtm *gtm; + unsigned long bios_limit = 0, acpi_limit = 0, limit; + + /* find out what BIOS configured */ + udma = saved_udma = (unsigned long)ap->host->private_data; + + if (ap->port_no == 0) + udma >>= 16; + if (dev->devno == 0) + udma >>= 8; + + if ((udma & 0xc0) == 0xc0) + bios_limit = ata_pack_xfermask(0, 0, udma_mask_map[udma & 0x7]); + + /* consult ACPI GTM too */ + gtm = ata_acpi_init_gtm(ap); + if (gtm) { + acpi_limit = ata_acpi_gtm_xfermask(dev, gtm); + + snprintf(acpi_str, sizeof(acpi_str), " (%u:%u:0x%x)", + gtm->drive[0].dma, gtm->drive[1].dma, gtm->flags); + } + + /* be optimistic, EH can take care of things if something goes wrong */ + limit = bios_limit | acpi_limit; + + /* If PIO or DMA isn't configured at all, don't limit. Let EH + * handle it. + */ + if (!(limit & ATA_MASK_PIO)) + limit |= ATA_MASK_PIO; + if (!(limit & (ATA_MASK_MWDMA | ATA_MASK_UDMA))) + limit |= ATA_MASK_MWDMA | ATA_MASK_UDMA; + + ata_port_printk(ap, KERN_DEBUG, "nv_mode_filter: 0x%lx&0x%lx->0x%lx, " + "BIOS=0x%lx (0x%x) ACPI=0x%lx%s\n", + xfer_mask, limit, xfer_mask & limit, bios_limit, + saved_udma, acpi_limit, acpi_str); + + return xfer_mask & limit; +} /** * nv_probe_init - cable detection @@ -252,31 +308,6 @@ static void nv_error_handler(struct ata_port *ap) ata_std_postreset); } -static int nv_cable_detect(struct ata_port *ap) -{ - static const u8 bitmask[2] = {0x03, 0x0C}; - struct pci_dev *pdev = to_pci_dev(ap->host->dev); - u8 ata66; - u16 udma; - int cbl; - - pci_read_config_byte(pdev, 0x52, &ata66); - if (ata66 & bitmask[ap->port_no]) - cbl = ATA_CBL_PATA80; - else - cbl = ATA_CBL_PATA40; - - /* We now have to double check because the Nvidia boxes BIOS - doesn't always set the cable bits but does set mode bits */ - pci_read_config_word(pdev, 0x62 - 2 * ap->port_no, &udma); - if ((udma & 0xC4) == 0xC4 || (udma & 0xC400) == 0xC400) - cbl = ATA_CBL_PATA80; - /* And a triple check across suspend/resume with ACPI around */ - if (ata_acpi_cbl_80wire(ap)) - cbl = ATA_CBL_PATA80; - return cbl; -} - /** * nv100_set_piomode - set initial PIO mode data * @ap: ATA interface @@ -314,6 +345,14 @@ static void nv133_set_dmamode(struct ata_port *ap, struct ata_device *adev) timing_setup(ap, adev, 0x50, adev->dma_mode, 4); } +static void nv_host_stop(struct ata_host *host) +{ + u32 udma = (unsigned long)host->private_data; + + /* restore PCI config register 0x60 */ + pci_write_config_dword(to_pci_dev(host->dev), 0x60, udma); +} + static struct scsi_host_template amd_sht = { .module = THIS_MODULE, .name = DRV_NAME, @@ -478,7 +517,8 @@ static struct ata_port_operations nv100_port_ops = { .thaw = ata_bmdma_thaw, .error_handler = nv_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, - .cable_detect = nv_cable_detect, + .cable_detect = ata_cable_ignore, + .mode_filter = nv_mode_filter, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -495,6 +535,7 @@ static struct ata_port_operations nv100_port_ops = { .irq_on = ata_irq_on, .port_start = ata_sff_port_start, + .host_stop = nv_host_stop, }; static struct ata_port_operations nv133_port_ops = { @@ -511,7 +552,8 @@ static struct ata_port_operations nv133_port_ops = { .thaw = ata_bmdma_thaw, .error_handler = nv_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, - .cable_detect = nv_cable_detect, + .cable_detect = ata_cable_ignore, + .mode_filter = nv_mode_filter, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -528,6 +570,7 @@ static struct ata_port_operations nv133_port_ops = { .irq_on = ata_irq_on, .port_start = ata_sff_port_start, + .host_stop = nv_host_stop, }; static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) @@ -614,7 +657,8 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) .port_ops = &amd100_port_ops } }; - const struct ata_port_info *ppi[] = { NULL, NULL }; + struct ata_port_info pi; + const struct ata_port_info *ppi[] = { &pi, NULL }; static int printed_version; int type = id->driver_data; u8 fifo; @@ -628,6 +672,19 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) if (type == 1 && pdev->revision > 0x7) type = 2; + /* Serenade ? */ + if (type == 5 && pdev->subsystem_vendor == PCI_VENDOR_ID_AMD && + pdev->subsystem_device == PCI_DEVICE_ID_AMD_SERENADE) + type = 6; /* UDMA 100 only */ + + /* + * Okay, type is determined now. Apply type-specific workarounds. + */ + pi = info[type]; + + if (type < 3) + ata_pci_clear_simplex(pdev); + /* Check for AMD7411 */ if (type == 3) /* FIFO is broken */ @@ -635,16 +692,17 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) else pci_write_config_byte(pdev, 0x41, fifo | 0xF0); - /* Serenade ? */ - if (type == 5 && pdev->subsystem_vendor == PCI_VENDOR_ID_AMD && - pdev->subsystem_device == PCI_DEVICE_ID_AMD_SERENADE) - type = 6; /* UDMA 100 only */ + /* Cable detection on Nvidia chips doesn't work too well, + * cache BIOS programmed UDMA mode. + */ + if (type == 7 || type == 8) { + u32 udma; - if (type < 3) - ata_pci_clear_simplex(pdev); + pci_read_config_dword(pdev, 0x60, &udma); + pi.private_data = (void *)(unsigned long)udma; + } /* And fire it up */ - ppi[0] = &info[type]; return ata_pci_init_one(pdev, ppi); } diff --git a/drivers/ata/pata_bf54x.c b/drivers/ata/pata_bf54x.c index 7842cc4..a32e3c4 100644 --- a/drivers/ata/pata_bf54x.c +++ b/drivers/ata/pata_bf54x.c @@ -832,6 +832,7 @@ static void bfin_bmdma_setup(struct ata_queued_cmd *qc) { unsigned short config = WDSIZE_16; struct scatterlist *sg; + unsigned int si; pr_debug("in atapi dma setup\n"); /* Program the ATA_CTRL register with dir */ @@ -839,7 +840,7 @@ static void bfin_bmdma_setup(struct ata_queued_cmd *qc) /* fill the ATAPI DMA controller */ set_dma_config(CH_ATAPI_TX, config); set_dma_x_modify(CH_ATAPI_TX, 2); - ata_for_each_sg(sg, qc) { + for_each_sg(qc->sg, sg, qc->n_elem, si) { set_dma_start_addr(CH_ATAPI_TX, sg_dma_address(sg)); set_dma_x_count(CH_ATAPI_TX, sg_dma_len(sg) >> 1); } @@ -848,7 +849,7 @@ static void bfin_bmdma_setup(struct ata_queued_cmd *qc) /* fill the ATAPI DMA controller */ set_dma_config(CH_ATAPI_RX, config); set_dma_x_modify(CH_ATAPI_RX, 2); - ata_for_each_sg(sg, qc) { + for_each_sg(qc->sg, sg, qc->n_elem, si) { set_dma_start_addr(CH_ATAPI_RX, sg_dma_address(sg)); set_dma_x_count(CH_ATAPI_RX, sg_dma_len(sg) >> 1); } @@ -867,6 +868,7 @@ static void bfin_bmdma_start(struct ata_queued_cmd *qc) struct ata_port *ap = qc->ap; void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr; struct scatterlist *sg; + unsigned int si; pr_debug("in atapi dma start\n"); if (!(ap->udma_mask || ap->mwdma_mask)) @@ -881,7 +883,7 @@ static void bfin_bmdma_start(struct ata_queued_cmd *qc) * data cache is enabled. Otherwise, this loop * is an empty loop and optimized out. */ - ata_for_each_sg(sg, qc) { + for_each_sg(qc->sg, sg, qc->n_elem, si) { flush_dcache_range(sg_dma_address(sg), sg_dma_address(sg) + sg_dma_len(sg)); } @@ -910,7 +912,7 @@ static void bfin_bmdma_start(struct ata_queued_cmd *qc) ATAPI_SET_CONTROL(base, ATAPI_GET_CONTROL(base) | TFRCNT_RST); /* Set transfer length to buffer len */ - ata_for_each_sg(sg, qc) { + for_each_sg(qc->sg, sg, qc->n_elem, si) { ATAPI_SET_XFER_LEN(base, (sg_dma_len(sg) >> 1)); } @@ -932,6 +934,7 @@ static void bfin_bmdma_stop(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; struct scatterlist *sg; + unsigned int si; pr_debug("in atapi dma stop\n"); if (!(ap->udma_mask || ap->mwdma_mask)) @@ -950,7 +953,7 @@ static void bfin_bmdma_stop(struct ata_queued_cmd *qc) * data cache is enabled. Otherwise, this loop * is an empty loop and optimized out. */ - ata_for_each_sg(sg, qc) { + for_each_sg(qc->sg, sg, qc->n_elem, si) { invalidate_dcache_range( sg_dma_address(sg), sg_dma_address(sg) @@ -1167,34 +1170,36 @@ static unsigned char bfin_bmdma_status(struct ata_port *ap) * Note: Original code is ata_data_xfer(). */ -static void bfin_data_xfer(struct ata_device *adev, unsigned char *buf, - unsigned int buflen, int write_data) +static unsigned int bfin_data_xfer(struct ata_device *dev, unsigned char *buf, + unsigned int buflen, int rw) { - struct ata_port *ap = adev->link->ap; - unsigned int words = buflen >> 1; - unsigned short *buf16 = (u16 *) buf; + struct ata_port *ap = dev->link->ap; void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr; + unsigned int words = buflen >> 1; + unsigned short *buf16 = (u16 *)buf; /* Transfer multiple of 2 bytes */ - if (write_data) { - write_atapi_data(base, words, buf16); - } else { + if (rw == READ) read_atapi_data(base, words, buf16); - } + else + write_atapi_data(base, words, buf16); /* Transfer trailing 1 byte, if any. */ if (unlikely(buflen & 0x01)) { unsigned short align_buf[1] = { 0 }; unsigned char *trailing_buf = buf + buflen - 1; - if (write_data) { - memcpy(align_buf, trailing_buf, 1); - write_atapi_data(base, 1, align_buf); - } else { + if (rw == READ) { read_atapi_data(base, 1, align_buf); memcpy(trailing_buf, align_buf, 1); + } else { + memcpy(align_buf, trailing_buf, 1); + write_atapi_data(base, 1, align_buf); } + words++; } + + return words << 1; } /** diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c index 33f7f08..d4590f5 100644 --- a/drivers/ata/pata_cs5520.c +++ b/drivers/ata/pata_cs5520.c @@ -198,7 +198,7 @@ static int __devinit cs5520_init_one(struct pci_dev *pdev, const struct pci_devi }; const struct ata_port_info *ppi[2]; u8 pcicfg; - void *iomap[5]; + void __iomem *iomap[5]; struct ata_host *host; struct ata_ioports *ioaddr; int i, rc; diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c index c79f066..68eb349 100644 --- a/drivers/ata/pata_hpt37x.c +++ b/drivers/ata/pata_hpt37x.c @@ -847,15 +847,16 @@ static u32 hpt374_read_freq(struct pci_dev *pdev) u32 freq; unsigned long io_base = pci_resource_start(pdev, 4); if (PCI_FUNC(pdev->devfn) & 1) { - struct pci_dev *pdev_0 = pci_get_slot(pdev->bus, pdev->devfn - 1); + struct pci_dev *pdev_0; + + pdev_0 = pci_get_slot(pdev->bus, pdev->devfn - 1); /* Someone hot plugged the controller on us ? */ if (pdev_0 == NULL) return 0; io_base = pci_resource_start(pdev_0, 4); freq = inl(io_base + 0x90); pci_dev_put(pdev_0); - } - else + } else freq = inl(io_base + 0x90); return freq; } diff --git a/drivers/ata/pata_icside.c b/drivers/ata/pata_icside.c index 842fe08..5b8586d 100644 --- a/drivers/ata/pata_icside.c +++ b/drivers/ata/pata_icside.c @@ -224,6 +224,7 @@ static void pata_icside_bmdma_setup(struct ata_queued_cmd *qc) struct pata_icside_state *state = ap->host->private_data; struct scatterlist *sg, *rsg = state->sg; unsigned int write = qc->tf.flags & ATA_TFLAG_WRITE; + unsigned int si; /* * We are simplex; BUG if we try to fiddle with DMA @@ -234,7 +235,7 @@ static void pata_icside_bmdma_setup(struct ata_queued_cmd *qc) /* * Copy ATAs scattered sg list into a contiguous array of sg */ - ata_for_each_sg(sg, qc) { + for_each_sg(qc->sg, sg, qc->n_elem, si) { memcpy(rsg, sg, sizeof(*sg)); rsg++; } diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c index ca9aae0..109ddd4 100644 --- a/drivers/ata/pata_it821x.c +++ b/drivers/ata/pata_it821x.c @@ -430,7 +430,7 @@ static unsigned int it821x_smart_qc_issue_prot(struct ata_queued_cmd *qc) return ata_qc_issue_prot(qc); } printk(KERN_DEBUG "it821x: can't process command 0x%02X\n", qc->tf.command); - return AC_ERR_INVALID; + return AC_ERR_DEV; } /** @@ -516,6 +516,37 @@ static void it821x_dev_config(struct ata_device *adev) printk("(%dK stripe)", adev->id[146]); printk(".\n"); } + /* This is a controller firmware triggered funny, don't + report the drive faulty! */ + adev->horkage &= ~ATA_HORKAGE_DIAGNOSTIC; +} + +/** + * it821x_ident_hack - Hack identify data up + * @ap: Port + * + * Walk the devices on this firmware driven port and slightly + * mash the identify data to stop us and common tools trying to + * use features not firmware supported. The firmware itself does + * some masking (eg SMART) but not enough. + * + * This is a bit of an abuse of the cable method, but it is the + * only method called at the right time. We could modify the libata + * core specifically for ident hacking but while we have one offender + * it seems better to keep the fallout localised. + */ + +static int it821x_ident_hack(struct ata_port *ap) +{ + struct ata_device *adev; + ata_link_for_each_dev(adev, &ap->link) { + if (ata_dev_enabled(adev)) { + adev->id[84] &= ~(1 << 6); /* No FUA */ + adev->id[85] &= ~(1 << 10); /* No HPA */ + adev->id[76] = 0; /* No NCQ/AN etc */ + } + } + return ata_cable_unknown(ap); } @@ -634,7 +665,7 @@ static struct ata_port_operations it821x_smart_port_ops = { .thaw = ata_bmdma_thaw, .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, - .cable_detect = ata_cable_unknown, + .cable_detect = it821x_ident_hack, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c index 120b5bf..030878f 100644 --- a/drivers/ata/pata_ixp4xx_cf.c +++ b/drivers/ata/pata_ixp4xx_cf.c @@ -42,13 +42,13 @@ static int ixp4xx_set_mode(struct ata_link *link, struct ata_device **error) return 0; } -static void ixp4xx_mmio_data_xfer(struct ata_device *adev, unsigned char *buf, - unsigned int buflen, int write_data) +static unsigned int ixp4xx_mmio_data_xfer(struct ata_device *dev, + unsigned char *buf, unsigned int buflen, int rw) { unsigned int i; unsigned int words = buflen >> 1; u16 *buf16 = (u16 *) buf; - struct ata_port *ap = adev->link->ap; + struct ata_port *ap = dev->link->ap; void __iomem *mmio = ap->ioaddr.data_addr; struct ixp4xx_pata_data *data = ap->host->dev->platform_data; @@ -59,30 +59,32 @@ static void ixp4xx_mmio_data_xfer(struct ata_device *adev, unsigned char *buf, udelay(100); /* Transfer multiple of 2 bytes */ - if (write_data) { - for (i = 0; i < words; i++) - writew(buf16[i], mmio); - } else { + if (rw == READ) for (i = 0; i < words; i++) buf16[i] = readw(mmio); - } + else + for (i = 0; i < words; i++) + writew(buf16[i], mmio); /* Transfer trailing 1 byte, if any. */ if (unlikely(buflen & 0x01)) { u16 align_buf[1] = { 0 }; unsigned char *trailing_buf = buf + buflen - 1; - if (write_data) { - memcpy(align_buf, trailing_buf, 1); - writew(align_buf[0], mmio); - } else { + if (rw == READ) { align_buf[0] = readw(mmio); memcpy(trailing_buf, align_buf, 1); + } else { + memcpy(align_buf, trailing_buf, 1); + writew(align_buf[0], mmio); } + words++; } udelay(100); *data->cs0_cfg |= 0x01; + + return words << 1; } static struct scsi_host_template ixp4xx_sht = { diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c index 17159b5..c4a939b 100644 --- a/drivers/ata/pata_legacy.c +++ b/drivers/ata/pata_legacy.c @@ -68,8 +68,9 @@ #define NR_HOST 6 -static int legacy_port[NR_HOST] = { 0x1f0, 0x170, 0x1e8, 0x168, 0x1e0, 0x160 }; -static int legacy_irq[NR_HOST] = { 14, 15, 11, 10, 8, 12 }; +static int all; +module_param(all, int, 0444); +MODULE_PARM_DESC(all, "Grab all legacy port devices, even if PCI(0=off, 1=on)"); struct legacy_data { unsigned long timing; @@ -80,21 +81,103 @@ struct legacy_data { }; +enum controller { + BIOS = 0, + SNOOP = 1, + PDC20230 = 2, + HT6560A = 3, + HT6560B = 4, + OPTI611A = 5, + OPTI46X = 6, + QDI6500 = 7, + QDI6580 = 8, + QDI6580DP = 9, /* Dual channel mode is different */ + + UNKNOWN = -1 +}; + + +struct legacy_probe { + unsigned char *name; + unsigned long port; + unsigned int irq; + unsigned int slot; + enum controller type; + unsigned long private; +}; + +struct legacy_controller { + const char *name; + struct ata_port_operations *ops; + unsigned int pio_mask; + unsigned int flags; + int (*setup)(struct legacy_probe *probe, struct legacy_data *data); +}; + +static int legacy_port[NR_HOST] = { 0x1f0, 0x170, 0x1e8, 0x168, 0x1e0, 0x160 }; + +static struct legacy_probe probe_list[NR_HOST]; static struct legacy_data legacy_data[NR_HOST]; static struct ata_host *legacy_host[NR_HOST]; static int nr_legacy_host; -static int probe_all; /* Set to check all ISA port ranges */ -static int ht6560a; /* HT 6560A on primary 1, secondary 2, both 3 */ -static int ht6560b; /* HT 6560A on primary 1, secondary 2, both 3 */ -static int opti82c611a; /* Opti82c611A on primary 1, secondary 2, both 3 */ -static int opti82c46x; /* Opti 82c465MV present (pri/sec autodetect) */ -static int autospeed; /* Chip present which snoops speed changes */ -static int pio_mask = 0x1F; /* PIO range for autospeed devices */ +static int probe_all; /* Set to check all ISA port ranges */ +static int ht6560a; /* HT 6560A on primary 1, second 2, both 3 */ +static int ht6560b; /* HT 6560A on primary 1, second 2, both 3 */ +static int opti82c611a; /* Opti82c611A on primary 1, sec 2, both 3 */ +static int opti82c46x; /* Opti 82c465MV present(pri/sec autodetect) */ +static int qdi; /* Set to probe QDI controllers */ +static int autospeed; /* Chip present which snoops speed changes */ +static int pio_mask = 0x1F; /* PIO range for autospeed devices */ static int iordy_mask = 0xFFFFFFFF; /* Use iordy if available */ /** + * legacy_probe_add - Add interface to probe list + * @port: Controller port + * @irq: IRQ number + * @type: Controller type + * @private: Controller specific info + * + * Add an entry into the probe list for ATA controllers. This is used + * to add the default ISA slots and then to build up the table + * further according to other ISA/VLB/Weird device scans + * + * An I/O port list is used to keep ordering stable and sane, as we + * don't have any good way to talk about ordering otherwise + */ + +static int legacy_probe_add(unsigned long port, unsigned int irq, + enum controller type, unsigned long private) +{ + struct legacy_probe *lp = &probe_list[0]; + int i; + struct legacy_probe *free = NULL; + + for (i = 0; i < NR_HOST; i++) { + if (lp->port == 0 && free == NULL) + free = lp; + /* Matching port, or the correct slot for ordering */ + if (lp->port == port || legacy_port[i] == port) { + free = lp; + break; + } + lp++; + } + if (free == NULL) { + printk(KERN_ERR "pata_legacy: Too many interfaces.\n"); + return -1; + } + /* Fill in the entry for later probing */ + free->port = port; + free->irq = irq; + free->type = type; + free->private = private; + return 0; +} + + +/** * legacy_set_mode - mode setting * @link: IDE link * @unused: Device that failed when error is returned @@ -113,7 +196,8 @@ static int legacy_set_mode(struct ata_link *link, struct ata_device **unused) ata_link_for_each_dev(dev, link) { if (ata_dev_enabled(dev)) { - ata_dev_printk(dev, KERN_INFO, "configured for PIO\n"); + ata_dev_printk(dev, KERN_INFO, + "configured for PIO\n"); dev->pio_mode = XFER_PIO_0; dev->xfer_mode = XFER_PIO_0; dev->xfer_shift = ATA_SHIFT_PIO; @@ -171,7 +255,7 @@ static struct ata_port_operations simple_port_ops = { .irq_clear = ata_bmdma_irq_clear, .irq_on = ata_irq_on, - .port_start = ata_port_start, + .port_start = ata_sff_port_start, }; static struct ata_port_operations legacy_port_ops = { @@ -198,15 +282,16 @@ static struct ata_port_operations legacy_port_ops = { .irq_clear = ata_bmdma_irq_clear, .irq_on = ata_irq_on, - .port_start = ata_port_start, + .port_start = ata_sff_port_start, }; /* * Promise 20230C and 20620 support * - * This controller supports PIO0 to PIO2. We set PIO timings conservatively to - * allow for 50MHz Vesa Local Bus. The 20620 DMA support is weird being DMA to - * controller and PIO'd to the host and not supported. + * This controller supports PIO0 to PIO2. We set PIO timings + * conservatively to allow for 50MHz Vesa Local Bus. The 20620 DMA + * support is weird being DMA to controller and PIO'd to the host + * and not supported. */ static void pdc20230_set_piomode(struct ata_port *ap, struct ata_device *adev) @@ -221,8 +306,7 @@ static void pdc20230_set_piomode(struct ata_port *ap, struct ata_device *adev) local_irq_save(flags); /* Unlock the control interface */ - do - { + do { inb(0x1F5); outb(inb(0x1F2) | 0x80, 0x1F2); inb(0x1F2); @@ -231,7 +315,7 @@ static void pdc20230_set_piomode(struct ata_port *ap, struct ata_device *adev) inb(0x1F2); inb(0x1F2); } - while((inb(0x1F2) & 0x80) && --tries); + while ((inb(0x1F2) & 0x80) && --tries); local_irq_restore(flags); @@ -249,13 +333,14 @@ static void pdc20230_set_piomode(struct ata_port *ap, struct ata_device *adev) } -static void pdc_data_xfer_vlb(struct ata_device *adev, unsigned char *buf, unsigned int buflen, int write_data) +static unsigned int pdc_data_xfer_vlb(struct ata_device *dev, + unsigned char *buf, unsigned int buflen, int rw) { - struct ata_port *ap = adev->link->ap; - int slop = buflen & 3; - unsigned long flags; + if (ata_id_has_dword_io(dev->id)) { + struct ata_port *ap = dev->link->ap; + int slop = buflen & 3; + unsigned long flags; - if (ata_id_has_dword_io(adev->id)) { local_irq_save(flags); /* Perform the 32bit I/O synchronization sequence */ @@ -264,26 +349,27 @@ static void pdc_data_xfer_vlb(struct ata_device *adev, unsigned char *buf, unsig ioread8(ap->ioaddr.nsect_addr); /* Now the data */ - - if (write_data) - iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); - else + if (rw == READ) ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); + else + iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); if (unlikely(slop)) { - __le32 pad = 0; - if (write_data) { - memcpy(&pad, buf + buflen - slop, slop); - iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr); - } else { + u32 pad; + if (rw == READ) { pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr)); memcpy(buf + buflen - slop, &pad, slop); + } else { + memcpy(&pad, buf + buflen - slop, slop); + iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr); } + buflen += 4 - slop; } local_irq_restore(flags); - } - else - ata_data_xfer_noirq(adev, buf, buflen, write_data); + } else + buflen = ata_data_xfer_noirq(dev, buf, buflen, rw); + + return buflen; } static struct ata_port_operations pdc20230_port_ops = { @@ -310,14 +396,14 @@ static struct ata_port_operations pdc20230_port_ops = { .irq_clear = ata_bmdma_irq_clear, .irq_on = ata_irq_on, - .port_start = ata_port_start, + .port_start = ata_sff_port_start, }; /* * Holtek 6560A support * - * This controller supports PIO0 to PIO2 (no IORDY even though higher timings - * can be loaded). + * This controller supports PIO0 to PIO2 (no IORDY even though higher + * timings can be loaded). */ static void ht6560a_set_piomode(struct ata_port *ap, struct ata_device *adev) @@ -364,14 +450,14 @@ static struct ata_port_operations ht6560a_port_ops = { .irq_clear = ata_bmdma_irq_clear, .irq_on = ata_irq_on, - .port_start = ata_port_start, + .port_start = ata_sff_port_start, }; /* * Holtek 6560B support * - * This controller supports PIO0 to PIO4. We honour the BIOS/jumper FIFO setting - * unless we see an ATAPI device in which case we force it off. + * This controller supports PIO0 to PIO4. We honour the BIOS/jumper FIFO + * setting unless we see an ATAPI device in which case we force it off. * * FIXME: need to implement 2nd channel support. */ @@ -398,7 +484,7 @@ static void ht6560b_set_piomode(struct ata_port *ap, struct ata_device *adev) if (adev->class != ATA_DEV_ATA) { u8 rconf = inb(0x3E6); if (rconf & 0x24) { - rconf &= ~ 0x24; + rconf &= ~0x24; outb(rconf, 0x3E6); } } @@ -423,13 +509,13 @@ static struct ata_port_operations ht6560b_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - .data_xfer = ata_data_xfer, /* FIXME: Check 32bit and noirq */ + .data_xfer = ata_data_xfer, /* FIXME: Check 32bit and noirq */ .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, .irq_on = ata_irq_on, - .port_start = ata_port_start, + .port_start = ata_sff_port_start, }; /* @@ -462,7 +548,8 @@ static u8 opti_syscfg(u8 reg) * This controller supports PIO0 to PIO3. */ -static void opti82c611a_set_piomode(struct ata_port *ap, struct ata_device *adev) +static void opti82c611a_set_piomode(struct ata_port *ap, + struct ata_device *adev) { u8 active, recover, setup; struct ata_timing t; @@ -549,7 +636,7 @@ static struct ata_port_operations opti82c611a_port_ops = { .irq_clear = ata_bmdma_irq_clear, .irq_on = ata_irq_on, - .port_start = ata_port_start, + .port_start = ata_sff_port_start, }; /* @@ -681,77 +768,282 @@ static struct ata_port_operations opti82c46x_port_ops = { .irq_clear = ata_bmdma_irq_clear, .irq_on = ata_irq_on, - .port_start = ata_port_start, + .port_start = ata_sff_port_start, }; +static void qdi6500_set_piomode(struct ata_port *ap, struct ata_device *adev) +{ + struct ata_timing t; + struct legacy_data *qdi = ap->host->private_data; + int active, recovery; + u8 timing; + + /* Get the timing data in cycles */ + ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000); + + if (qdi->fast) { + active = 8 - FIT(t.active, 1, 8); + recovery = 18 - FIT(t.recover, 3, 18); + } else { + active = 9 - FIT(t.active, 2, 9); + recovery = 15 - FIT(t.recover, 0, 15); + } + timing = (recovery << 4) | active | 0x08; + + qdi->clock[adev->devno] = timing; + + outb(timing, qdi->timing); +} /** - * legacy_init_one - attach a legacy interface - * @port: port number - * @io: I/O port start - * @ctrl: control port + * qdi6580dp_set_piomode - PIO setup for dual channel + * @ap: Port + * @adev: Device * @irq: interrupt line * - * Register an ISA bus IDE interface. Such interfaces are PIO and we - * assume do not support IRQ sharing. + * In dual channel mode the 6580 has one clock per channel and we have + * to software clockswitch in qc_issue_prot. */ -static __init int legacy_init_one(int port, unsigned long io, unsigned long ctrl, int irq) +static void qdi6580dp_set_piomode(struct ata_port *ap, struct ata_device *adev) { - struct legacy_data *ld = &legacy_data[nr_legacy_host]; - struct ata_host *host; - struct ata_port *ap; - struct platform_device *pdev; - struct ata_port_operations *ops = &legacy_port_ops; - void __iomem *io_addr, *ctrl_addr; - int pio_modes = pio_mask; - u32 mask = (1 << port); - u32 iordy = (iordy_mask & mask) ? 0: ATA_FLAG_NO_IORDY; - int ret; + struct ata_timing t; + struct legacy_data *qdi = ap->host->private_data; + int active, recovery; + u8 timing; - pdev = platform_device_register_simple(DRV_NAME, nr_legacy_host, NULL, 0); - if (IS_ERR(pdev)) - return PTR_ERR(pdev); + /* Get the timing data in cycles */ + ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000); + + if (qdi->fast) { + active = 8 - FIT(t.active, 1, 8); + recovery = 18 - FIT(t.recover, 3, 18); + } else { + active = 9 - FIT(t.active, 2, 9); + recovery = 15 - FIT(t.recover, 0, 15); + } + timing = (recovery << 4) | active | 0x08; - ret = -EBUSY; - if (devm_request_region(&pdev->dev, io, 8, "pata_legacy") == NULL || - devm_request_region(&pdev->dev, ctrl, 1, "pata_legacy") == NULL) - goto fail; + qdi->clock[adev->devno] = timing; - ret = -ENOMEM; - io_addr = devm_ioport_map(&pdev->dev, io, 8); - ctrl_addr = devm_ioport_map(&pdev->dev, ctrl, 1); - if (!io_addr || !ctrl_addr) - goto fail; + outb(timing, qdi->timing + 2 * ap->port_no); + /* Clear the FIFO */ + if (adev->class != ATA_DEV_ATA) + outb(0x5F, qdi->timing + 3); +} - if (ht6560a & mask) { - ops = &ht6560a_port_ops; - pio_modes = 0x07; - iordy = ATA_FLAG_NO_IORDY; - } - if (ht6560b & mask) { - ops = &ht6560b_port_ops; - pio_modes = 0x1F; - } - if (opti82c611a & mask) { - ops = &opti82c611a_port_ops; - pio_modes = 0x0F; +/** + * qdi6580_set_piomode - PIO setup for single channel + * @ap: Port + * @adev: Device + * + * In single channel mode the 6580 has one clock per device and we can + * avoid the requirement to clock switch. We also have to load the timing + * into the right clock according to whether we are master or slave. + */ + +static void qdi6580_set_piomode(struct ata_port *ap, struct ata_device *adev) +{ + struct ata_timing t; + struct legacy_data *qdi = ap->host->private_data; + int active, recovery; + u8 timing; + + /* Get the timing data in cycles */ + ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000); + + if (qdi->fast) { + active = 8 - FIT(t.active, 1, 8); + recovery = 18 - FIT(t.recover, 3, 18); + } else { + active = 9 - FIT(t.active, 2, 9); + recovery = 15 - FIT(t.recover, 0, 15); } - if (opti82c46x & mask) { - ops = &opti82c46x_port_ops; - pio_modes = 0x0F; + timing = (recovery << 4) | active | 0x08; + qdi->clock[adev->devno] = timing; + outb(timing, qdi->timing + 2 * adev->devno); + /* Clear the FIFO */ + if (adev->class != ATA_DEV_ATA) + outb(0x5F, qdi->timing + 3); +} + +/** + * qdi_qc_issue_prot - command issue + * @qc: command pending + * + * Called when the libata layer is about to issue a command. We wrap + * this interface so that we can load the correct ATA timings. + */ + +static unsigned int qdi_qc_issue_prot(struct ata_queued_cmd *qc) +{ + struct ata_port *ap = qc->ap; + struct ata_device *adev = qc->dev; + struct legacy_data *qdi = ap->host->private_data; + + if (qdi->clock[adev->devno] != qdi->last) { + if (adev->pio_mode) { + qdi->last = qdi->clock[adev->devno]; + outb(qdi->clock[adev->devno], qdi->timing + + 2 * ap->port_no); + } } + return ata_qc_issue_prot(qc); +} - /* Probe for automatically detectable controllers */ +/* For the 6580 can we flip the FIFO on/off at this point ? */ - if (io == 0x1F0 && ops == &legacy_port_ops) { - unsigned long flags; +static unsigned int qdi_data_xfer(struct ata_device *adev, unsigned char *buf, + unsigned int buflen, int rw) +{ + struct ata_port *ap = adev->link->ap; + int slop = buflen & 3; - local_irq_save(flags); + if (ata_id_has_dword_io(adev->id)) { + if (rw == WRITE) + iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); + else + ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); + + if (unlikely(slop)) { + u32 pad; + if (rw == WRITE) { + memcpy(&pad, buf + buflen - slop, slop); + pad = le32_to_cpu(pad); + iowrite32(pad, ap->ioaddr.data_addr); + } else { + pad = ioread32(ap->ioaddr.data_addr); + pad = cpu_to_le32(pad); + memcpy(buf + buflen - slop, &pad, slop); + } + } + return (buflen + 3) & ~3; + } else + return ata_data_xfer(adev, buf, buflen, rw); +} + +static struct ata_port_operations qdi6500_port_ops = { + .set_piomode = qdi6500_set_piomode, + + .tf_load = ata_tf_load, + .tf_read = ata_tf_read, + .check_status = ata_check_status, + .exec_command = ata_exec_command, + .dev_select = ata_std_dev_select, + + .freeze = ata_bmdma_freeze, + .thaw = ata_bmdma_thaw, + .error_handler = ata_bmdma_error_handler, + .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, + + .qc_prep = ata_qc_prep, + .qc_issue = qdi_qc_issue_prot, + .data_xfer = qdi_data_xfer, + + .irq_handler = ata_interrupt, + .irq_clear = ata_bmdma_irq_clear, + .irq_on = ata_irq_on, + + .port_start = ata_sff_port_start, +}; + +static struct ata_port_operations qdi6580_port_ops = { + .set_piomode = qdi6580_set_piomode, + + .tf_load = ata_tf_load, + .tf_read = ata_tf_read, + .check_status = ata_check_status, + .exec_command = ata_exec_command, + .dev_select = ata_std_dev_select, + + .freeze = ata_bmdma_freeze, + .thaw = ata_bmdma_thaw, + .error_handler = ata_bmdma_error_handler, + .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, + + .qc_prep = ata_qc_prep, + .qc_issue = ata_qc_issue_prot, + + .data_xfer = qdi_data_xfer, + + .irq_handler = ata_interrupt, + .irq_clear = ata_bmdma_irq_clear, + .irq_on = ata_irq_on, + + .port_start = ata_sff_port_start, +}; + +static struct ata_port_operations qdi6580dp_port_ops = { + .set_piomode = qdi6580dp_set_piomode, + + .tf_load = ata_tf_load, + .tf_read = ata_tf_read, + .check_status = ata_check_status, + .exec_command = ata_exec_command, + .dev_select = ata_std_dev_select, + + .freeze = ata_bmdma_freeze, + .thaw = ata_bmdma_thaw, + .error_handler = ata_bmdma_error_handler, + .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, + + .qc_prep = ata_qc_prep, + .qc_issue = qdi_qc_issue_prot, + + .data_xfer = qdi_data_xfer, + + .irq_handler = ata_interrupt, + .irq_clear = ata_bmdma_irq_clear, + .irq_on = ata_irq_on, + + .port_start = ata_sff_port_start, +}; + +static struct legacy_controller controllers[] = { + {"BIOS", &legacy_port_ops, 0x1F, + ATA_FLAG_NO_IORDY, NULL }, + {"Snooping", &simple_port_ops, 0x1F, + 0 , NULL }, + {"PDC20230", &pdc20230_port_ops, 0x7, + ATA_FLAG_NO_IORDY, NULL }, + {"HT6560A", &ht6560a_port_ops, 0x07, + ATA_FLAG_NO_IORDY, NULL }, + {"HT6560B", &ht6560b_port_ops, 0x1F, + ATA_FLAG_NO_IORDY, NULL }, + {"OPTI82C611A", &opti82c611a_port_ops, 0x0F, + 0 , NULL }, + {"OPTI82C46X", &opti82c46x_port_ops, 0x0F, + 0 , NULL }, + {"QDI6500", &qdi6500_port_ops, 0x07, + ATA_FLAG_NO_IORDY, NULL }, + {"QDI6580", &qdi6580_port_ops, 0x1F, + 0 , NULL }, + {"QDI6580DP", &qdi6580dp_port_ops, 0x1F, + 0 , NULL } +}; + +/** + * probe_chip_type - Discover controller + * @probe: Probe entry to check + * + * Probe an ATA port and identify the type of controller. We don't + * check if the controller appears to be driveless at this point. + */ + +static int probe_chip_type(struct legacy_probe *probe) +{ + int mask = 1 << probe->slot; + + if (probe->port == 0x1F0) { + unsigned long flags; + local_irq_save(flags); /* Probes */ - inb(0x1F5); outb(inb(0x1F2) | 0x80, 0x1F2); + inb(0x1F5); inb(0x1F2); inb(0x3F6); inb(0x3F6); @@ -760,29 +1052,83 @@ static __init int legacy_init_one(int port, unsigned long io, unsigned long ctrl if ((inb(0x1F2) & 0x80) == 0) { /* PDC20230c or 20630 ? */ - printk(KERN_INFO "PDC20230-C/20630 VLB ATA controller detected.\n"); - pio_modes = 0x07; - ops = &pdc20230_port_ops; - iordy = ATA_FLAG_NO_IORDY; + printk(KERN_INFO "PDC20230-C/20630 VLB ATA controller" + " detected.\n"); udelay(100); inb(0x1F5); + local_irq_restore(flags); + return PDC20230; } else { outb(0x55, 0x1F2); inb(0x1F2); inb(0x1F2); - if (inb(0x1F2) == 0x00) { - printk(KERN_INFO "PDC20230-B VLB ATA controller detected.\n"); - } + if (inb(0x1F2) == 0x00) + printk(KERN_INFO "PDC20230-B VLB ATA " + "controller detected.\n"); + local_irq_restore(flags); + return BIOS; } local_irq_restore(flags); } + if (ht6560a & mask) + return HT6560A; + if (ht6560b & mask) + return HT6560B; + if (opti82c611a & mask) + return OPTI611A; + if (opti82c46x & mask) + return OPTI46X; + if (autospeed & mask) + return SNOOP; + return BIOS; +} + + +/** + * legacy_init_one - attach a legacy interface + * @pl: probe record + * + * Register an ISA bus IDE interface. Such interfaces are PIO and we + * assume do not support IRQ sharing. + */ + +static __init int legacy_init_one(struct legacy_probe *probe) +{ + struct legacy_controller *controller = &controllers[probe->type]; + int pio_modes = controller->pio_mask; + unsigned long io = probe->port; + u32 mask = (1 << probe->slot); + struct ata_port_operations *ops = controller->ops; + struct legacy_data *ld = &legacy_data[probe->slot]; + struct ata_host *host = NULL; + struct ata_port *ap; + struct platform_device *pdev; + struct ata_device *dev; + void __iomem *io_addr, *ctrl_addr; + u32 iordy = (iordy_mask & mask) ? 0: ATA_FLAG_NO_IORDY; + int ret; + + iordy |= controller->flags; + + pdev = platform_device_register_simple(DRV_NAME, probe->slot, NULL, 0); + if (IS_ERR(pdev)) + return PTR_ERR(pdev); - /* Chip does mode setting by command snooping */ - if (ops == &legacy_port_ops && (autospeed & mask)) - ops = &simple_port_ops; + ret = -EBUSY; + if (devm_request_region(&pdev->dev, io, 8, "pata_legacy") == NULL || + devm_request_region(&pdev->dev, io + 0x0206, 1, + "pata_legacy") == NULL) + goto fail; ret = -ENOMEM; + io_addr = devm_ioport_map(&pdev->dev, io, 8); + ctrl_addr = devm_ioport_map(&pdev->dev, io + 0x0206, 1); + if (!io_addr || !ctrl_addr) + goto fail; + if (controller->setup) + if (controller->setup(probe, ld) < 0) + goto fail; host = ata_host_alloc(&pdev->dev, 1); if (!host) goto fail; @@ -797,17 +1143,30 @@ static __init int legacy_init_one(int port, unsigned long io, unsigned long ctrl ata_std_ports(&ap->ioaddr); ap->private_data = ld; - ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx", io, ctrl); + ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx", io, io + 0x0206); - ret = ata_host_activate(host, irq, ata_interrupt, 0, &legacy_sht); + ret = ata_host_activate(host, probe->irq, ata_interrupt, 0, + &legacy_sht); if (ret) goto fail; - - legacy_host[nr_legacy_host++] = dev_get_drvdata(&pdev->dev); ld->platform_dev = pdev; - return 0; + /* Nothing found means we drop the port as its probably not there */ + + ret = -ENODEV; + ata_link_for_each_dev(dev, &ap->link) { + if (!ata_dev_absent(dev)) { + legacy_host[probe->slot] = host; + ld->platform_dev = pdev; + return 0; + } + } fail: + if (host) + ata_host_detach(host); + /* FIXME: use devm for this */ + if (ld->timing) + release_region(ld->timing, 2); platform_device_unregister(pdev); return ret; } @@ -818,13 +1177,15 @@ fail: * @master: set this if we find an ATA master * @master: set this if we find an ATA secondary * - * A small number of vendors implemented early PCI ATA interfaces on bridge logic - * without the ATA interface being PCI visible. Where we have a matching PCI driver - * we must skip the relevant device here. If we don't know about it then the legacy - * driver is the right driver anyway. + * A small number of vendors implemented early PCI ATA interfaces + * on bridge logic without the ATA interface being PCI visible. + * Where we have a matching PCI driver we must skip the relevant + * device here. If we don't know about it then the legacy driver + * is the right driver anyway. */ -static void legacy_check_special_cases(struct pci_dev *p, int *primary, int *secondary) +static void legacy_check_special_cases(struct pci_dev *p, int *primary, + int *secondary) { /* Cyrix CS5510 pre SFF MWDMA ATA on the bridge */ if (p->vendor == 0x1078 && p->device == 0x0000) { @@ -840,7 +1201,8 @@ static void legacy_check_special_cases(struct pci_dev *p, int *primary, int *sec if (p->vendor == 0x8086 && p->device == 0x1234) { u16 r; pci_read_config_word(p, 0x6C, &r); - if (r & 0x8000) { /* ATA port enabled */ + if (r & 0x8000) { + /* ATA port enabled */ if (r & 0x4000) *secondary = 1; else @@ -850,6 +1212,117 @@ static void legacy_check_special_cases(struct pci_dev *p, int *primary, int *sec } } +static __init void probe_opti_vlb(void) +{ + /* If an OPTI 82C46X is present find out where the channels are */ + static const char *optis[4] = { + "3/463MV", "5MV", + "5MVA", "5MVB" + }; + u8 chans = 1; + u8 ctrl = (opti_syscfg(0x30) & 0xC0) >> 6; + + opti82c46x = 3; /* Assume master and slave first */ + printk(KERN_INFO DRV_NAME ": Opti 82C46%s chipset support.\n", + optis[ctrl]); + if (ctrl == 3) + chans = (opti_syscfg(0x3F) & 0x20) ? 2 : 1; + ctrl = opti_syscfg(0xAC); + /* Check enabled and this port is the 465MV port. On the + MVB we may have two channels */ + if (ctrl & 8) { + if (chans == 2) { + legacy_probe_add(0x1F0, 14, OPTI46X, 0); + legacy_probe_add(0x170, 15, OPTI46X, 0); + } + if (ctrl & 4) + legacy_probe_add(0x170, 15, OPTI46X, 0); + else + legacy_probe_add(0x1F0, 14, OPTI46X, 0); + } else + legacy_probe_add(0x1F0, 14, OPTI46X, 0); +} + +static __init void qdi65_identify_port(u8 r, u8 res, unsigned long port) +{ + static const unsigned long ide_port[2] = { 0x170, 0x1F0 }; + /* Check card type */ + if ((r & 0xF0) == 0xC0) { + /* QD6500: single channel */ + if (r & 8) { + /* Disabled ? */ + release_region(port, 2); + return; + } + legacy_probe_add(ide_port[r & 0x01], 14 + (r & 0x01), + QDI6500, port); + } + if (((r & 0xF0) == 0xA0) || (r & 0xF0) == 0x50) { + /* QD6580: dual channel */ + if (!request_region(port + 2 , 2, "pata_qdi")) { + release_region(port, 2); + return; + } + res = inb(port + 3); + /* Single channel mode ? */ + if (res & 1) + legacy_probe_add(ide_port[r & 0x01], 14 + (r & 0x01), + QDI6580, port); + else { /* Dual channel mode */ + legacy_probe_add(0x1F0, 14, QDI6580DP, port); + /* port + 0x02, r & 0x04 */ + legacy_probe_add(0x170, 15, QDI6580DP, port + 2); + } + } +} + +static __init void probe_qdi_vlb(void) +{ + unsigned long flags; + static const unsigned long qd_port[2] = { 0x30, 0xB0 }; + int i; + + /* + * Check each possible QD65xx base address + */ + + for (i = 0; i < 2; i++) { + unsigned long port = qd_port[i]; + u8 r, res; + + + if (request_region(port, 2, "pata_qdi")) { + /* Check for a card */ + local_irq_save(flags); + /* I have no h/w that needs this delay but it + is present in the historic code */ + r = inb(port); + udelay(1); + outb(0x19, port); + udelay(1); + res = inb(port); + udelay(1); + outb(r, port); + udelay(1); + local_irq_restore(flags); + + /* Fail */ + if (res == 0x19) { + release_region(port, 2); + continue; + } + /* Passes the presence test */ + r = inb(port + 1); + udelay(1); + /* Check port agrees with port set */ + if ((r & 2) >> 1 != i) { + release_region(port, 2); + continue; + } + qdi65_identify_port(r, res, port); + } + } +} /** * legacy_init - attach legacy interfaces @@ -867,15 +1340,17 @@ static __init int legacy_init(void) int ct = 0; int primary = 0; int secondary = 0; - int last_port = NR_HOST; + int pci_present = 0; + struct legacy_probe *pl = &probe_list[0]; + int slot = 0; struct pci_dev *p = NULL; for_each_pci_dev(p) { int r; - /* Check for any overlap of the system ATA mappings. Native mode controllers - stuck on these addresses or some devices in 'raid' mode won't be found by - the storage class test */ + /* Check for any overlap of the system ATA mappings. Native + mode controllers stuck on these addresses or some devices + in 'raid' mode won't be found by the storage class test */ for (r = 0; r < 6; r++) { if (pci_resource_start(p, r) == 0x1f0) primary = 1; @@ -885,49 +1360,37 @@ static __init int legacy_init(void) /* Check for special cases */ legacy_check_special_cases(p, &primary, &secondary); - /* If PCI bus is present then don't probe for tertiary legacy ports */ - if (probe_all == 0) - last_port = 2; + /* If PCI bus is present then don't probe for tertiary + legacy ports */ + pci_present = 1; } - /* If an OPTI 82C46X is present find out where the channels are */ - if (opti82c46x) { - static const char *optis[4] = { - "3/463MV", "5MV", - "5MVA", "5MVB" - }; - u8 chans = 1; - u8 ctrl = (opti_syscfg(0x30) & 0xC0) >> 6; - - opti82c46x = 3; /* Assume master and slave first */ - printk(KERN_INFO DRV_NAME ": Opti 82C46%s chipset support.\n", optis[ctrl]); - if (ctrl == 3) - chans = (opti_syscfg(0x3F) & 0x20) ? 2 : 1; - ctrl = opti_syscfg(0xAC); - /* Check enabled and this port is the 465MV port. On the - MVB we may have two channels */ - if (ctrl & 8) { - if (ctrl & 4) - opti82c46x = 2; /* Slave */ - else - opti82c46x = 1; /* Master */ - if (chans == 2) - opti82c46x = 3; /* Master and Slave */ - } /* Slave only */ - else if (chans == 1) - opti82c46x = 1; + if (primary == 0 || all) + legacy_probe_add(0x1F0, 14, UNKNOWN, 0); + if (secondary == 0 || all) + legacy_probe_add(0x170, 15, UNKNOWN, 0); + + if (probe_all || !pci_present) { + /* ISA/VLB extra ports */ + legacy_probe_add(0x1E8, 11, UNKNOWN, 0); + legacy_probe_add(0x168, 10, UNKNOWN, 0); + legacy_probe_add(0x1E0, 8, UNKNOWN, 0); + legacy_probe_add(0x160, 12, UNKNOWN, 0); } - for (i = 0; i < last_port; i++) { - /* Skip primary if we have seen a PCI one */ - if (i == 0 && primary == 1) - continue; - /* Skip secondary if we have seen a PCI one */ - if (i == 1 && secondary == 1) + if (opti82c46x) + probe_opti_vlb(); + if (qdi) + probe_qdi_vlb(); + + + for (i = 0; i < NR_HOST; i++, pl++) { + if (pl->port == 0) continue; - if (legacy_init_one(i, legacy_port[i], - legacy_port[i] + 0x0206, - legacy_irq[i]) == 0) + if (pl->type == UNKNOWN) + pl->type = probe_chip_type(pl); + pl->slot = slot++; + if (legacy_init_one(pl) == 0) ct++; } if (ct != 0) @@ -941,7 +1404,6 @@ static __exit void legacy_exit(void) for (i = 0; i < nr_legacy_host; i++) { struct legacy_data *ld = &legacy_data[i]; - ata_host_detach(legacy_host[i]); platform_device_unregister(ld->platform_dev); if (ld->timing) @@ -960,9 +1422,9 @@ module_param(ht6560a, int, 0); module_param(ht6560b, int, 0); module_param(opti82c611a, int, 0); module_param(opti82c46x, int, 0); +module_param(qdi, int, 0); module_param(pio_mask, int, 0); module_param(iordy_mask, int, 0); module_init(legacy_init); module_exit(legacy_exit); - diff --git a/drivers/ata/pata_ninja32.c b/drivers/ata/pata_ninja32.c new file mode 100644 index 0000000..1c1b835 --- /dev/null +++ b/drivers/ata/pata_ninja32.c @@ -0,0 +1,214 @@ +/* + * pata_ninja32.c - Ninja32 PATA for new ATA layer + * (C) 2007 Red Hat Inc + * Alan Cox + * + * Note: The controller like many controllers has shared timings for + * PIO and DMA. We thus flip to the DMA timings in dma_start and flip back + * in the dma_stop function. Thus we actually don't need a set_dmamode + * method as the PIO method is always called and will set the right PIO + * timing parameters. + * + * The Ninja32 Cardbus is not a generic SFF controller. Instead it is + * laid out as follows off BAR 0. This is based upon Mark Lord's delkin + * driver and the extensive analysis done by the BSD developers, notably + * ITOH Yasufumi. + * + * Base + 0x00 IRQ Status + * Base + 0x01 IRQ control + * Base + 0x02 Chipset control + * Base + 0x04 VDMA and reset control + wait bits + * Base + 0x08 BMIMBA + * Base + 0x0C DMA Length + * Base + 0x10 Taskfile + * Base + 0x18 BMDMA Status ? + * Base + 0x1C + * Base + 0x1D Bus master control + * bit 0 = enable + * bit 1 = 0 write/1 read + * bit 2 = 1 sgtable + * bit 3 = go + * bit 4-6 wait bits + * bit 7 = done + * Base + 0x1E AltStatus + * Base + 0x1F timing register + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRV_NAME "pata_ninja32" +#define DRV_VERSION "0.0.1" + + +/** + * ninja32_set_piomode - set initial PIO mode data + * @ap: ATA interface + * @adev: ATA device + * + * Called to do the PIO mode setup. Our timing registers are shared + * but we want to set the PIO timing by default. + */ + +static void ninja32_set_piomode(struct ata_port *ap, struct ata_device *adev) +{ + static u16 pio_timing[5] = { + 0xd6, 0x85, 0x44, 0x33, 0x13 + }; + iowrite8(pio_timing[adev->pio_mode - XFER_PIO_0], + ap->ioaddr.bmdma_addr + 0x1f); + ap->private_data = adev; +} + + +static void ninja32_dev_select(struct ata_port *ap, unsigned int device) +{ + struct ata_device *adev = &ap->link.device[device]; + if (ap->private_data != adev) { + iowrite8(0xd6, ap->ioaddr.bmdma_addr + 0x1f); + ata_std_dev_select(ap, device); + ninja32_set_piomode(ap, adev); + } +} + +static struct scsi_host_template ninja32_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, +}; + +static struct ata_port_operations ninja32_port_ops = { + .set_piomode = ninja32_set_piomode, + .mode_filter = ata_pci_default_filter, + + .tf_load = ata_tf_load, + .tf_read = ata_tf_read, + .check_status = ata_check_status, + .exec_command = ata_exec_command, + .dev_select = ninja32_dev_select, + + .freeze = ata_bmdma_freeze, + .thaw = ata_bmdma_thaw, + .error_handler = ata_bmdma_error_handler, + .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, + + .bmdma_setup = ata_bmdma_setup, + .bmdma_start = ata_bmdma_start, + .bmdma_stop = ata_bmdma_stop, + .bmdma_status = ata_bmdma_status, + + .qc_prep = ata_qc_prep, + .qc_issue = ata_qc_issue_prot, + + .data_xfer = ata_data_xfer, + + .irq_handler = ata_interrupt, + .irq_clear = ata_bmdma_irq_clear, + .irq_on = ata_irq_on, + + .port_start = ata_sff_port_start, +}; + +static int ninja32_init_one(struct pci_dev *dev, const struct pci_device_id *id) +{ + struct ata_host *host; + struct ata_port *ap; + void __iomem *base; + int rc; + + host = ata_host_alloc(&dev->dev, 1); + if (!host) + return -ENOMEM; + ap = host->ports[0]; + + /* Set up the PCI device */ + rc = pcim_enable_device(dev); + if (rc) + return rc; + rc = pcim_iomap_regions(dev, 1 << 0, DRV_NAME); + if (rc == -EBUSY) + pcim_pin_device(dev); + if (rc) + return rc; + + host->iomap = pcim_iomap_table(dev); + rc = pci_set_dma_mask(dev, ATA_DMA_MASK); + if (rc) + return rc; + rc = pci_set_consistent_dma_mask(dev, ATA_DMA_MASK); + if (rc) + return rc; + pci_set_master(dev); + + /* Set up the register mappings */ + base = host->iomap[0]; + if (!base) + return -ENOMEM; + ap->ops = &ninja32_port_ops; + ap->pio_mask = 0x1F; + ap->flags |= ATA_FLAG_SLAVE_POSS; + + ap->ioaddr.cmd_addr = base + 0x10; + ap->ioaddr.ctl_addr = base + 0x1E; + ap->ioaddr.altstatus_addr = base + 0x1E; + ap->ioaddr.bmdma_addr = base; + ata_std_ports(&ap->ioaddr); + + iowrite8(0x05, base + 0x01); /* Enable interrupt lines */ + iowrite8(0xB3, base + 0x02); /* Burst, ?? setup */ + iowrite8(0x00, base + 0x04); /* WAIT0 ? */ + /* FIXME: Should we disable them at remove ? */ + return ata_host_activate(host, dev->irq, ata_interrupt, + IRQF_SHARED, &ninja32_sht); +} + +static const struct pci_device_id ninja32[] = { + { 0x1145, 0xf021, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { 0x1145, 0xf024, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { }, +}; + +static struct pci_driver ninja32_pci_driver = { + .name = DRV_NAME, + .id_table = ninja32, + .probe = ninja32_init_one, + .remove = ata_pci_remove_one +}; + +static int __init ninja32_init(void) +{ + return pci_register_driver(&ninja32_pci_driver); +} + +static void __exit ninja32_exit(void) +{ + pci_unregister_driver(&ninja32_pci_driver); +} + +MODULE_AUTHOR("Alan Cox"); +MODULE_DESCRIPTION("low-level driver for Ninja32 ATA"); +MODULE_LICENSE("GPL"); +MODULE_DEVICE_TABLE(pci, ninja32); +MODULE_VERSION(DRV_VERSION); + +module_init(ninja32_init); +module_exit(ninja32_exit); diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c index fd36099..3e7f6a9 100644 --- a/drivers/ata/pata_pcmcia.c +++ b/drivers/ata/pata_pcmcia.c @@ -42,7 +42,7 @@ #define DRV_NAME "pata_pcmcia" -#define DRV_VERSION "0.3.2" +#define DRV_VERSION "0.3.3" /* * Private data structure to glue stuff together @@ -86,6 +86,47 @@ static int pcmcia_set_mode(struct ata_link *link, struct ata_device **r_failed_d return ata_do_set_mode(link, r_failed_dev); } +/** + * pcmcia_set_mode_8bit - PCMCIA specific mode setup + * @link: link + * @r_failed_dev: Return pointer for failed device + * + * For the simple emulated 8bit stuff the less we do the better. + */ + +static int pcmcia_set_mode_8bit(struct ata_link *link, + struct ata_device **r_failed_dev) +{ + return 0; +} + +/** + * ata_data_xfer_8bit - Transfer data by 8bit PIO + * @dev: device to target + * @buf: data buffer + * @buflen: buffer length + * @rw: read/write + * + * Transfer data from/to the device data register by 8 bit PIO. + * + * LOCKING: + * Inherited from caller. + */ + +static unsigned int ata_data_xfer_8bit(struct ata_device *dev, + unsigned char *buf, unsigned int buflen, int rw) +{ + struct ata_port *ap = dev->link->ap; + + if (rw == READ) + ioread8_rep(ap->ioaddr.data_addr, buf, buflen); + else + iowrite8_rep(ap->ioaddr.data_addr, buf, buflen); + + return buflen; +} + + static struct scsi_host_template pcmcia_sht = { .module = THIS_MODULE, .name = DRV_NAME, @@ -129,6 +170,31 @@ static struct ata_port_operations pcmcia_port_ops = { .port_start = ata_sff_port_start, }; +static struct ata_port_operations pcmcia_8bit_port_ops = { + .set_mode = pcmcia_set_mode_8bit, + .tf_load = ata_tf_load, + .tf_read = ata_tf_read, + .check_status = ata_check_status, + .exec_command = ata_exec_command, + .dev_select = ata_std_dev_select, + + .freeze = ata_bmdma_freeze, + .thaw = ata_bmdma_thaw, + .error_handler = ata_bmdma_error_handler, + .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = ata_cable_40wire, + + .qc_prep = ata_qc_prep, + .qc_issue = ata_qc_issue_prot, + + .data_xfer = ata_data_xfer_8bit, + + .irq_clear = ata_bmdma_irq_clear, + .irq_on = ata_irq_on, + + .port_start = ata_sff_port_start, +}; + #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) @@ -153,9 +219,12 @@ static int pcmcia_init_one(struct pcmcia_device *pdev) cistpl_cftable_entry_t dflt; } *stk = NULL; cistpl_cftable_entry_t *cfg; - int pass, last_ret = 0, last_fn = 0, is_kme = 0, ret = -ENOMEM; + int pass, last_ret = 0, last_fn = 0, is_kme = 0, ret = -ENOMEM, p; unsigned long io_base, ctl_base; void __iomem *io_addr, *ctl_addr; + int n_ports = 1; + + struct ata_port_operations *ops = &pcmcia_port_ops; info = kzalloc(sizeof(*info), GFP_KERNEL); if (info == NULL) @@ -282,27 +351,32 @@ next_entry: /* FIXME: Could be more ports at base + 0x10 but we only deal with one right now */ if (pdev->io.NumPorts1 >= 0x20) - printk(KERN_WARNING DRV_NAME ": second channel not yet supported.\n"); + n_ports = 2; + if (pdev->manf_id == 0x0097 && pdev->card_id == 0x1620) + ops = &pcmcia_8bit_port_ops; /* * Having done the PCMCIA plumbing the ATA side is relatively * sane. */ ret = -ENOMEM; - host = ata_host_alloc(&pdev->dev, 1); + host = ata_host_alloc(&pdev->dev, n_ports); if (!host) goto failed; - ap = host->ports[0]; - ap->ops = &pcmcia_port_ops; - ap->pio_mask = 1; /* ISA so PIO 0 cycles */ - ap->flags |= ATA_FLAG_SLAVE_POSS; - ap->ioaddr.cmd_addr = io_addr; - ap->ioaddr.altstatus_addr = ctl_addr; - ap->ioaddr.ctl_addr = ctl_addr; - ata_std_ports(&ap->ioaddr); + for (p = 0; p < n_ports; p++) { + ap = host->ports[p]; - ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx", io_base, ctl_base); + ap->ops = ops; + ap->pio_mask = 1; /* ISA so PIO 0 cycles */ + ap->flags |= ATA_FLAG_SLAVE_POSS; + ap->ioaddr.cmd_addr = io_addr + 0x10 * p; + ap->ioaddr.altstatus_addr = ctl_addr + 0x10 * p; + ap->ioaddr.ctl_addr = ctl_addr + 0x10 * p; + ata_std_ports(&ap->ioaddr); + + ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx", io_base, ctl_base); + } /* activate */ ret = ata_host_activate(host, pdev->irq.AssignedIRQ, ata_interrupt, @@ -360,6 +434,7 @@ static struct pcmcia_device_id pcmcia_devices[] = { PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704), PCMCIA_DEVICE_MANF_CARD(0x0032, 0x2904), PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401), /* SanDisk CFA */ + PCMCIA_DEVICE_MANF_CARD(0x0097, 0x1620), /* TI emulated */ PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000), /* Toshiba */ PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d), PCMCIA_DEVICE_MANF_CARD(0x00ce, 0x0000), /* Samsung */ diff --git a/drivers/ata/pata_pdc2027x.c b/drivers/ata/pata_pdc2027x.c index 2622577..028af5d 100644 --- a/drivers/ata/pata_pdc2027x.c +++ b/drivers/ata/pata_pdc2027x.c @@ -348,7 +348,7 @@ static unsigned long pdc2027x_mode_filter(struct ata_device *adev, unsigned long ata_id_c_string(pair->id, model_num, ATA_ID_PROD, ATA_ID_PROD_LEN + 1); /* If the master is a maxtor in UDMA6 then the slave should not use UDMA 6 */ - if (strstr(model_num, "Maxtor") == 0 && pair->dma_mode == XFER_UDMA_6) + if (strstr(model_num, "Maxtor") == NULL && pair->dma_mode == XFER_UDMA_6) mask &= ~ (1 << (6 + ATA_SHIFT_UDMA)); return ata_pci_default_filter(adev, mask); diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c index 8f28156..b0e65d8 100644 --- a/drivers/ata/pata_pdc202xx_old.c +++ b/drivers/ata/pata_pdc202xx_old.c @@ -168,8 +168,7 @@ static void pdc2026x_bmdma_start(struct ata_queued_cmd *qc) pdc202xx_set_dmamode(ap, qc->dev); /* Cases the state machine will not complete correctly without help */ - if ((tf->flags & ATA_TFLAG_LBA48) || tf->protocol == ATA_PROT_ATAPI_DMA) - { + if ((tf->flags & ATA_TFLAG_LBA48) || tf->protocol == ATAPI_PROT_DMA) { len = qc->nbytes / 2; if (tf->flags & ATA_TFLAG_WRITE) @@ -208,7 +207,7 @@ static void pdc2026x_bmdma_stop(struct ata_queued_cmd *qc) void __iomem *atapi_reg = master + 0x20 + (4 * ap->port_no); /* Cases the state machine will not complete correctly */ - if (tf->protocol == ATA_PROT_ATAPI_DMA || ( tf->flags & ATA_TFLAG_LBA48)) { + if (tf->protocol == ATAPI_PROT_DMA || (tf->flags & ATA_TFLAG_LBA48)) { iowrite32(0, atapi_reg); iowrite8(ioread8(clock) & ~sel66, clock); } diff --git a/drivers/ata/pata_qdi.c b/drivers/ata/pata_qdi.c index a4c0e50..9f308ed 100644 --- a/drivers/ata/pata_qdi.c +++ b/drivers/ata/pata_qdi.c @@ -124,29 +124,33 @@ static unsigned int qdi_qc_issue_prot(struct ata_queued_cmd *qc) return ata_qc_issue_prot(qc); } -static void qdi_data_xfer(struct ata_device *adev, unsigned char *buf, unsigned int buflen, int write_data) +static unsigned int qdi_data_xfer(struct ata_device *dev, unsigned char *buf, + unsigned int buflen, int rw) { - struct ata_port *ap = adev->link->ap; - int slop = buflen & 3; + if (ata_id_has_dword_io(dev->id)) { + struct ata_port *ap = dev->link->ap; + int slop = buflen & 3; - if (ata_id_has_dword_io(adev->id)) { - if (write_data) - iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); - else + if (rw == READ) ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); + else + iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); if (unlikely(slop)) { - __le32 pad = 0; - if (write_data) { - memcpy(&pad, buf + buflen - slop, slop); - iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr); - } else { + u32 pad; + if (rw == READ) { pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr)); memcpy(buf + buflen - slop, &pad, slop); + } else { + memcpy(&pad, buf + buflen - slop, slop); + iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr); } + buflen += 4 - slop; } } else - ata_data_xfer(adev, buf, buflen, write_data); + buflen = ata_data_xfer(dev, buf, buflen, rw); + + return buflen; } static struct scsi_host_template qdi_sht = { diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c index ea2ef9f..55055b2 100644 --- a/drivers/ata/pata_scc.c +++ b/drivers/ata/pata_scc.c @@ -768,45 +768,47 @@ static u8 scc_bmdma_status (struct ata_port *ap) /** * scc_data_xfer - Transfer data by PIO - * @adev: device for this I/O + * @dev: device for this I/O * @buf: data buffer * @buflen: buffer length - * @write_data: read/write + * @rw: read/write * * Note: Original code is ata_data_xfer(). */ -static void scc_data_xfer (struct ata_device *adev, unsigned char *buf, - unsigned int buflen, int write_data) +static unsigned int scc_data_xfer (struct ata_device *dev, unsigned char *buf, + unsigned int buflen, int rw) { - struct ata_port *ap = adev->link->ap; + struct ata_port *ap = dev->link->ap; unsigned int words = buflen >> 1; unsigned int i; u16 *buf16 = (u16 *) buf; void __iomem *mmio = ap->ioaddr.data_addr; /* Transfer multiple of 2 bytes */ - if (write_data) { - for (i = 0; i < words; i++) - out_be32(mmio, cpu_to_le16(buf16[i])); - } else { + if (rw == READ) for (i = 0; i < words; i++) buf16[i] = le16_to_cpu(in_be32(mmio)); - } + else + for (i = 0; i < words; i++) + out_be32(mmio, cpu_to_le16(buf16[i])); /* Transfer trailing 1 byte, if any. */ if (unlikely(buflen & 0x01)) { u16 align_buf[1] = { 0 }; unsigned char *trailing_buf = buf + buflen - 1; - if (write_data) { - memcpy(align_buf, trailing_buf, 1); - out_be32(mmio, cpu_to_le16(align_buf[0])); - } else { + if (rw == READ) { align_buf[0] = le16_to_cpu(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])); } + words++; } + + return words << 1; } /** diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c index 453d72b..39627ab 100644 --- a/drivers/ata/pata_via.c +++ b/drivers/ata/pata_via.c @@ -185,7 +185,8 @@ static int via_cable_detect(struct ata_port *ap) { if (ata66 & (0x10100000 >> (16 * ap->port_no))) return ATA_CBL_PATA80; /* Check with ACPI so we can spot BIOS reported SATA bridges */ - if (ata_acpi_cbl_80wire(ap)) + if (ata_acpi_init_gtm(ap) && + ata_acpi_cbl_80wire(ap, ata_acpi_init_gtm(ap))) return ATA_CBL_PATA80; return ATA_CBL_PATA40; } diff --git a/drivers/ata/pata_winbond.c b/drivers/ata/pata_winbond.c index 7116a9e..17a9d07 100644 --- a/drivers/ata/pata_winbond.c +++ b/drivers/ata/pata_winbond.c @@ -92,29 +92,33 @@ static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev) } -static void winbond_data_xfer(struct ata_device *adev, unsigned char *buf, unsigned int buflen, int write_data) +static unsigned int winbond_data_xfer(struct ata_device *dev, + unsigned char *buf, unsigned int buflen, int rw) { - struct ata_port *ap = adev->link->ap; + struct ata_port *ap = dev->link->ap; int slop = buflen & 3; - if (ata_id_has_dword_io(adev->id)) { - if (write_data) - iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); - else + if (ata_id_has_dword_io(dev->id)) { + if (rw == READ) ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); + else + iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); if (unlikely(slop)) { - __le32 pad = 0; - if (write_data) { - memcpy(&pad, buf + buflen - slop, slop); - iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr); - } else { + u32 pad; + if (rw == READ) { pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr)); memcpy(buf + buflen - slop, &pad, slop); + } else { + memcpy(&pad, buf + buflen - slop, slop); + iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr); } + buflen += 4 - slop; } } else - ata_data_xfer(adev, buf, buflen, write_data); + buflen = ata_data_xfer(dev, buf, buflen, rw); + + return buflen; } static struct scsi_host_template winbond_sht = { diff --git a/drivers/ata/pdc_adma.c b/drivers/ata/pdc_adma.c index bd4c2a3..8e1b7e9 100644 --- a/drivers/ata/pdc_adma.c +++ b/drivers/ata/pdc_adma.c @@ -321,8 +321,9 @@ static int adma_fill_sg(struct ata_queued_cmd *qc) u8 *buf = pp->pkt, *last_buf = NULL; int i = (2 + buf[3]) * 8; u8 pFLAGS = pORD | ((qc->tf.flags & ATA_TFLAG_WRITE) ? pDIRO : 0); + unsigned int si; - ata_for_each_sg(sg, qc) { + for_each_sg(qc->sg, sg, qc->n_elem, si) { u32 addr; u32 len; @@ -455,7 +456,7 @@ static unsigned int adma_qc_issue(struct ata_queued_cmd *qc) adma_packet_start(qc); return 0; - case ATA_PROT_ATAPI_DMA: + case ATAPI_PROT_DMA: BUG(); break; diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index d015b4a..d041709 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c @@ -323,6 +323,7 @@ static unsigned int sata_fsl_fill_sg(struct ata_queued_cmd *qc, void *cmd_desc, struct scatterlist *sg; unsigned int num_prde = 0; u32 ttl_dwords = 0; + unsigned int si; /* * NOTE : direct & indirect prdt's are contigiously allocated @@ -333,13 +334,14 @@ static unsigned int sata_fsl_fill_sg(struct ata_queued_cmd *qc, void *cmd_desc, struct prde *prd_ptr_to_indirect_ext = NULL; unsigned indirect_ext_segment_sz = 0; dma_addr_t indirect_ext_segment_paddr; + unsigned int si; VPRINTK("SATA FSL : cd = 0x%x, prd = 0x%x\n", cmd_desc, prd); indirect_ext_segment_paddr = cmd_desc_paddr + SATA_FSL_CMD_DESC_OFFSET_TO_PRDT + SATA_FSL_MAX_PRD_DIRECT * 16; - ata_for_each_sg(sg, qc) { + for_each_sg(qc->sg, sg, qc->n_elem, si) { dma_addr_t sg_addr = sg_dma_address(sg); u32 sg_len = sg_dma_len(sg); @@ -417,7 +419,7 @@ static void sata_fsl_qc_prep(struct ata_queued_cmd *qc) } /* setup "ACMD - atapi command" in cmd. desc. if this is ATAPI cmd */ - if (is_atapi_taskfile(&qc->tf)) { + if (ata_is_atapi(qc->tf.protocol)) { desc_info |= ATAPI_CMD; memset((void *)&cd->acmd, 0, 32); memcpy((void *)&cd->acmd, qc->cdb, qc->dev->cdb_len); diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c index 323c087..96e614a 100644 --- a/drivers/ata/sata_inic162x.c +++ b/drivers/ata/sata_inic162x.c @@ -585,7 +585,7 @@ static struct ata_port_operations inic_port_ops = { }; static struct ata_port_info inic_port_info = { - /* For some reason, ATA_PROT_ATAPI is broken on this + /* For some reason, ATAPI_PROT_PIO is broken on this * controller, and no, PIO_POLLING does't fix it. It somehow * manages to report the wrong ireason and ignoring ireason * results in machine lock up. Tell libata to always prefer diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 37b850a..7e72463 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -1136,9 +1136,10 @@ static void mv_fill_sg(struct ata_queued_cmd *qc) struct mv_port_priv *pp = qc->ap->private_data; struct scatterlist *sg; struct mv_sg *mv_sg, *last_sg = NULL; + unsigned int si; mv_sg = pp->sg_tbl; - ata_for_each_sg(sg, qc) { + for_each_sg(qc->sg, sg, qc->n_elem, si) { dma_addr_t addr = sg_dma_address(sg); u32 sg_len = sg_dma_len(sg); diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index ed5dc7c..a0f98fd 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c @@ -1336,21 +1336,18 @@ static void nv_adma_fill_aprd(struct ata_queued_cmd *qc, static void nv_adma_fill_sg(struct ata_queued_cmd *qc, struct nv_adma_cpb *cpb) { struct nv_adma_port_priv *pp = qc->ap->private_data; - unsigned int idx; struct nv_adma_prd *aprd; struct scatterlist *sg; + unsigned int si; VPRINTK("ENTER\n"); - idx = 0; - - ata_for_each_sg(sg, qc) { - aprd = (idx < 5) ? &cpb->aprd[idx] : - &pp->aprd[NV_ADMA_SGTBL_LEN * qc->tag + (idx-5)]; - nv_adma_fill_aprd(qc, sg, idx, aprd); - idx++; + for_each_sg(qc->sg, sg, qc->n_elem, si) { + aprd = (si < 5) ? &cpb->aprd[si] : + &pp->aprd[NV_ADMA_SGTBL_LEN * qc->tag + (si-5)]; + nv_adma_fill_aprd(qc, sg, si, aprd); } - if (idx > 5) + if (si > 5) cpb->next_aprd = cpu_to_le64(((u64)(pp->aprd_dma + NV_ADMA_SGTBL_SZ * qc->tag))); else cpb->next_aprd = cpu_to_le64(0); @@ -1995,17 +1992,14 @@ static void nv_swncq_fill_sg(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; struct scatterlist *sg; - unsigned int idx; struct nv_swncq_port_priv *pp = ap->private_data; struct ata_prd *prd; - - WARN_ON(qc->__sg == NULL); - WARN_ON(qc->n_elem == 0 && qc->pad_len == 0); + unsigned int si, idx; prd = pp->prd + ATA_MAX_PRD * qc->tag; idx = 0; - ata_for_each_sg(sg, qc) { + for_each_sg(qc->sg, sg, qc->n_elem, si) { u32 addr, offset; u32 sg_len, len; @@ -2027,8 +2021,7 @@ static void nv_swncq_fill_sg(struct ata_queued_cmd *qc) } } - if (idx) - prd[idx - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT); + prd[idx - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT); } static unsigned int nv_swncq_issue_atacmd(struct ata_port *ap, diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c index 7914def..a07d319 100644 --- a/drivers/ata/sata_promise.c +++ b/drivers/ata/sata_promise.c @@ -450,19 +450,19 @@ static void pdc_atapi_pkt(struct ata_queued_cmd *qc) struct pdc_port_priv *pp = ap->private_data; u8 *buf = pp->pkt; u32 *buf32 = (u32 *) buf; - unsigned int dev_sel, feature, nbytes; + unsigned int dev_sel, feature; /* set control bits (byte 0), zero delay seq id (byte 3), * and seq id (byte 2) */ switch (qc->tf.protocol) { - case ATA_PROT_ATAPI_DMA: + case ATAPI_PROT_DMA: if (!(qc->tf.flags & ATA_TFLAG_WRITE)) buf32[0] = cpu_to_le32(PDC_PKT_READ); else buf32[0] = 0; break; - case ATA_PROT_ATAPI_NODATA: + case ATAPI_PROT_NODATA: buf32[0] = cpu_to_le32(PDC_PKT_NODATA); break; default: @@ -473,45 +473,37 @@ static void pdc_atapi_pkt(struct ata_queued_cmd *qc) buf32[2] = 0; /* no next-packet */ /* select drive */ - if (sata_scr_valid(&ap->link)) { + if (sata_scr_valid(&ap->link)) dev_sel = PDC_DEVICE_SATA; - } else { - dev_sel = ATA_DEVICE_OBS; - if (qc->dev->devno != 0) - dev_sel |= ATA_DEV1; - } + else + dev_sel = qc->tf.device; + buf[12] = (1 << 5) | ATA_REG_DEVICE; buf[13] = dev_sel; buf[14] = (1 << 5) | ATA_REG_DEVICE | PDC_PKT_CLEAR_BSY; buf[15] = dev_sel; /* once more, waiting for BSY to clear */ buf[16] = (1 << 5) | ATA_REG_NSECT; - buf[17] = 0x00; + buf[17] = qc->tf.nsect; buf[18] = (1 << 5) | ATA_REG_LBAL; - buf[19] = 0x00; + buf[19] = qc->tf.lbal; /* set feature and byte counter registers */ - if (qc->tf.protocol != ATA_PROT_ATAPI_DMA) { + if (qc->tf.protocol != ATAPI_PROT_DMA) feature = PDC_FEATURE_ATAPI_PIO; - /* set byte counter register to real transfer byte count */ - nbytes = qc->nbytes; - if (nbytes > 0xffff) - nbytes = 0xffff; - } else { + else feature = PDC_FEATURE_ATAPI_DMA; - /* set byte counter register to 0 */ - nbytes = 0; - } + buf[20] = (1 << 5) | ATA_REG_FEATURE; buf[21] = feature; buf[22] = (1 << 5) | ATA_REG_BYTEL; - buf[23] = nbytes & 0xFF; + buf[23] = qc->tf.lbam; buf[24] = (1 << 5) | ATA_REG_BYTEH; - buf[25] = (nbytes >> 8) & 0xFF; + buf[25] = qc->tf.lbah; /* send ATAPI packet command 0xA0 */ buf[26] = (1 << 5) | ATA_REG_CMD; - buf[27] = ATA_CMD_PACKET; + buf[27] = qc->tf.command; /* select drive and check DRQ */ buf[28] = (1 << 5) | ATA_REG_DEVICE | PDC_PKT_WAIT_DRDY; @@ -541,17 +533,15 @@ static void pdc_fill_sg(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; struct scatterlist *sg; - unsigned int idx; const u32 SG_COUNT_ASIC_BUG = 41*4; + unsigned int si, idx; + u32 len; if (!(qc->flags & ATA_QCFLAG_DMAMAP)) return; - WARN_ON(qc->__sg == NULL); - WARN_ON(qc->n_elem == 0 && qc->pad_len == 0); - idx = 0; - ata_for_each_sg(sg, qc) { + for_each_sg(qc->sg, sg, qc->n_elem, si) { u32 addr, offset; u32 sg_len, len; @@ -578,29 +568,27 @@ static void pdc_fill_sg(struct ata_queued_cmd *qc) } } - if (idx) { - u32 len = le32_to_cpu(ap->prd[idx - 1].flags_len); + len = le32_to_cpu(ap->prd[idx - 1].flags_len); - if (len > SG_COUNT_ASIC_BUG) { - u32 addr; + if (len > SG_COUNT_ASIC_BUG) { + u32 addr; - VPRINTK("Splitting last PRD.\n"); + VPRINTK("Splitting last PRD.\n"); - addr = le32_to_cpu(ap->prd[idx - 1].addr); - ap->prd[idx - 1].flags_len = cpu_to_le32(len - SG_COUNT_ASIC_BUG); - VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", idx - 1, addr, SG_COUNT_ASIC_BUG); + addr = le32_to_cpu(ap->prd[idx - 1].addr); + ap->prd[idx - 1].flags_len = cpu_to_le32(len - SG_COUNT_ASIC_BUG); + VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", idx - 1, addr, SG_COUNT_ASIC_BUG); - addr = addr + len - SG_COUNT_ASIC_BUG; - len = SG_COUNT_ASIC_BUG; - ap->prd[idx].addr = cpu_to_le32(addr); - ap->prd[idx].flags_len = cpu_to_le32(len); - VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", idx, addr, len); + addr = addr + len - SG_COUNT_ASIC_BUG; + len = SG_COUNT_ASIC_BUG; + ap->prd[idx].addr = cpu_to_le32(addr); + ap->prd[idx].flags_len = cpu_to_le32(len); + VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", idx, addr, len); - idx++; - } - - ap->prd[idx - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT); + idx++; } + + ap->prd[idx - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT); } static void pdc_qc_prep(struct ata_queued_cmd *qc) @@ -627,14 +615,14 @@ static void pdc_qc_prep(struct ata_queued_cmd *qc) pdc_pkt_footer(&qc->tf, pp->pkt, i); break; - case ATA_PROT_ATAPI: + case ATAPI_PROT_PIO: pdc_fill_sg(qc); break; - case ATA_PROT_ATAPI_DMA: + case ATAPI_PROT_DMA: pdc_fill_sg(qc); /*FALLTHROUGH*/ - case ATA_PROT_ATAPI_NODATA: + case ATAPI_PROT_NODATA: pdc_atapi_pkt(qc); break; @@ -754,8 +742,8 @@ static inline unsigned int pdc_host_intr(struct ata_port *ap, switch (qc->tf.protocol) { case ATA_PROT_DMA: case ATA_PROT_NODATA: - case ATA_PROT_ATAPI_DMA: - case ATA_PROT_ATAPI_NODATA: + case ATAPI_PROT_DMA: + case ATAPI_PROT_NODATA: qc->err_mask |= ac_err_mask(ata_wait_idle(ap)); ata_qc_complete(qc); handled = 1; @@ -900,7 +888,7 @@ static inline void pdc_packet_start(struct ata_queued_cmd *qc) static unsigned int pdc_qc_issue_prot(struct ata_queued_cmd *qc) { switch (qc->tf.protocol) { - case ATA_PROT_ATAPI_NODATA: + case ATAPI_PROT_NODATA: if (qc->dev->flags & ATA_DFLAG_CDB_INTR) break; /*FALLTHROUGH*/ @@ -908,7 +896,7 @@ static unsigned int pdc_qc_issue_prot(struct ata_queued_cmd *qc) if (qc->tf.flags & ATA_TFLAG_POLLING) break; /*FALLTHROUGH*/ - case ATA_PROT_ATAPI_DMA: + case ATAPI_PROT_DMA: case ATA_PROT_DMA: pdc_packet_start(qc); return 0; @@ -922,16 +910,14 @@ static unsigned int pdc_qc_issue_prot(struct ata_queued_cmd *qc) static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf) { - WARN_ON(tf->protocol == ATA_PROT_DMA || - tf->protocol == ATA_PROT_ATAPI_DMA); + WARN_ON(tf->protocol == ATA_PROT_DMA || tf->protocol == ATAPI_PROT_DMA); ata_tf_load(ap, tf); } static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf) { - WARN_ON(tf->protocol == ATA_PROT_DMA || - tf->protocol == ATA_PROT_ATAPI_DMA); + WARN_ON(tf->protocol == ATA_PROT_DMA || tf->protocol == ATAPI_PROT_DMA); ata_exec_command(ap, tf); } diff --git a/drivers/ata/sata_promise.h b/drivers/ata/sata_promise.h index 6ee5e19..00d6000 100644 --- a/drivers/ata/sata_promise.h +++ b/drivers/ata/sata_promise.h @@ -46,7 +46,7 @@ static inline unsigned int pdc_pkt_header(struct ata_taskfile *tf, unsigned int devno, u8 *buf) { u8 dev_reg; - u32 *buf32 = (u32 *) buf; + __le32 *buf32 = (__le32 *) buf; /* set control bits (byte 0), zero delay seq id (byte 3), * and seq id (byte 2) diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c index c68b241..91cc12c 100644 --- a/drivers/ata/sata_qstor.c +++ b/drivers/ata/sata_qstor.c @@ -287,14 +287,10 @@ static unsigned int qs_fill_sg(struct ata_queued_cmd *qc) struct scatterlist *sg; struct ata_port *ap = qc->ap; struct qs_port_priv *pp = ap->private_data; - unsigned int nelem; u8 *prd = pp->pkt + QS_CPB_BYTES; + unsigned int si; - WARN_ON(qc->__sg == NULL); - WARN_ON(qc->n_elem == 0 && qc->pad_len == 0); - - nelem = 0; - ata_for_each_sg(sg, qc) { + for_each_sg(qc->sg, sg, qc->n_elem, si) { u64 addr; u32 len; @@ -306,12 +302,11 @@ static unsigned int qs_fill_sg(struct ata_queued_cmd *qc) *(__le32 *)prd = cpu_to_le32(len); prd += sizeof(u64); - VPRINTK("PRD[%u] = (0x%llX, 0x%X)\n", nelem, + VPRINTK("PRD[%u] = (0x%llX, 0x%X)\n", si, (unsigned long long)addr, len); - nelem++; } - return nelem; + return si; } static void qs_qc_prep(struct ata_queued_cmd *qc) @@ -376,7 +371,7 @@ static unsigned int qs_qc_issue(struct ata_queued_cmd *qc) qs_packet_start(qc); return 0; - case ATA_PROT_ATAPI_DMA: + case ATAPI_PROT_DMA: BUG(); break; diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c index f5119bf..0b8191b 100644 --- a/drivers/ata/sata_sil.c +++ b/drivers/ata/sata_sil.c @@ -416,15 +416,14 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2) */ /* Check the ATA_DFLAG_CDB_INTR flag is enough here. - * The flag was turned on only for atapi devices. - * No need to check is_atapi_taskfile(&qc->tf) again. + * The flag was turned on only for atapi devices. No + * need to check ata_is_atapi(qc->tf.protocol) again. */ if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR)) goto err_hsm; break; case HSM_ST_LAST: - if (qc->tf.protocol == ATA_PROT_DMA || - qc->tf.protocol == ATA_PROT_ATAPI_DMA) { + if (ata_is_dma(qc->tf.protocol)) { /* clear DMA-Start bit */ ap->ops->bmdma_stop(qc); @@ -451,8 +450,7 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2) /* kick HSM in the ass */ ata_hsm_move(ap, qc, status, 0); - if (unlikely(qc->err_mask) && (qc->tf.protocol == ATA_PROT_DMA || - qc->tf.protocol == ATA_PROT_ATAPI_DMA)) + if (unlikely(qc->err_mask) && ata_is_dma(qc->tf.protocol)) ata_ehi_push_desc(ehi, "BMDMA2 stat 0x%x", bmdma2); return; diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c index 864c1c1..b4b1f91 100644 --- a/drivers/ata/sata_sil24.c +++ b/drivers/ata/sata_sil24.c @@ -813,8 +813,9 @@ static inline void sil24_fill_sg(struct ata_queued_cmd *qc, { struct scatterlist *sg; struct sil24_sge *last_sge = NULL; + unsigned int si; - ata_for_each_sg(sg, qc) { + for_each_sg(qc->sg, sg, qc->n_elem, si) { sge->addr = cpu_to_le64(sg_dma_address(sg)); sge->cnt = cpu_to_le32(sg_dma_len(sg)); sge->flags = 0; @@ -823,8 +824,7 @@ static inline void sil24_fill_sg(struct ata_queued_cmd *qc, sge++; } - if (likely(last_sge)) - last_sge->flags = cpu_to_le32(SGE_TRM); + last_sge->flags = cpu_to_le32(SGE_TRM); } static int sil24_qc_defer(struct ata_queued_cmd *qc) @@ -852,9 +852,7 @@ static int sil24_qc_defer(struct ata_queued_cmd *qc) * set. * */ - int is_excl = (prot == ATA_PROT_ATAPI || - prot == ATA_PROT_ATAPI_NODATA || - prot == ATA_PROT_ATAPI_DMA || + int is_excl = (ata_is_atapi(prot) || (qc->flags & ATA_QCFLAG_RESULT_TF)); if (unlikely(ap->excl_link)) { @@ -885,35 +883,21 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc) cb = &pp->cmd_block[sil24_tag(qc->tag)]; - switch (qc->tf.protocol) { - case ATA_PROT_PIO: - case ATA_PROT_DMA: - case ATA_PROT_NCQ: - case ATA_PROT_NODATA: + if (!ata_is_atapi(qc->tf.protocol)) { prb = &cb->ata.prb; sge = cb->ata.sge; - break; - - case ATA_PROT_ATAPI: - case ATA_PROT_ATAPI_DMA: - case ATA_PROT_ATAPI_NODATA: + } else { prb = &cb->atapi.prb; sge = cb->atapi.sge; memset(cb->atapi.cdb, 0, 32); memcpy(cb->atapi.cdb, qc->cdb, qc->dev->cdb_len); - if (qc->tf.protocol != ATA_PROT_ATAPI_NODATA) { + if (ata_is_data(qc->tf.protocol)) { if (qc->tf.flags & ATA_TFLAG_WRITE) ctrl = PRB_CTRL_PACKET_WRITE; else ctrl = PRB_CTRL_PACKET_READ; } - break; - - default: - prb = NULL; /* shut up, gcc */ - sge = NULL; - BUG(); } prb->ctrl = cpu_to_le16(ctrl); diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c index 4d85718..e1b5748 100644 --- a/drivers/ata/sata_sx4.c +++ b/drivers/ata/sata_sx4.c @@ -213,8 +213,9 @@ struct pdc_host_priv { static int pdc_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); -static void pdc_eng_timeout(struct ata_port *ap); -static void pdc_20621_phy_reset(struct ata_port *ap); +static void pdc_error_handler(struct ata_port *ap); +static void pdc_freeze(struct ata_port *ap); +static void pdc_thaw(struct ata_port *ap); static int pdc_port_start(struct ata_port *ap); static void pdc20621_qc_prep(struct ata_queued_cmd *qc); static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf); @@ -259,11 +260,12 @@ static const struct ata_port_operations pdc_20621_ops = { .check_status = ata_check_status, .exec_command = pdc_exec_command_mmio, .dev_select = ata_std_dev_select, - .phy_reset = pdc_20621_phy_reset, .qc_prep = pdc20621_qc_prep, .qc_issue = pdc20621_qc_issue_prot, .data_xfer = ata_data_xfer, - .eng_timeout = pdc_eng_timeout, + .freeze = pdc_freeze, + .thaw = pdc_thaw, + .error_handler = pdc_error_handler, .irq_clear = pdc20621_irq_clear, .irq_on = ata_irq_on, .port_start = pdc_port_start, @@ -320,21 +322,13 @@ static int pdc_port_start(struct ata_port *ap) return 0; } -static void pdc_20621_phy_reset(struct ata_port *ap) -{ - VPRINTK("ENTER\n"); - ap->cbl = ATA_CBL_SATA; - ata_port_probe(ap); - ata_bus_reset(ap); -} - static inline void pdc20621_ata_sg(struct ata_taskfile *tf, u8 *buf, unsigned int portno, unsigned int total_len) { u32 addr; unsigned int dw = PDC_DIMM_APKT_PRD >> 2; - u32 *buf32 = (u32 *) buf; + __le32 *buf32 = (__le32 *) buf; /* output ATA packet S/G table */ addr = PDC_20621_DIMM_BASE + PDC_20621_DIMM_DATA + @@ -356,7 +350,7 @@ static inline void pdc20621_host_sg(struct ata_taskfile *tf, u8 *buf, { u32 addr; unsigned int dw = PDC_DIMM_HPKT_PRD >> 2; - u32 *buf32 = (u32 *) buf; + __le32 *buf32 = (__le32 *) buf; /* output Host DMA packet S/G table */ addr = PDC_20621_DIMM_BASE + PDC_20621_DIMM_DATA + @@ -377,7 +371,7 @@ static inline unsigned int pdc20621_ata_pkt(struct ata_taskfile *tf, unsigned int portno) { unsigned int i, dw; - u32 *buf32 = (u32 *) buf; + __le32 *buf32 = (__le32 *) buf; u8 dev_reg; unsigned int dimm_sg = PDC_20621_DIMM_BASE + @@ -429,7 +423,8 @@ static inline void pdc20621_host_pkt(struct ata_taskfile *tf, u8 *buf, unsigned int portno) { unsigned int dw; - u32 tmp, *buf32 = (u32 *) buf; + u32 tmp; + __le32 *buf32 = (__le32 *) buf; unsigned int host_sg = PDC_20621_DIMM_BASE + (PDC_DIMM_WINDOW_STEP * portno) + @@ -473,7 +468,7 @@ static void pdc20621_dma_prep(struct ata_queued_cmd *qc) void __iomem *mmio = ap->host->iomap[PDC_MMIO_BAR]; void __iomem *dimm_mmio = ap->host->iomap[PDC_DIMM_BAR]; unsigned int portno = ap->port_no; - unsigned int i, idx, total_len = 0, sgt_len; + unsigned int i, si, idx, total_len = 0, sgt_len; u32 *buf = (u32 *) &pp->dimm_buf[PDC_DIMM_HEADER_SZ]; WARN_ON(!(qc->flags & ATA_QCFLAG_DMAMAP)); @@ -487,7 +482,7 @@ static void pdc20621_dma_prep(struct ata_queued_cmd *qc) * Build S/G table */ idx = 0; - ata_for_each_sg(sg, qc) { + for_each_sg(qc->sg, sg, qc->n_elem, si) { buf[idx++] = cpu_to_le32(sg_dma_address(sg)); buf[idx++] = cpu_to_le32(sg_dma_len(sg)); total_len += sg_dma_len(sg); @@ -700,7 +695,7 @@ static unsigned int pdc20621_qc_issue_prot(struct ata_queued_cmd *qc) pdc20621_packet_start(qc); return 0; - case ATA_PROT_ATAPI_DMA: + case ATAPI_PROT_DMA: BUG(); break; @@ -868,40 +863,70 @@ static irqreturn_t pdc20621_interrupt(int irq, void *dev_instance) return IRQ_RETVAL(handled); } -static void pdc_eng_timeout(struct ata_port *ap) +static void pdc_freeze(struct ata_port *ap) { - u8 drv_stat; - struct ata_host *host = ap->host; - struct ata_queued_cmd *qc; - unsigned long flags; + void __iomem *mmio = ap->ioaddr.cmd_addr; + u32 tmp; - DPRINTK("ENTER\n"); + /* FIXME: this should handle HDMA copy engine freezing */ - spin_lock_irqsave(&host->lock, flags); + tmp = readl(mmio + PDC_CTLSTAT); + tmp |= PDC_MASK_INT; + tmp &= ~PDC_DMA_ENABLE; + writel(tmp, mmio + PDC_CTLSTAT); + readl(mmio + PDC_CTLSTAT); /* flush */ +} - qc = ata_qc_from_tag(ap, ap->link.active_tag); +static void pdc_thaw(struct ata_port *ap) +{ + void __iomem *mmio = ap->ioaddr.cmd_addr; + void __iomem *mmio_base; + u32 tmp; - switch (qc->tf.protocol) { - case ATA_PROT_DMA: - case ATA_PROT_NODATA: - ata_port_printk(ap, KERN_ERR, "command timeout\n"); - qc->err_mask |= __ac_err_mask(ata_wait_idle(ap)); - break; + /* FIXME: this should handle HDMA copy engine thawing */ - default: - drv_stat = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000); + /* reading SEQ mask register clears IRQ */ + mmio_base = ap->host->iomap[PDC_MMIO_BAR] + PDC_CHIP0_OFS; + readl(mmio_base + PDC_20621_SEQMASK); - ata_port_printk(ap, KERN_ERR, - "unknown timeout, cmd 0x%x stat 0x%x\n", - qc->tf.command, drv_stat); + /* turn IRQ back on */ + tmp = readl(mmio + PDC_CTLSTAT); + tmp &= ~PDC_MASK_INT; + writel(tmp, mmio + PDC_CTLSTAT); + readl(mmio + PDC_CTLSTAT); /* flush */ +} - qc->err_mask |= ac_err_mask(drv_stat); - break; +static void pdc_reset_port(struct ata_port *ap) +{ + void __iomem *mmio = ap->ioaddr.cmd_addr + PDC_CTLSTAT; + unsigned int i; + u32 tmp; + + /* FIXME: handle HDMA copy engine */ + + for (i = 11; i > 0; i--) { + tmp = readl(mmio); + if (tmp & PDC_RESET) + break; + + udelay(100); + + tmp |= PDC_RESET; + writel(tmp, mmio); } - spin_unlock_irqrestore(&host->lock, flags); - ata_eh_qc_complete(qc); - DPRINTK("EXIT\n"); + tmp &= ~PDC_RESET; + writel(tmp, mmio); + readl(mmio); /* flush */ +} + +static void pdc_error_handler(struct ata_port *ap) +{ + if (!(ap->pflags & ATA_PFLAG_FROZEN)) + pdc_reset_port(ap); + + ata_do_eh(ap, ata_std_prereset, ata_std_softreset, NULL, + ata_std_postreset); } static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf) diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 0841df0..aa0df0a 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -5142,6 +5142,7 @@ static void ipr_build_ata_ioadl(struct ipr_cmnd *ipr_cmd, struct ipr_ioadl_desc *last_ioadl = NULL; int len = qc->nbytes + qc->pad_len; struct scatterlist *sg; + unsigned int si; if (len == 0) return; @@ -5159,7 +5160,7 @@ static void ipr_build_ata_ioadl(struct ipr_cmnd *ipr_cmd, cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg); } - ata_for_each_sg(sg, qc) { + for_each_sg(qc->sg, sg, qc->n_elem, si) { ioadl->flags_and_data_len = cpu_to_be32(ioadl_flags | sg_dma_len(sg)); ioadl->address = cpu_to_be32(sg_dma_address(sg)); @@ -5222,12 +5223,12 @@ static unsigned int ipr_qc_issue(struct ata_queued_cmd *qc) regs->flags |= IPR_ATA_FLAG_XFER_TYPE_DMA; break; - case ATA_PROT_ATAPI: - case ATA_PROT_ATAPI_NODATA: + case ATAPI_PROT_PIO: + case ATAPI_PROT_NODATA: regs->flags |= IPR_ATA_FLAG_PACKET_CMD; break; - case ATA_PROT_ATAPI_DMA: + case ATAPI_PROT_DMA: regs->flags |= IPR_ATA_FLAG_PACKET_CMD; regs->flags |= IPR_ATA_FLAG_XFER_TYPE_DMA; break; diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index 0829b55..827cfb1 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c @@ -158,8 +158,8 @@ static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc) struct Scsi_Host *host = sas_ha->core.shost; struct sas_internal *i = to_sas_internal(host->transportt); struct scatterlist *sg; - unsigned int num = 0; unsigned int xfer = 0; + unsigned int si; task = sas_alloc_task(GFP_ATOMIC); if (!task) @@ -176,22 +176,20 @@ static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc) ata_tf_to_fis(&qc->tf, 1, 0, (u8*)&task->ata_task.fis); task->uldd_task = qc; - if (is_atapi_taskfile(&qc->tf)) { + if (ata_is_atapi(qc->tf.protocol)) { memcpy(task->ata_task.atapi_packet, qc->cdb, qc->dev->cdb_len); task->total_xfer_len = qc->nbytes + qc->pad_len; task->num_scatter = qc->pad_len ? qc->n_elem + 1 : qc->n_elem; } else { - ata_for_each_sg(sg, qc) { - num++; + for_each_sg(qc->sg, sg, qc->n_elem, si) xfer += sg->length; - } task->total_xfer_len = xfer; - task->num_scatter = num; + task->num_scatter = si; } task->data_dir = qc->dma_dir; - task->scatter = qc->__sg; + task->scatter = qc->sg; task->ata_task.retry_count = 1; task->task_state_flags = SAS_TASK_STATE_PENDING; qc->lldd_task = task; @@ -200,7 +198,7 @@ static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc) case ATA_PROT_NCQ: task->ata_task.use_ncq = 1; /* fall through */ - case ATA_PROT_ATAPI_DMA: + case ATAPI_PROT_DMA: case ATA_PROT_DMA: task->ata_task.dma_xfer = 1; break; diff --git a/include/linux/ata.h b/include/linux/ata.h index e672e80..78bbaca 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -286,9 +286,10 @@ enum { ATA_CBL_NONE = 0, ATA_CBL_PATA40 = 1, ATA_CBL_PATA80 = 2, - ATA_CBL_PATA40_SHORT = 3, /* 40 wire cable to high UDMA spec */ - ATA_CBL_PATA_UNK = 4, - ATA_CBL_SATA = 5, + ATA_CBL_PATA40_SHORT = 3, /* 40 wire cable to high UDMA spec */ + ATA_CBL_PATA_UNK = 4, /* don't know, maybe 80c? */ + ATA_CBL_PATA_IGN = 5, /* don't know, ignore cable handling */ + ATA_CBL_SATA = 6, /* SATA Status and Control Registers */ SCR_STATUS = 0, @@ -324,6 +325,13 @@ enum { ATA_TFLAG_LBA = (1 << 4), /* enable LBA */ ATA_TFLAG_FUA = (1 << 5), /* enable FUA */ ATA_TFLAG_POLLING = (1 << 6), /* set nIEN to 1 and use polling */ + + /* protocol flags */ + ATA_PROT_FLAG_PIO = (1 << 0), /* is PIO */ + ATA_PROT_FLAG_DMA = (1 << 1), /* is DMA */ + ATA_PROT_FLAG_DATA = ATA_PROT_FLAG_PIO | ATA_PROT_FLAG_DMA, + ATA_PROT_FLAG_NCQ = (1 << 2), /* is NCQ */ + ATA_PROT_FLAG_ATAPI = (1 << 3), /* is ATAPI */ }; enum ata_tf_protocols { @@ -333,9 +341,9 @@ enum ata_tf_protocols { ATA_PROT_PIO, /* PIO data xfer */ ATA_PROT_DMA, /* DMA */ ATA_PROT_NCQ, /* NCQ */ - ATA_PROT_ATAPI, /* packet command, PIO data xfer*/ - ATA_PROT_ATAPI_NODATA, /* packet command, no data */ - ATA_PROT_ATAPI_DMA, /* packet command with special DMA sauce */ + ATAPI_PROT_NODATA, /* packet command, no data */ + ATAPI_PROT_PIO, /* packet command, PIO data xfer*/ + ATAPI_PROT_DMA, /* packet command with special DMA sauce */ }; enum ata_ioctls { @@ -346,8 +354,8 @@ enum ata_ioctls { /* core structures */ struct ata_prd { - u32 addr; - u32 flags_len; + __le32 addr; + __le32 flags_len; }; struct ata_taskfile { @@ -373,13 +381,69 @@ struct ata_taskfile { u8 command; /* IO operation */ }; +/* + * protocol tests + */ +static inline unsigned int ata_prot_flags(u8 prot) +{ + switch (prot) { + case ATA_PROT_NODATA: + return 0; + case ATA_PROT_PIO: + return ATA_PROT_FLAG_PIO; + case ATA_PROT_DMA: + return ATA_PROT_FLAG_DMA; + case ATA_PROT_NCQ: + return ATA_PROT_FLAG_DMA | ATA_PROT_FLAG_NCQ; + case ATAPI_PROT_NODATA: + return ATA_PROT_FLAG_ATAPI; + case ATAPI_PROT_PIO: + return ATA_PROT_FLAG_ATAPI | ATA_PROT_FLAG_PIO; + case ATAPI_PROT_DMA: + return ATA_PROT_FLAG_ATAPI | ATA_PROT_FLAG_DMA; + } + return 0; +} + +static inline int ata_is_atapi(u8 prot) +{ + return ata_prot_flags(prot) & ATA_PROT_FLAG_ATAPI; +} + +static inline int ata_is_nodata(u8 prot) +{ + return !(ata_prot_flags(prot) & ATA_PROT_FLAG_DATA); +} + +static inline int ata_is_pio(u8 prot) +{ + return ata_prot_flags(prot) & ATA_PROT_FLAG_PIO; +} + +static inline int ata_is_dma(u8 prot) +{ + return ata_prot_flags(prot) & ATA_PROT_FLAG_DMA; +} + +static inline int ata_is_ncq(u8 prot) +{ + return ata_prot_flags(prot) & ATA_PROT_FLAG_NCQ; +} + +static inline int ata_is_data(u8 prot) +{ + return ata_prot_flags(prot) & ATA_PROT_FLAG_DATA; +} + +/* + * id tests + */ #define ata_id_is_ata(id) (((id)[0] & (1 << 15)) == 0) #define ata_id_has_lba(id) ((id)[49] & (1 << 9)) #define ata_id_has_dma(id) ((id)[49] & (1 << 8)) #define ata_id_has_ncq(id) ((id)[76] & (1 << 8)) #define ata_id_queue_depth(id) (((id)[75] & 0x1f) + 1) #define ata_id_removeable(id) ((id)[0] & (1 << 7)) -#define ata_id_has_dword_io(id) ((id)[48] & (1 << 0)) #define ata_id_has_atapi_AN(id) \ ( (((id)[76] != 0x0000) && ((id)[76] != 0xffff)) && \ ((id)[78] & (1 << 5)) ) @@ -415,6 +479,7 @@ static inline bool ata_id_has_dipm(const u16 *id) return val & (1 << 3); } + static inline int ata_id_has_fua(const u16 *id) { if ((id[84] & 0xC000) != 0x4000) @@ -519,6 +584,26 @@ static inline int ata_id_is_sata(const u16 *id) return ata_id_major_version(id) >= 5 && id[93] == 0; } +static inline int ata_id_has_tpm(const u16 *id) +{ + /* The TPM bits are only valid on ATA8 */ + if (ata_id_major_version(id) < 8) + return 0; + if ((id[48] & 0xC000) != 0x4000) + return 0; + return id[48] & (1 << 0); +} + +static inline int ata_id_has_dword_io(const u16 *id) +{ + /* ATA 8 reuses this flag for "trusted" computing */ + if (ata_id_major_version(id) > 7) + return 0; + if (id[48] & (1 << 0)) + return 1; + return 0; +} + static inline int ata_id_current_chs_valid(const u16 *id) { /* For ATA-1 devices, if the INITIALIZE DEVICE PARAMETERS command @@ -574,13 +659,6 @@ static inline int atapi_command_packet_set(const u16 *dev_id) return (dev_id[0] >> 8) & 0x1f; } -static inline int is_atapi_taskfile(const struct ata_taskfile *tf) -{ - return (tf->protocol == ATA_PROT_ATAPI) || - (tf->protocol == ATA_PROT_ATAPI_NODATA) || - (tf->protocol == ATA_PROT_ATAPI_DMA); -} - static inline int is_multi_taskfile(struct ata_taskfile *tf) { return (tf->command == ATA_CMD_READ_MULTI) || diff --git a/include/linux/cdrom.h b/include/linux/cdrom.h index c6d3e22..fcdc11b 100644 --- a/include/linux/cdrom.h +++ b/include/linux/cdrom.h @@ -451,6 +451,7 @@ struct cdrom_generic_command #define GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1e #define GPCMD_READ_10 0x28 #define GPCMD_READ_12 0xa8 +#define GPCMD_READ_BUFFER 0x3c #define GPCMD_READ_BUFFER_CAPACITY 0x5c #define GPCMD_READ_CDVD_CAPACITY 0x25 #define GPCMD_READ_CD 0xbe @@ -480,7 +481,9 @@ struct cdrom_generic_command #define GPCMD_TEST_UNIT_READY 0x00 #define GPCMD_VERIFY_10 0x2f #define GPCMD_WRITE_10 0x2a +#define GPCMD_WRITE_12 0xaa #define GPCMD_WRITE_AND_VERIFY_10 0x2e +#define GPCMD_WRITE_BUFFER 0x3b /* This is listed as optional in ATAPI 2.6, but is (curiously) * missing from Mt. Fuji, Table 57. It _is_ mentioned in Mt. Fuji * Table 377 as an MMC command for SCSi devices though... Most ATAPI diff --git a/include/linux/libata.h b/include/linux/libata.h index 124033c..ccb0556 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -35,6 +35,7 @@ #include #include #include +#include /* * Define if arch has non-standard setup. This is a _PCI_ standard @@ -143,10 +144,11 @@ enum { ATA_DFLAG_NCQ_OFF = (1 << 13), /* device limited to non-NCQ mode */ ATA_DFLAG_SPUNDOWN = (1 << 14), /* XXX: for spindown_compat */ ATA_DFLAG_SLEEPING = (1 << 15), /* device is sleeping */ - ATA_DFLAG_INIT_MASK = (1 << 16) - 1, + ATA_DFLAG_DUBIOUS_XFER = (1 << 16), /* data transfer not verified */ + ATA_DFLAG_INIT_MASK = (1 << 24) - 1, - ATA_DFLAG_DETACH = (1 << 16), - ATA_DFLAG_DETACHED = (1 << 17), + ATA_DFLAG_DETACH = (1 << 24), + ATA_DFLAG_DETACHED = (1 << 25), ATA_DEV_UNKNOWN = 0, /* unknown device */ ATA_DEV_ATA = 1, /* ATA device */ @@ -217,9 +219,7 @@ enum { /* struct ata_queued_cmd flags */ ATA_QCFLAG_ACTIVE = (1 << 0), /* cmd not yet ack'd to scsi lyer */ - ATA_QCFLAG_SG = (1 << 1), /* have s/g table? */ - ATA_QCFLAG_SINGLE = (1 << 2), /* no s/g, just a single buffer */ - ATA_QCFLAG_DMAMAP = ATA_QCFLAG_SG | ATA_QCFLAG_SINGLE, + ATA_QCFLAG_DMAMAP = (1 << 1), /* SG table is DMA mapped */ ATA_QCFLAG_IO = (1 << 3), /* standard IO command */ ATA_QCFLAG_RESULT_TF = (1 << 4), /* result TF requested */ ATA_QCFLAG_CLEAR_EXCL = (1 << 5), /* clear excl_link on completion */ @@ -266,19 +266,15 @@ enum { PORT_DISABLED = 2, /* encoding various smaller bitmaps into a single - * unsigned int bitmap + * unsigned long bitmap */ - ATA_BITS_PIO = 7, - ATA_BITS_MWDMA = 5, - ATA_BITS_UDMA = 8, + ATA_NR_PIO_MODES = 7, + ATA_NR_MWDMA_MODES = 5, + ATA_NR_UDMA_MODES = 8, ATA_SHIFT_PIO = 0, - ATA_SHIFT_MWDMA = ATA_SHIFT_PIO + ATA_BITS_PIO, - ATA_SHIFT_UDMA = ATA_SHIFT_MWDMA + ATA_BITS_MWDMA, - - ATA_MASK_PIO = ((1 << ATA_BITS_PIO) - 1) << ATA_SHIFT_PIO, - ATA_MASK_MWDMA = ((1 << ATA_BITS_MWDMA) - 1) << ATA_SHIFT_MWDMA, - ATA_MASK_UDMA = ((1 << ATA_BITS_UDMA) - 1) << ATA_SHIFT_UDMA, + ATA_SHIFT_MWDMA = ATA_SHIFT_PIO + ATA_NR_PIO_MODES, + ATA_SHIFT_UDMA = ATA_SHIFT_MWDMA + ATA_NR_MWDMA_MODES, /* size of buffer to pad xfers ending on unaligned boundaries */ ATA_DMA_PAD_SZ = 4, @@ -349,6 +345,21 @@ enum { ATA_DMA_MASK_ATA = (1 << 0), /* DMA on ATA Disk */ ATA_DMA_MASK_ATAPI = (1 << 1), /* DMA on ATAPI */ ATA_DMA_MASK_CFA = (1 << 2), /* DMA on CF Card */ + + /* ATAPI command types */ + ATAPI_READ = 0, /* READs */ + ATAPI_WRITE = 1, /* WRITEs */ + ATAPI_READ_CD = 2, /* READ CD [MSF] */ + ATAPI_MISC = 3, /* the rest */ +}; + +enum ata_xfer_mask { + ATA_MASK_PIO = ((1LU << ATA_NR_PIO_MODES) - 1) + << ATA_SHIFT_PIO, + ATA_MASK_MWDMA = ((1LU << ATA_NR_MWDMA_MODES) - 1) + << ATA_SHIFT_MWDMA, + ATA_MASK_UDMA = ((1LU << ATA_NR_UDMA_MODES) - 1) + << ATA_SHIFT_UDMA, }; enum hsm_task_states { @@ -447,7 +458,7 @@ struct ata_queued_cmd { unsigned int tag; unsigned int n_elem; unsigned int n_iter; - unsigned int orig_n_elem; + unsigned int mapped_n_elem; int dma_dir; @@ -455,17 +466,18 @@ struct ata_queued_cmd { unsigned int sect_size; unsigned int nbytes; + unsigned int raw_nbytes; unsigned int curbytes; struct scatterlist *cursg; unsigned int cursg_ofs; + struct scatterlist *last_sg; + struct scatterlist saved_last_sg; struct scatterlist sgent; - struct scatterlist pad_sgent; - void *buf_virt; + struct scatterlist extra_sg[2]; - /* DO NOT iterate over __sg manually, use ata_for_each_sg() */ - struct scatterlist *__sg; + struct scatterlist *sg; unsigned int err_mask; struct ata_taskfile result_tf; @@ -482,7 +494,7 @@ struct ata_port_stats { }; struct ata_ering_entry { - int is_io; + unsigned int eflags; unsigned int err_mask; u64 timestamp; }; @@ -522,9 +534,9 @@ struct ata_device { unsigned int cdb_len; /* per-dev xfer mask */ - unsigned int pio_mask; - unsigned int mwdma_mask; - unsigned int udma_mask; + unsigned long pio_mask; + unsigned long mwdma_mask; + unsigned long udma_mask; /* for CHS addressing */ u16 cylinders; /* Number of cylinders */ @@ -560,6 +572,8 @@ struct ata_eh_context { int tries[ATA_MAX_DEVICES]; unsigned int classes[ATA_MAX_DEVICES]; unsigned int did_probe_mask; + unsigned int saved_ncq_enabled; + u8 saved_xfer_mode[ATA_MAX_DEVICES]; }; struct ata_acpi_drive @@ -686,7 +700,8 @@ struct ata_port_operations { void (*bmdma_setup) (struct ata_queued_cmd *qc); void (*bmdma_start) (struct ata_queued_cmd *qc); - void (*data_xfer) (struct ata_device *, unsigned char *, unsigned int, int); + unsigned int (*data_xfer) (struct ata_device *dev, unsigned char *buf, + unsigned int buflen, int rw); int (*qc_defer) (struct ata_queued_cmd *qc); void (*qc_prep) (struct ata_queued_cmd *qc); @@ -832,8 +847,6 @@ extern int ata_busy_sleep(struct ata_port *ap, unsigned long timeout_pat, unsigned long timeout); extern void ata_wait_after_reset(struct ata_port *ap, unsigned long deadline); extern int ata_wait_ready(struct ata_port *ap, unsigned long deadline); -extern void ata_port_queue_task(struct ata_port *ap, work_func_t fn, - void *data, unsigned long delay); extern u32 ata_wait_register(void __iomem *reg, u32 mask, u32 val, unsigned long interval_msec, unsigned long timeout_msec); @@ -848,6 +861,16 @@ extern void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf); extern void ata_tf_to_fis(const struct ata_taskfile *tf, u8 pmp, int is_cmd, u8 *fis); extern void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf); +extern unsigned long ata_pack_xfermask(unsigned long pio_mask, + unsigned long mwdma_mask, unsigned long udma_mask); +extern void ata_unpack_xfermask(unsigned long xfer_mask, + unsigned long *pio_mask, unsigned long *mwdma_mask, + unsigned long *udma_mask); +extern u8 ata_xfer_mask2mode(unsigned long xfer_mask); +extern unsigned long ata_xfer_mode2mask(u8 xfer_mode); +extern int ata_xfer_mode2shift(unsigned long xfer_mode); +extern const char *ata_mode_string(unsigned long xfer_mask); +extern unsigned long ata_id_xfermask(const u16 *id); extern void ata_noop_dev_select(struct ata_port *ap, unsigned int device); extern void ata_std_dev_select(struct ata_port *ap, unsigned int device); extern u8 ata_check_status(struct ata_port *ap); @@ -856,17 +879,15 @@ extern void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf) extern int ata_port_start(struct ata_port *ap); extern int ata_sff_port_start(struct ata_port *ap); extern irqreturn_t ata_interrupt(int irq, void *dev_instance); -extern void ata_data_xfer(struct ata_device *adev, unsigned char *buf, - unsigned int buflen, int write_data); -extern void ata_data_xfer_noirq(struct ata_device *adev, unsigned char *buf, - unsigned int buflen, int write_data); +extern unsigned int ata_data_xfer(struct ata_device *dev, + unsigned char *buf, unsigned int buflen, int rw); +extern unsigned int ata_data_xfer_noirq(struct ata_device *dev, + unsigned char *buf, unsigned int buflen, int rw); extern int ata_std_qc_defer(struct ata_queued_cmd *qc); extern void ata_dumb_qc_prep(struct ata_queued_cmd *qc); extern void ata_qc_prep(struct ata_queued_cmd *qc); extern void ata_noop_qc_prep(struct ata_queued_cmd *qc); extern unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc); -extern void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, - unsigned int buflen); extern void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg, unsigned int n_elem); extern unsigned int ata_dev_classify(const struct ata_taskfile *tf); @@ -875,7 +896,6 @@ extern void ata_id_string(const u16 *id, unsigned char *s, unsigned int ofs, unsigned int len); extern void ata_id_c_string(const u16 *id, unsigned char *s, unsigned int ofs, unsigned int len); -extern void ata_id_to_dma_mode(struct ata_device *dev, u8 unknown); extern void ata_bmdma_setup(struct ata_queued_cmd *qc); extern void ata_bmdma_start(struct ata_queued_cmd *qc); extern void ata_bmdma_stop(struct ata_queued_cmd *qc); @@ -910,6 +930,7 @@ extern u8 ata_irq_on(struct ata_port *ap); extern int ata_cable_40wire(struct ata_port *ap); extern int ata_cable_80wire(struct ata_port *ap); extern int ata_cable_sata(struct ata_port *ap); +extern int ata_cable_ignore(struct ata_port *ap); extern int ata_cable_unknown(struct ata_port *ap); /* @@ -917,11 +938,13 @@ extern int ata_cable_unknown(struct ata_port *ap); */ extern unsigned int ata_pio_need_iordy(const struct ata_device *); +extern const struct ata_timing *ata_timing_find_mode(u8 xfer_mode); extern int ata_timing_compute(struct ata_device *, unsigned short, struct ata_timing *, int, int); extern void ata_timing_merge(const struct ata_timing *, const struct ata_timing *, struct ata_timing *, unsigned int); +extern u8 ata_timing_cycle2mode(unsigned int xfer_shift, int cycle); enum { ATA_TIMING_SETUP = (1 << 0), @@ -948,15 +971,40 @@ static inline const struct ata_acpi_gtm *ata_acpi_init_gtm(struct ata_port *ap) return &ap->__acpi_init_gtm; return NULL; } -extern int ata_acpi_cbl_80wire(struct ata_port *ap); int ata_acpi_stm(struct ata_port *ap, const struct ata_acpi_gtm *stm); int ata_acpi_gtm(struct ata_port *ap, struct ata_acpi_gtm *stm); +unsigned long ata_acpi_gtm_xfermask(struct ata_device *dev, + const struct ata_acpi_gtm *gtm); +int ata_acpi_cbl_80wire(struct ata_port *ap, const struct ata_acpi_gtm *gtm); #else static inline const struct ata_acpi_gtm *ata_acpi_init_gtm(struct ata_port *ap) { return NULL; } -static inline int ata_acpi_cbl_80wire(struct ata_port *ap) { return 0; } + +static inline int ata_acpi_stm(const struct ata_port *ap, + struct ata_acpi_gtm *stm) +{ + return -ENOSYS; +} + +static inline int ata_acpi_gtm(const struct ata_port *ap, + struct ata_acpi_gtm *stm) +{ + return -ENOSYS; +} + +static inline unsigned int ata_acpi_gtm_xfermask(struct ata_device *dev, + const struct ata_acpi_gtm *gtm) +{ + return 0; +} + +static inline int ata_acpi_cbl_80wire(struct ata_port *ap, + const struct ata_acpi_gtm *gtm) +{ + return 0; +} #endif #ifdef CONFIG_PCI @@ -986,7 +1034,8 @@ extern int ata_pci_prepare_sff_host(struct pci_dev *pdev, const struct ata_port_info * const * ppi, struct ata_host **r_host); extern int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits); -extern unsigned long ata_pci_default_filter(struct ata_device *, unsigned long); +extern unsigned long ata_pci_default_filter(struct ata_device *dev, + unsigned long xfer_mask); #endif /* CONFIG_PCI */ /* @@ -1074,35 +1123,6 @@ extern void ata_port_pbar_desc(struct ata_port *ap, int bar, ssize_t offset, const char *name); #endif -/* - * qc helpers - */ -static inline struct scatterlist * -ata_qc_first_sg(struct ata_queued_cmd *qc) -{ - qc->n_iter = 0; - if (qc->n_elem) - return qc->__sg; - if (qc->pad_len) - return &qc->pad_sgent; - return NULL; -} - -static inline struct scatterlist * -ata_qc_next_sg(struct scatterlist *sg, struct ata_queued_cmd *qc) -{ - if (sg == &qc->pad_sgent) - return NULL; - if (++qc->n_iter < qc->n_elem) - return sg_next(sg); - if (qc->pad_len) - return &qc->pad_sgent; - return NULL; -} - -#define ata_for_each_sg(sg, qc) \ - for (sg = ata_qc_first_sg(qc); sg; sg = ata_qc_next_sg(sg, qc)) - static inline unsigned int ata_tag_valid(unsigned int tag) { return (tag < ATA_MAX_QUEUE) ? 1 : 0; @@ -1337,15 +1357,17 @@ static inline void ata_tf_init(struct ata_device *dev, struct ata_taskfile *tf) static inline void ata_qc_reinit(struct ata_queued_cmd *qc) { qc->dma_dir = DMA_NONE; - qc->__sg = NULL; + qc->sg = NULL; qc->flags = 0; qc->cursg = NULL; qc->cursg_ofs = 0; - qc->nbytes = qc->curbytes = 0; + qc->nbytes = qc->raw_nbytes = qc->curbytes = 0; qc->n_elem = 0; + qc->mapped_n_elem = 0; qc->n_iter = 0; qc->err_mask = 0; qc->pad_len = 0; + qc->last_sg = NULL; qc->sect_size = ATA_SECT_SIZE; ata_tf_init(qc->dev, &qc->tf); @@ -1362,6 +1384,27 @@ static inline int ata_try_flush_cache(const struct ata_device *dev) ata_id_has_flush_ext(dev->id); } +static inline int atapi_cmd_type(u8 opcode) +{ + switch (opcode) { + case GPCMD_READ_10: + case GPCMD_READ_12: + return ATAPI_READ; + + case GPCMD_WRITE_10: + case GPCMD_WRITE_12: + case GPCMD_WRITE_AND_VERIFY_10: + return ATAPI_WRITE; + + case GPCMD_READ_CD: + case GPCMD_READ_CD_MSF: + return ATAPI_READ_CD; + + default: + return ATAPI_MISC; + } +} + static inline unsigned int ac_err_mask(u8 status) { if (status & (ATA_BUSY | ATA_DRQ))