From ae8d4ee7ff429136c8b482c3b38ed994c021d3fc Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sun, 4 Nov 2007 22:05:49 -0500 Subject: 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 --- include/linux/ata.h | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/ata.h b/include/linux/ata.h index e672e80202a..3fbe6d7784a 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -379,7 +379,6 @@ struct ata_taskfile { #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 +414,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 +519,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 -- cgit v1.2.3 From f20ded38aa54b92dd0af32578b8916d0aa2d9e05 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 27 Nov 2007 19:28:52 +0900 Subject: 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 --- include/linux/libata.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 124033cb5e9..ca347b01864 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -143,10 +143,10 @@ 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_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 */ -- cgit v1.2.3 From 405e66b38797875e80669eaf72d313dbb76533c3 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 27 Nov 2007 19:28:53 +0900 Subject: 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 --- include/linux/ata.h | 71 +++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 64 insertions(+), 7 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ata.h b/include/linux/ata.h index 3fbe6d7784a..43fecf62773 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -324,6 +324,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 { @@ -373,6 +380,63 @@ 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 ATA_PROT_ATAPI_NODATA: + return ATA_PROT_FLAG_ATAPI; + case ATA_PROT_ATAPI: + return ATA_PROT_FLAG_ATAPI | ATA_PROT_FLAG_PIO; + case ATA_PROT_ATAPI_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)) @@ -594,13 +658,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) || -- cgit v1.2.3 From 3884f7b0a8382b89d8ca5da23bd98e3e15fc805b Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 27 Nov 2007 19:28:56 +0900 Subject: 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 --- include/linux/libata.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index ca347b01864..74f1255e252 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -482,7 +482,7 @@ struct ata_port_stats { }; struct ata_ering_entry { - int is_io; + unsigned int eflags; unsigned int err_mask; u64 timestamp; }; -- cgit v1.2.3 From 00115e0f5bc3bfdf3f3855ad89c8895f10458f92 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 27 Nov 2007 19:28:58 +0900 Subject: 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 --- include/linux/libata.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 74f1255e252..131fb6625e1 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -143,6 +143,7 @@ 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_DUBIOUS_XFER = (1 << 16), /* data transfer not verified */ ATA_DFLAG_INIT_MASK = (1 << 24) - 1, ATA_DFLAG_DETACH = (1 << 24), @@ -560,6 +561,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 -- cgit v1.2.3 From 6357357cae7794dcb89cace758108dec612e7ed5 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 27 Nov 2007 19:43:39 +0900 Subject: 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 --- include/linux/libata.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 131fb6625e1..083dd77b120 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -851,6 +851,15 @@ 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 int ata_pack_xfermask(unsigned int pio_mask, + unsigned int mwdma_mask, unsigned int udma_mask); +extern void ata_unpack_xfermask(unsigned int xfer_mask, unsigned int *pio_mask, + unsigned int *mwdma_mask, unsigned int *udma_mask); +extern u8 ata_xfer_mask2mode(unsigned int xfer_mask); +extern unsigned int ata_xfer_mode2mask(u8 xfer_mode); +extern int ata_xfer_mode2shift(unsigned int xfer_mode); +extern const char *ata_mode_string(unsigned int xfer_mask); +extern unsigned int 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); @@ -920,6 +929,7 @@ 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 *, -- cgit v1.2.3 From 70cd071e4ecc06c985189665af75c108601fd5a3 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 27 Nov 2007 19:43:40 +0900 Subject: 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 --- include/linux/libata.h | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 083dd77b120..e2ed3bac8c5 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -269,17 +269,20 @@ enum { /* encoding various smaller bitmaps into a single * unsigned int 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, + + ATA_MASK_PIO = ((1 << ATA_NR_PIO_MODES) - 1) + << ATA_SHIFT_PIO, + ATA_MASK_MWDMA = ((1 << ATA_NR_MWDMA_MODES) - 1) + << ATA_SHIFT_MWDMA, + ATA_MASK_UDMA = ((1 << ATA_NR_UDMA_MODES) - 1) + << ATA_SHIFT_UDMA, /* size of buffer to pad xfers ending on unaligned boundaries */ ATA_DMA_PAD_SZ = 4, -- cgit v1.2.3 From 9d3501ab962b1506d93974faf8509251b4a85fbc Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 27 Nov 2007 19:43:41 +0900 Subject: 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 --- include/linux/libata.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index e2ed3bac8c5..d33702fe78f 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -890,7 +890,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); -- cgit v1.2.3 From 7dc951aefdc1dc20228691b04867fb6195864d67 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 27 Nov 2007 19:43:42 +0900 Subject: 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 --- include/linux/libata.h | 46 +++++++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 21 deletions(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index d33702fe78f..d9eb20c67bb 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -267,7 +267,7 @@ enum { PORT_DISABLED = 2, /* encoding various smaller bitmaps into a single - * unsigned int bitmap + * unsigned long bitmap */ ATA_NR_PIO_MODES = 7, ATA_NR_MWDMA_MODES = 5, @@ -277,13 +277,6 @@ enum { ATA_SHIFT_MWDMA = ATA_SHIFT_PIO + ATA_NR_PIO_MODES, ATA_SHIFT_UDMA = ATA_SHIFT_MWDMA + ATA_NR_MWDMA_MODES, - ATA_MASK_PIO = ((1 << ATA_NR_PIO_MODES) - 1) - << ATA_SHIFT_PIO, - ATA_MASK_MWDMA = ((1 << ATA_NR_MWDMA_MODES) - 1) - << ATA_SHIFT_MWDMA, - ATA_MASK_UDMA = ((1 << ATA_NR_UDMA_MODES) - 1) - << ATA_SHIFT_UDMA, - /* size of buffer to pad xfers ending on unaligned boundaries */ ATA_DMA_PAD_SZ = 4, ATA_DMA_PAD_BUF_SZ = ATA_DMA_PAD_SZ * ATA_MAX_QUEUE, @@ -355,6 +348,15 @@ enum { ATA_DMA_MASK_CFA = (1 << 2), /* DMA on CF Card */ }; +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 { HSM_ST_IDLE, /* no command on going */ HSM_ST_FIRST, /* (waiting the device to) @@ -526,9 +528,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 */ @@ -854,15 +856,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 int ata_pack_xfermask(unsigned int pio_mask, - unsigned int mwdma_mask, unsigned int udma_mask); -extern void ata_unpack_xfermask(unsigned int xfer_mask, unsigned int *pio_mask, - unsigned int *mwdma_mask, unsigned int *udma_mask); -extern u8 ata_xfer_mask2mode(unsigned int xfer_mask); -extern unsigned int ata_xfer_mode2mask(u8 xfer_mode); -extern int ata_xfer_mode2shift(unsigned int xfer_mode); -extern const char *ata_mode_string(unsigned int xfer_mask); -extern unsigned int ata_id_xfermask(const u16 *id); +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); @@ -1001,7 +1004,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 */ /* -- cgit v1.2.3 From c88f90c3779cd5e710f2acdf59ad2bd0380de98d Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 27 Nov 2007 19:43:48 +0900 Subject: 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 --- include/linux/ata.h | 7 ++++--- include/linux/libata.h | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ata.h b/include/linux/ata.h index 43fecf62773..c17e9404c88 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, diff --git a/include/linux/libata.h b/include/linux/libata.h index d9eb20c67bb..bdb7c6e1399 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -927,6 +927,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); /* -- cgit v1.2.3 From 7c77fa4d51b1480bcec2e898c94d6912fe063c16 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 18 Dec 2007 16:33:03 +0900 Subject: 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 --- include/linux/libata.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index bdb7c6e1399..8022e5b2224 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -961,6 +961,10 @@ enum { /* libata-acpi.c */ #ifdef CONFIG_ATA_ACPI +extern const unsigned int ata_acpi_pio_cycle[7]; +extern const unsigned int ata_acpi_mwdma_cycle[5]; +extern const unsigned int ata_acpi_udma_cycle[7]; + static inline const struct ata_acpi_gtm *ata_acpi_init_gtm(struct ata_port *ap) { if (ap->pflags & ATA_PFLAG_INIT_GTM_VALID) @@ -970,12 +974,33 @@ static inline const struct ata_acpi_gtm *ata_acpi_init_gtm(struct ata_port *ap) 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); + #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; +} #endif #ifdef CONFIG_PCI -- cgit v1.2.3 From a0f79b929acaba10d4780acd2543eff20bf4b5b0 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 18 Dec 2007 16:33:05 +0900 Subject: 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 --- include/linux/libata.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 8022e5b2224..8ede93b5c7a 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -941,6 +941,7 @@ extern int ata_timing_compute(struct ata_device *, unsigned short, 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), @@ -961,10 +962,6 @@ enum { /* libata-acpi.c */ #ifdef CONFIG_ATA_ACPI -extern const unsigned int ata_acpi_pio_cycle[7]; -extern const unsigned int ata_acpi_mwdma_cycle[5]; -extern const unsigned int ata_acpi_udma_cycle[7]; - static inline const struct ata_acpi_gtm *ata_acpi_init_gtm(struct ata_port *ap) { if (ap->pflags & ATA_PFLAG_INIT_GTM_VALID) -- cgit v1.2.3 From 021ee9a6da1cfc57f6a6c769c3c898bdd4753108 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 18 Dec 2007 16:33:06 +0900 Subject: 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 --- include/linux/libata.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 8ede93b5c7a..cc4eaef6f88 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -968,18 +968,16 @@ 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) @@ -998,6 +996,12 @@ static inline unsigned int ata_acpi_gtm_xfermask(struct ata_device *dev, { 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 -- cgit v1.2.3 From 537b53c1692960b8b3b0324e886fbe48cb9e5c00 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 5 Dec 2007 16:43:04 +0900 Subject: 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 --- include/linux/cdrom.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/cdrom.h b/include/linux/cdrom.h index c6d3e22c062..fcdc11b9609 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 -- cgit v1.2.3 From 0dc36888d4422140f9eaf50f24953ec109f750a3 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 18 Dec 2007 16:34:43 -0500 Subject: 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 --- include/linux/ata.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ata.h b/include/linux/ata.h index c17e9404c88..bc55471a4b2 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -341,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 { @@ -395,11 +395,11 @@ static inline unsigned int ata_prot_flags(u8 prot) return ATA_PROT_FLAG_DMA; case ATA_PROT_NCQ: return ATA_PROT_FLAG_DMA | ATA_PROT_FLAG_NCQ; - case ATA_PROT_ATAPI_NODATA: + case ATAPI_PROT_NODATA: return ATA_PROT_FLAG_ATAPI; - case ATA_PROT_ATAPI: + case ATAPI_PROT_PIO: return ATA_PROT_FLAG_ATAPI | ATA_PROT_FLAG_PIO; - case ATA_PROT_ATAPI_DMA: + case ATAPI_PROT_DMA: return ATA_PROT_FLAG_ATAPI | ATA_PROT_FLAG_DMA; } return 0; -- cgit v1.2.3 From ceb0c642624f634c5b4f46b0e22df19be87a2e53 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 5 Dec 2007 16:43:06 +0900 Subject: 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 --- include/linux/libata.h | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index cc4eaef6f88..03afcd63202 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 @@ -346,6 +347,12 @@ 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 { @@ -1408,6 +1415,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)) -- cgit v1.2.3 From 55dba3120fbcbea6800f9a18503d25f73212a347 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 5 Dec 2007 16:43:07 +0900 Subject: 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 --- include/linux/libata.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 03afcd63202..7fa96cb4f6d 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -701,7 +701,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); @@ -881,10 +882,10 @@ 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); -- cgit v1.2.3 From 001102d7859be0e7f7b9f2d62b841f2c0f9c2640 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 5 Dec 2007 16:43:09 +0900 Subject: 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 --- include/linux/libata.h | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 7fa96cb4f6d..acd90ad7841 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -219,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 */ @@ -475,7 +473,6 @@ struct ata_queued_cmd { struct scatterlist sgent; struct scatterlist pad_sgent; - void *buf_virt; /* DO NOT iterate over __sg manually, use ata_for_each_sg() */ struct scatterlist *__sg; @@ -891,8 +888,6 @@ 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); -- cgit v1.2.3 From ff2aeb1eb64c8a4770a6304f9addbae9f9828646 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 5 Dec 2007 16:43:11 +0900 Subject: 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 --- include/linux/libata.h | 42 ++++++++---------------------------------- 1 file changed, 8 insertions(+), 34 deletions(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index acd90ad7841..162f8b5509a 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -458,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; @@ -471,11 +471,12 @@ struct ata_queued_cmd { struct scatterlist *cursg; unsigned int cursg_ofs; + struct scatterlist *last_sg; + struct scatterlist saved_last_sg; struct scatterlist sgent; - struct scatterlist pad_sgent; + 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; @@ -1123,35 +1124,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; @@ -1386,15 +1358,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->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); -- cgit v1.2.3 From 0bcc65ad78ae517de16b2ca07a2891f49d44d156 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 5 Dec 2007 16:43:12 +0900 Subject: 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 --- include/linux/libata.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 162f8b5509a..7b7c78e4207 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -466,6 +466,7 @@ struct ata_queued_cmd { unsigned int sect_size; unsigned int nbytes; + unsigned int raw_nbytes; unsigned int curbytes; struct scatterlist *cursg; @@ -1362,7 +1363,7 @@ static inline void ata_qc_reinit(struct ata_queued_cmd *qc) 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; -- cgit v1.2.3 From 442eacc362c2576aac8ebfd41b99252e28e0f49c Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Wed, 19 Dec 2007 04:25:10 -0500 Subject: 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 --- include/linux/libata.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 7b7c78e4207..ccb055636f3 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -847,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); -- cgit v1.2.3 From 4ca4e439640cd1d3659cbcf60e7a73c2ae0450b3 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 30 Dec 2007 09:32:22 +0000 Subject: libata annotations and fixes Signed-off-by: Al Viro Signed-off-by: Jeff Garzik --- include/linux/ata.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ata.h b/include/linux/ata.h index bc55471a4b2..78bbacaed8c 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -354,8 +354,8 @@ enum ata_ioctls { /* core structures */ struct ata_prd { - u32 addr; - u32 flags_len; + __le32 addr; + __le32 flags_len; }; struct ata_taskfile { -- cgit v1.2.3 From 4e6b79fa61091a0ed9b0af0f573cc257772cd88d Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 18 Jan 2008 18:36:28 +0900 Subject: libata: factor out ata_pci_activate_sff_host() from ata_pci_one() Factor out ata_pci_activate_sff_host() from ata_pci_one(). This does about the same thing as ata_host_activate() but needs to be separate because SFF controllers use different and multiple IRQs in legacy mode. This will be used to make SFF LLD initialization more flexible. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index ccb055636f3..4374c427778 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1033,6 +1033,9 @@ extern int ata_pci_init_bmdma(struct ata_host *host); 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 ata_pci_activate_sff_host(struct ata_host *host, + irq_handler_t irq_handler, + struct scsi_host_template *sht); 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 *dev, unsigned long xfer_mask); -- cgit v1.2.3 From 5e8f757cb2e0f67bf43f71d5180a8bf0ab3484eb Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sat, 19 Jan 2008 16:07:58 +0000 Subject: ata_generic: Cenatek support Not much to do here. It's an ata memory as disk. Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik --- include/linux/pci_ids.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 7f2215139e9..1fbd0256e86 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2066,6 +2066,9 @@ #define PCI_VENDOR_ID_NETCELL 0x169c #define PCI_DEVICE_ID_REVOLUTION 0x0044 +#define PCI_VENDOR_ID_CENATEK 0x16CA +#define PCI_DEVICE_ID_CENATEK_IDE 0x0001 + #define PCI_VENDOR_ID_VITESSE 0x1725 #define PCI_DEVICE_ID_VITESSE_VSC7174 0x7174 -- cgit v1.2.3