diff options
Diffstat (limited to 'include/linux/libata.h')
-rw-r--r-- | include/linux/libata.h | 39 |
1 files changed, 38 insertions, 1 deletions
diff --git a/include/linux/libata.h b/include/linux/libata.h index a4cce9936a80..364cd11456f6 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
@@ -155,6 +155,10 @@ enum { | |||
155 | ATA_SHIFT_UDMA = 0, | 155 | ATA_SHIFT_UDMA = 0, |
156 | ATA_SHIFT_MWDMA = 8, | 156 | ATA_SHIFT_MWDMA = 8, |
157 | ATA_SHIFT_PIO = 11, | 157 | ATA_SHIFT_PIO = 11, |
158 | |||
159 | /* size of buffer to pad xfers ending on unaligned boundaries */ | ||
160 | ATA_DMA_PAD_SZ = 4, | ||
161 | ATA_DMA_PAD_BUF_SZ = ATA_DMA_PAD_SZ * ATA_MAX_QUEUE, | ||
158 | 162 | ||
159 | /* Masks for port functions */ | 163 | /* Masks for port functions */ |
160 | ATA_PORT_PRIMARY = (1 << 0), | 164 | ATA_PORT_PRIMARY = (1 << 0), |
@@ -242,9 +246,12 @@ struct ata_queued_cmd { | |||
242 | unsigned long flags; /* ATA_QCFLAG_xxx */ | 246 | unsigned long flags; /* ATA_QCFLAG_xxx */ |
243 | unsigned int tag; | 247 | unsigned int tag; |
244 | unsigned int n_elem; | 248 | unsigned int n_elem; |
249 | unsigned int orig_n_elem; | ||
245 | 250 | ||
246 | int dma_dir; | 251 | int dma_dir; |
247 | 252 | ||
253 | unsigned int pad_len; | ||
254 | |||
248 | unsigned int nsect; | 255 | unsigned int nsect; |
249 | unsigned int cursect; | 256 | unsigned int cursect; |
250 | 257 | ||
@@ -255,9 +262,11 @@ struct ata_queued_cmd { | |||
255 | unsigned int cursg_ofs; | 262 | unsigned int cursg_ofs; |
256 | 263 | ||
257 | struct scatterlist sgent; | 264 | struct scatterlist sgent; |
265 | struct scatterlist pad_sgent; | ||
258 | void *buf_virt; | 266 | void *buf_virt; |
259 | 267 | ||
260 | struct scatterlist *sg; | 268 | /* DO NOT iterate over __sg manually, use ata_for_each_sg() */ |
269 | struct scatterlist *__sg; | ||
261 | 270 | ||
262 | ata_qc_cb_t complete_fn; | 271 | ata_qc_cb_t complete_fn; |
263 | 272 | ||
@@ -303,6 +312,9 @@ struct ata_port { | |||
303 | struct ata_prd *prd; /* our SG list */ | 312 | struct ata_prd *prd; /* our SG list */ |
304 | dma_addr_t prd_dma; /* and its DMA mapping */ | 313 | dma_addr_t prd_dma; /* and its DMA mapping */ |
305 | 314 | ||
315 | void *pad; /* array of DMA pad buffers */ | ||
316 | dma_addr_t pad_dma; | ||
317 | |||
306 | struct ata_ioports ioaddr; /* ATA cmd/ctl/dma register blocks */ | 318 | struct ata_ioports ioaddr; /* ATA cmd/ctl/dma register blocks */ |
307 | 319 | ||
308 | u8 ctl; /* cache of ATA control register */ | 320 | u8 ctl; /* cache of ATA control register */ |
@@ -505,6 +517,31 @@ extern int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bit | |||
505 | #endif /* CONFIG_PCI */ | 517 | #endif /* CONFIG_PCI */ |
506 | 518 | ||
507 | 519 | ||
520 | static inline int | ||
521 | ata_sg_is_last(struct scatterlist *sg, struct ata_queued_cmd *qc) | ||
522 | { | ||
523 | if (sg == &qc->pad_sgent) | ||
524 | return 1; | ||
525 | if (qc->pad_len) | ||
526 | return 0; | ||
527 | if (((sg - qc->__sg) + 1) == qc->n_elem) | ||
528 | return 1; | ||
529 | return 0; | ||
530 | } | ||
531 | |||
532 | static inline struct scatterlist * | ||
533 | ata_qc_next_sg(struct scatterlist *sg, struct ata_queued_cmd *qc) | ||
534 | { | ||
535 | if (sg == &qc->pad_sgent) | ||
536 | return NULL; | ||
537 | if (++sg - qc->__sg < qc->n_elem) | ||
538 | return sg; | ||
539 | return qc->pad_len ? &qc->pad_sgent : NULL; | ||
540 | } | ||
541 | |||
542 | #define ata_for_each_sg(sg, qc) \ | ||
543 | for (sg = qc->__sg; sg; sg = ata_qc_next_sg(sg, qc)) | ||
544 | |||
508 | static inline unsigned int ata_tag_valid(unsigned int tag) | 545 | static inline unsigned int ata_tag_valid(unsigned int tag) |
509 | { | 546 | { |
510 | return (tag < ATA_MAX_QUEUE) ? 1 : 0; | 547 | return (tag < ATA_MAX_QUEUE) ? 1 : 0; |