diff options
Diffstat (limited to 'include/linux/libata.h')
| -rw-r--r-- | include/linux/libata.h | 82 |
1 files changed, 77 insertions, 5 deletions
diff --git a/include/linux/libata.h b/include/linux/libata.h index 00a8a5738858..dcd17e7458ab 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), |
| @@ -172,6 +176,13 @@ enum hsm_task_states { | |||
| 172 | HSM_ST_ERR, | 176 | HSM_ST_ERR, |
| 173 | }; | 177 | }; |
| 174 | 178 | ||
| 179 | enum ata_completion_errors { | ||
| 180 | AC_ERR_OTHER = (1 << 0), | ||
| 181 | AC_ERR_DEV = (1 << 1), | ||
| 182 | AC_ERR_ATA_BUS = (1 << 2), | ||
| 183 | AC_ERR_HOST_BUS = (1 << 3), | ||
| 184 | }; | ||
| 185 | |||
| 175 | /* forward declarations */ | 186 | /* forward declarations */ |
| 176 | struct scsi_device; | 187 | struct scsi_device; |
| 177 | struct ata_port_operations; | 188 | struct ata_port_operations; |
| @@ -179,7 +190,7 @@ struct ata_port; | |||
| 179 | struct ata_queued_cmd; | 190 | struct ata_queued_cmd; |
| 180 | 191 | ||
| 181 | /* typedefs */ | 192 | /* typedefs */ |
| 182 | typedef int (*ata_qc_cb_t) (struct ata_queued_cmd *qc, u8 drv_stat); | 193 | typedef int (*ata_qc_cb_t) (struct ata_queued_cmd *qc, unsigned int err_mask); |
| 183 | 194 | ||
| 184 | struct ata_ioports { | 195 | struct ata_ioports { |
| 185 | unsigned long cmd_addr; | 196 | unsigned long cmd_addr; |
| @@ -242,9 +253,12 @@ struct ata_queued_cmd { | |||
| 242 | unsigned long flags; /* ATA_QCFLAG_xxx */ | 253 | unsigned long flags; /* ATA_QCFLAG_xxx */ |
| 243 | unsigned int tag; | 254 | unsigned int tag; |
| 244 | unsigned int n_elem; | 255 | unsigned int n_elem; |
| 256 | unsigned int orig_n_elem; | ||
| 245 | 257 | ||
| 246 | int dma_dir; | 258 | int dma_dir; |
| 247 | 259 | ||
| 260 | unsigned int pad_len; | ||
| 261 | |||
| 248 | unsigned int nsect; | 262 | unsigned int nsect; |
| 249 | unsigned int cursect; | 263 | unsigned int cursect; |
| 250 | 264 | ||
| @@ -255,9 +269,11 @@ struct ata_queued_cmd { | |||
| 255 | unsigned int cursg_ofs; | 269 | unsigned int cursg_ofs; |
| 256 | 270 | ||
| 257 | struct scatterlist sgent; | 271 | struct scatterlist sgent; |
| 272 | struct scatterlist pad_sgent; | ||
| 258 | void *buf_virt; | 273 | void *buf_virt; |
| 259 | 274 | ||
| 260 | struct scatterlist *sg; | 275 | /* DO NOT iterate over __sg manually, use ata_for_each_sg() */ |
| 276 | struct scatterlist *__sg; | ||
| 261 | 277 | ||
| 262 | ata_qc_cb_t complete_fn; | 278 | ata_qc_cb_t complete_fn; |
| 263 | 279 | ||
| @@ -303,6 +319,9 @@ struct ata_port { | |||
| 303 | struct ata_prd *prd; /* our SG list */ | 319 | struct ata_prd *prd; /* our SG list */ |
| 304 | dma_addr_t prd_dma; /* and its DMA mapping */ | 320 | dma_addr_t prd_dma; /* and its DMA mapping */ |
| 305 | 321 | ||
| 322 | void *pad; /* array of DMA pad buffers */ | ||
| 323 | dma_addr_t pad_dma; | ||
| 324 | |||
| 306 | struct ata_ioports ioaddr; /* ATA cmd/ctl/dma register blocks */ | 325 | struct ata_ioports ioaddr; /* ATA cmd/ctl/dma register blocks */ |
| 307 | 326 | ||
| 308 | u8 ctl; /* cache of ATA control register */ | 327 | u8 ctl; /* cache of ATA control register */ |
| @@ -347,7 +366,6 @@ struct ata_port_operations { | |||
| 347 | void (*exec_command)(struct ata_port *ap, const struct ata_taskfile *tf); | 366 | void (*exec_command)(struct ata_port *ap, const struct ata_taskfile *tf); |
| 348 | u8 (*check_status)(struct ata_port *ap); | 367 | u8 (*check_status)(struct ata_port *ap); |
| 349 | u8 (*check_altstatus)(struct ata_port *ap); | 368 | u8 (*check_altstatus)(struct ata_port *ap); |
| 350 | u8 (*check_err)(struct ata_port *ap); | ||
| 351 | void (*dev_select)(struct ata_port *ap, unsigned int device); | 369 | void (*dev_select)(struct ata_port *ap, unsigned int device); |
| 352 | 370 | ||
| 353 | void (*phy_reset) (struct ata_port *ap); | 371 | void (*phy_reset) (struct ata_port *ap); |
| @@ -434,7 +452,6 @@ extern void ata_noop_dev_select (struct ata_port *ap, unsigned int device); | |||
| 434 | extern void ata_std_dev_select (struct ata_port *ap, unsigned int device); | 452 | extern void ata_std_dev_select (struct ata_port *ap, unsigned int device); |
| 435 | extern u8 ata_check_status(struct ata_port *ap); | 453 | extern u8 ata_check_status(struct ata_port *ap); |
| 436 | extern u8 ata_altstatus(struct ata_port *ap); | 454 | extern u8 ata_altstatus(struct ata_port *ap); |
| 437 | extern u8 ata_chk_err(struct ata_port *ap); | ||
| 438 | extern void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf); | 455 | extern void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf); |
| 439 | extern int ata_port_start (struct ata_port *ap); | 456 | extern int ata_port_start (struct ata_port *ap); |
| 440 | extern void ata_port_stop (struct ata_port *ap); | 457 | extern void ata_port_stop (struct ata_port *ap); |
| @@ -455,7 +472,7 @@ extern void ata_bmdma_start (struct ata_queued_cmd *qc); | |||
| 455 | extern void ata_bmdma_stop(struct ata_queued_cmd *qc); | 472 | extern void ata_bmdma_stop(struct ata_queued_cmd *qc); |
| 456 | extern u8 ata_bmdma_status(struct ata_port *ap); | 473 | extern u8 ata_bmdma_status(struct ata_port *ap); |
| 457 | extern void ata_bmdma_irq_clear(struct ata_port *ap); | 474 | extern void ata_bmdma_irq_clear(struct ata_port *ap); |
| 458 | extern void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat); | 475 | extern void ata_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask); |
| 459 | extern void ata_eng_timeout(struct ata_port *ap); | 476 | extern void ata_eng_timeout(struct ata_port *ap); |
| 460 | extern void ata_scsi_simulate(u16 *id, struct scsi_cmnd *cmd, | 477 | extern void ata_scsi_simulate(u16 *id, struct scsi_cmnd *cmd, |
| 461 | void (*done)(struct scsi_cmnd *)); | 478 | void (*done)(struct scsi_cmnd *)); |
| @@ -507,6 +524,31 @@ extern int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bit | |||
| 507 | #endif /* CONFIG_PCI */ | 524 | #endif /* CONFIG_PCI */ |
| 508 | 525 | ||
| 509 | 526 | ||
| 527 | static inline int | ||
| 528 | ata_sg_is_last(struct scatterlist *sg, struct ata_queued_cmd *qc) | ||
| 529 | { | ||
| 530 | if (sg == &qc->pad_sgent) | ||
| 531 | return 1; | ||
| 532 | if (qc->pad_len) | ||
| 533 | return 0; | ||
| 534 | if (((sg - qc->__sg) + 1) == qc->n_elem) | ||
| 535 | return 1; | ||
| 536 | return 0; | ||
| 537 | } | ||
| 538 | |||
| 539 | static inline struct scatterlist * | ||
| 540 | ata_qc_next_sg(struct scatterlist *sg, struct ata_queued_cmd *qc) | ||
| 541 | { | ||
| 542 | if (sg == &qc->pad_sgent) | ||
| 543 | return NULL; | ||
| 544 | if (++sg - qc->__sg < qc->n_elem) | ||
| 545 | return sg; | ||
| 546 | return qc->pad_len ? &qc->pad_sgent : NULL; | ||
| 547 | } | ||
| 548 | |||
| 549 | #define ata_for_each_sg(sg, qc) \ | ||
| 550 | for (sg = qc->__sg; sg; sg = ata_qc_next_sg(sg, qc)) | ||
| 551 | |||
| 510 | static inline unsigned int ata_tag_valid(unsigned int tag) | 552 | static inline unsigned int ata_tag_valid(unsigned int tag) |
| 511 | { | 553 | { |
| 512 | return (tag < ATA_MAX_QUEUE) ? 1 : 0; | 554 | return (tag < ATA_MAX_QUEUE) ? 1 : 0; |
| @@ -718,4 +760,34 @@ static inline int ata_try_flush_cache(const struct ata_device *dev) | |||
| 718 | ata_id_has_flush_ext(dev->id); | 760 | ata_id_has_flush_ext(dev->id); |
| 719 | } | 761 | } |
| 720 | 762 | ||
| 763 | static inline unsigned int ac_err_mask(u8 status) | ||
| 764 | { | ||
| 765 | if (status & ATA_BUSY) | ||
| 766 | return AC_ERR_ATA_BUS; | ||
| 767 | if (status & (ATA_ERR | ATA_DF)) | ||
| 768 | return AC_ERR_DEV; | ||
| 769 | return 0; | ||
| 770 | } | ||
| 771 | |||
| 772 | static inline unsigned int __ac_err_mask(u8 status) | ||
| 773 | { | ||
| 774 | unsigned int mask = ac_err_mask(status); | ||
| 775 | if (mask == 0) | ||
| 776 | return AC_ERR_OTHER; | ||
| 777 | return mask; | ||
| 778 | } | ||
| 779 | |||
| 780 | static inline int ata_pad_alloc(struct ata_port *ap, struct device *dev) | ||
| 781 | { | ||
| 782 | ap->pad_dma = 0; | ||
| 783 | ap->pad = dma_alloc_coherent(dev, ATA_DMA_PAD_BUF_SZ, | ||
| 784 | &ap->pad_dma, GFP_KERNEL); | ||
| 785 | return (ap->pad == NULL) ? -ENOMEM : 0; | ||
| 786 | } | ||
| 787 | |||
| 788 | static inline void ata_pad_free(struct ata_port *ap, struct device *dev) | ||
| 789 | { | ||
| 790 | dma_free_coherent(dev, ATA_DMA_PAD_BUF_SZ, ap->pad, ap->pad_dma); | ||
| 791 | } | ||
| 792 | |||
| 721 | #endif /* __LINUX_LIBATA_H__ */ | 793 | #endif /* __LINUX_LIBATA_H__ */ |
