📄 libata.h
字号:
extern void ata_timing_merge(const struct ata_timing *, const struct ata_timing *, struct ata_timing *, unsigned int);enum { ATA_TIMING_SETUP = (1 << 0), ATA_TIMING_ACT8B = (1 << 1), ATA_TIMING_REC8B = (1 << 2), ATA_TIMING_CYC8B = (1 << 3), ATA_TIMING_8BIT = ATA_TIMING_ACT8B | ATA_TIMING_REC8B | ATA_TIMING_CYC8B, ATA_TIMING_ACTIVE = (1 << 4), ATA_TIMING_RECOVER = (1 << 5), ATA_TIMING_CYCLE = (1 << 6), ATA_TIMING_UDMA = (1 << 7), ATA_TIMING_ALL = ATA_TIMING_SETUP | ATA_TIMING_ACT8B | ATA_TIMING_REC8B | ATA_TIMING_CYC8B | ATA_TIMING_ACTIVE | ATA_TIMING_RECOVER | ATA_TIMING_CYCLE | ATA_TIMING_UDMA,};#ifdef CONFIG_PCIstruct pci_bits { unsigned int reg; /* PCI config register to read */ unsigned int width; /* 1 (8 bit), 2 (16 bit), 4 (32 bit) */ unsigned long mask; unsigned long val;};extern void ata_pci_host_stop (struct ata_host *host);extern struct ata_probe_ent *ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int portmask);extern int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits);extern unsigned long ata_pci_default_filter(const struct ata_port *, struct ata_device *, unsigned long);#endif /* CONFIG_PCI *//* * EH */extern void ata_eng_timeout(struct ata_port *ap);extern void ata_port_schedule_eh(struct ata_port *ap);extern int ata_port_abort(struct ata_port *ap);extern int ata_port_freeze(struct ata_port *ap);extern void ata_eh_freeze_port(struct ata_port *ap);extern void ata_eh_thaw_port(struct ata_port *ap);extern void ata_eh_qc_complete(struct ata_queued_cmd *qc);extern void ata_eh_qc_retry(struct ata_queued_cmd *qc);extern void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset, ata_reset_fn_t softreset, ata_reset_fn_t hardreset, ata_postreset_fn_t postreset);/* * printk helpers */#define ata_port_printk(ap, lv, fmt, args...) \ printk(lv"ata%u: "fmt, (ap)->id , ##args)#define ata_dev_printk(dev, lv, fmt, args...) \ printk(lv"ata%u.%02u: "fmt, (dev)->ap->id, (dev)->devno , ##args)/* * ata_eh_info helpers */#define ata_ehi_push_desc(ehi, fmt, args...) do { \ (ehi)->desc_len += scnprintf((ehi)->desc + (ehi)->desc_len, \ ATA_EH_DESC_LEN - (ehi)->desc_len, \ fmt , ##args); \} while (0)#define ata_ehi_clear_desc(ehi) do { \ (ehi)->desc[0] = '\0'; \ (ehi)->desc_len = 0; \} while (0)static inline void __ata_ehi_hotplugged(struct ata_eh_info *ehi){ if (ehi->flags & ATA_EHI_HOTPLUGGED) return; ehi->flags |= ATA_EHI_HOTPLUGGED | ATA_EHI_RESUME_LINK; ehi->hotplug_timestamp = jiffies; ehi->action |= ATA_EH_SOFTRESET; ehi->probe_mask |= (1 << ATA_MAX_DEVICES) - 1;}static inline void ata_ehi_hotplugged(struct ata_eh_info *ehi){ __ata_ehi_hotplugged(ehi); ehi->err_mask |= AC_ERR_ATA_BUS;}/* * qc helpers */static inline intata_sg_is_last(struct scatterlist *sg, struct ata_queued_cmd *qc){ if (sg == &qc->pad_sgent) return 1; if (qc->pad_len) return 0; if (((sg - qc->__sg) + 1) == qc->n_elem) return 1; return 0;}static inline struct scatterlist *ata_qc_first_sg(struct ata_queued_cmd *qc){ 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 (++sg - qc->__sg < qc->n_elem) return 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;}static inline unsigned int ata_tag_internal(unsigned int tag){ return tag == ATA_MAX_QUEUE - 1;}/* * device helpers */static inline unsigned int ata_class_enabled(unsigned int class){ return class == ATA_DEV_ATA || class == ATA_DEV_ATAPI;}static inline unsigned int ata_class_disabled(unsigned int class){ return class == ATA_DEV_ATA_UNSUP || class == ATA_DEV_ATAPI_UNSUP;}static inline unsigned int ata_class_absent(unsigned int class){ return !ata_class_enabled(class) && !ata_class_disabled(class);}static inline unsigned int ata_dev_enabled(const struct ata_device *dev){ return ata_class_enabled(dev->class);}static inline unsigned int ata_dev_disabled(const struct ata_device *dev){ return ata_class_disabled(dev->class);}static inline unsigned int ata_dev_absent(const struct ata_device *dev){ return ata_class_absent(dev->class);}static inline unsigned int ata_dev_ready(const struct ata_device *dev){ return ata_dev_enabled(dev) && !(dev->flags & ATA_DFLAG_SUSPENDED);}/* * port helpers */static inline int ata_port_max_devices(const struct ata_port *ap){ if (ap->flags & ATA_FLAG_SLAVE_POSS) return 2; return 1;}static inline u8 ata_chk_status(struct ata_port *ap){ return ap->ops->check_status(ap);}/** * ata_pause - Flush writes and pause 400 nanoseconds. * @ap: Port to wait for. * * LOCKING: * Inherited from caller. */static inline void ata_pause(struct ata_port *ap){ ata_altstatus(ap); ndelay(400);}/** * ata_busy_wait - Wait for a port status register * @ap: Port to wait for. * @bits: bits that must be clear * @max: number of 10uS waits to perform * * Waits up to max*10 microseconds for the selected bits in the port's * status register to be cleared. * Returns final value of status register. * * LOCKING: * Inherited from caller. */static inline u8 ata_busy_wait(struct ata_port *ap, unsigned int bits, unsigned int max){ u8 status; do { udelay(10); status = ata_chk_status(ap); max--; } while (status != 0xff && (status & bits) && (max > 0)); return status;}/** * ata_wait_idle - Wait for a port to be idle. * @ap: Port to wait for. * * Waits up to 10ms for port's BUSY and DRQ signals to clear. * Returns final value of status register. * * LOCKING: * Inherited from caller. */static inline u8 ata_wait_idle(struct ata_port *ap){ u8 status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000); if (status != 0xff && (status & (ATA_BUSY | ATA_DRQ))) { unsigned long l = ap->ioaddr.status_addr; if (ata_msg_warn(ap)) printk(KERN_WARNING "ATA: abnormal status 0x%X on port 0x%lX\n", status, l); } return status;}static inline void ata_qc_set_polling(struct ata_queued_cmd *qc){ qc->tf.ctl |= ATA_NIEN;}static inline struct ata_queued_cmd *__ata_qc_from_tag(struct ata_port *ap, unsigned int tag){ if (likely(ata_tag_valid(tag))) return &ap->qcmd[tag]; return NULL;}static inline struct ata_queued_cmd *ata_qc_from_tag(struct ata_port *ap, unsigned int tag){ struct ata_queued_cmd *qc = __ata_qc_from_tag(ap, tag); if (unlikely(!qc) || !ap->ops->error_handler) return qc; if ((qc->flags & (ATA_QCFLAG_ACTIVE | ATA_QCFLAG_FAILED)) == ATA_QCFLAG_ACTIVE) return qc; return NULL;}static inline void ata_tf_init(struct ata_device *dev, struct ata_taskfile *tf){ memset(tf, 0, sizeof(*tf)); tf->ctl = dev->ap->ctl; if (dev->devno == 0) tf->device = ATA_DEVICE_OBS; else tf->device = ATA_DEVICE_OBS | ATA_DEV1;}static inline void ata_qc_reinit(struct ata_queued_cmd *qc){ qc->dma_dir = DMA_NONE; qc->__sg = NULL; qc->flags = 0; qc->cursect = qc->cursg = qc->cursg_ofs = 0; qc->nsect = 0; qc->nbytes = qc->curbytes = 0; qc->n_elem = 0; qc->err_mask = 0; qc->pad_len = 0; ata_tf_init(qc->dev, &qc->tf); /* init result_tf such that it indicates normal completion */ qc->result_tf.command = ATA_DRDY; qc->result_tf.feature = 0;}/** * ata_irq_ack - Acknowledge a device interrupt. * @ap: Port on which interrupts are enabled. * * Wait up to 10 ms for legacy IDE device to become idle (BUSY * or BUSY+DRQ clear). Obtain dma status and port status from * device. Clear the interrupt. Return port status. * * LOCKING: */static inline u8 ata_irq_ack(struct ata_port *ap, unsigned int chk_drq){ unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY; u8 host_stat, post_stat, status; status = ata_busy_wait(ap, bits, 1000); if (status & bits) if (ata_msg_err(ap)) printk(KERN_ERR "abnormal status 0x%X\n", status); /* get controller status; clear intr, err bits */ if (ap->flags & ATA_FLAG_MMIO) { void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr; host_stat = readb(mmio + ATA_DMA_STATUS); writeb(host_stat | ATA_DMA_INTR | ATA_DMA_ERR, mmio + ATA_DMA_STATUS); post_stat = readb(mmio + ATA_DMA_STATUS); } else { host_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS); outb(host_stat | ATA_DMA_INTR | ATA_DMA_ERR, ap->ioaddr.bmdma_addr + ATA_DMA_STATUS); post_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS); } if (ata_msg_intr(ap)) printk(KERN_INFO "%s: irq ack: host_stat 0x%X, new host_stat 0x%X, drv_stat 0x%X\n", __FUNCTION__, host_stat, post_stat, status); return status;}static inline int ata_try_flush_cache(const struct ata_device *dev){ return ata_id_wcache_enabled(dev->id) || ata_id_has_flush(dev->id) || ata_id_has_flush_ext(dev->id);}static inline unsigned int ac_err_mask(u8 status){ if (status & (ATA_BUSY | ATA_DRQ)) return AC_ERR_HSM; if (status & (ATA_ERR | ATA_DF)) return AC_ERR_DEV; return 0;}static inline unsigned int __ac_err_mask(u8 status){ unsigned int mask = ac_err_mask(status); if (mask == 0) return AC_ERR_OTHER; return mask;}static inline int ata_pad_alloc(struct ata_port *ap, struct device *dev){ ap->pad_dma = 0; ap->pad = dma_alloc_coherent(dev, ATA_DMA_PAD_BUF_SZ, &ap->pad_dma, GFP_KERNEL); return (ap->pad == NULL) ? -ENOMEM : 0;}static inline void ata_pad_free(struct ata_port *ap, struct device *dev){ dma_free_coherent(dev, ATA_DMA_PAD_BUF_SZ, ap->pad, ap->pad_dma);}static inline struct ata_port *ata_shost_to_port(struct Scsi_Host *host){ return (struct ata_port *) &host->hostdata[0];}#endif /* __LINUX_LIBATA_H__ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -