aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorJeff Garzik <jgarzik@pobox.com>2005-10-05 07:13:30 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-10-05 07:13:30 -0400
commitcedc9a478d8c6265879dc3839ef3d4849a709184 (patch)
tree0c8e0fbffdb6081381c01b8cfd93c95b168acb44 /include
parented39f731ab2e77e58122232f6e27333331d7793d (diff)
libata: fix ATAPI DMA alignment issues
ATAPI needs to be padded to next 4 byte boundary, if misaligned. Original work by me, many fixes from Tejun Heo.
Diffstat (limited to 'include')
-rw-r--r--include/linux/libata.h27
1 files changed, 26 insertions, 1 deletions
diff --git a/include/linux/libata.h b/include/linux/libata.h
index ceee1fc42c60..3ab67622ef93 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -154,6 +154,10 @@ enum {
154 ATA_SHIFT_UDMA = 0, 154 ATA_SHIFT_UDMA = 0,
155 ATA_SHIFT_MWDMA = 8, 155 ATA_SHIFT_MWDMA = 8,
156 ATA_SHIFT_PIO = 11, 156 ATA_SHIFT_PIO = 11,
157
158 /* size of buffer to pad xfers ending on unaligned boundaries */
159 ATA_DMA_PAD_SZ = 4,
160 ATA_DMA_PAD_BUF_SZ = ATA_DMA_PAD_SZ * ATA_MAX_QUEUE,
157}; 161};
158 162
159enum pio_task_states { 163enum pio_task_states {
@@ -237,9 +241,12 @@ struct ata_queued_cmd {
237 unsigned long flags; /* ATA_QCFLAG_xxx */ 241 unsigned long flags; /* ATA_QCFLAG_xxx */
238 unsigned int tag; 242 unsigned int tag;
239 unsigned int n_elem; 243 unsigned int n_elem;
244 unsigned int orig_n_elem;
240 245
241 int dma_dir; 246 int dma_dir;
242 247
248 unsigned int pad_len;
249
243 unsigned int nsect; 250 unsigned int nsect;
244 unsigned int cursect; 251 unsigned int cursect;
245 252
@@ -250,9 +257,11 @@ struct ata_queued_cmd {
250 unsigned int cursg_ofs; 257 unsigned int cursg_ofs;
251 258
252 struct scatterlist sgent; 259 struct scatterlist sgent;
260 struct scatterlist pad_sgent;
253 void *buf_virt; 261 void *buf_virt;
254 262
255 struct scatterlist *sg; 263 /* DO NOT iterate over __sg manually, use ata_for_each_sg() */
264 struct scatterlist *__sg;
256 265
257 ata_qc_cb_t complete_fn; 266 ata_qc_cb_t complete_fn;
258 267
@@ -295,6 +304,9 @@ struct ata_port {
295 struct ata_prd *prd; /* our SG list */ 304 struct ata_prd *prd; /* our SG list */
296 dma_addr_t prd_dma; /* and its DMA mapping */ 305 dma_addr_t prd_dma; /* and its DMA mapping */
297 306
307 void *pad; /* array of DMA pad buffers */
308 dma_addr_t pad_dma;
309
298 struct ata_ioports ioaddr; /* ATA cmd/ctl/dma register blocks */ 310 struct ata_ioports ioaddr; /* ATA cmd/ctl/dma register blocks */
299 311
300 u8 ctl; /* cache of ATA control register */ 312 u8 ctl; /* cache of ATA control register */
@@ -458,6 +470,19 @@ extern int pci_test_config_bits(struct pci_dev *pdev, struct pci_bits *bits);
458#endif /* CONFIG_PCI */ 470#endif /* CONFIG_PCI */
459 471
460 472
473static inline struct scatterlist *
474ata_qc_next_sg(struct scatterlist *sg, struct ata_queued_cmd *qc)
475{
476 if (sg == &qc->pad_sgent)
477 return NULL;
478 if (++sg - qc->__sg < qc->n_elem)
479 return sg;
480 return qc->pad_len ? &qc->pad_sgent : NULL;
481}
482
483#define ata_for_each_sg(sg, qc) \
484 for (sg = qc->__sg; sg; sg = ata_qc_next_sg(sg, qc))
485
461static inline unsigned int ata_tag_valid(unsigned int tag) 486static inline unsigned int ata_tag_valid(unsigned int tag)
462{ 487{
463 return (tag < ATA_MAX_QUEUE) ? 1 : 0; 488 return (tag < ATA_MAX_QUEUE) ? 1 : 0;