[PATCH] libata: move err_mask to ata_queued_cmd
[pandora-kernel.git] / include / linux / libata.h
index 00a8a57..e18ce03 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
+#include <linux/dma-mapping.h>
 #include <asm/io.h>
 #include <linux/ata.h>
 #include <linux/workqueue.h>
@@ -58,6 +59,8 @@
 #define VPRINTK(fmt, args...)
 #endif /* ATA_DEBUG */
 
+#define BPRINTK(fmt, args...) if (ap->flags & ATA_FLAG_DEBUGMSG) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
+
 #ifdef ATA_NDEBUG
 #define assert(expr)
 #else
@@ -118,6 +121,7 @@ enum {
        ATA_FLAG_PIO_DMA        = (1 << 8), /* PIO cmds via DMA */
        ATA_FLAG_NOINTR         = (1 << 9), /* FIXME: Remove this once
                                             * proper HSM is in place. */
+       ATA_FLAG_DEBUGMSG       = (1 << 10),
 
        ATA_QCFLAG_ACTIVE       = (1 << 1), /* cmd not yet ack'd to scsi lyer */
        ATA_QCFLAG_SG           = (1 << 3), /* have s/g table? */
@@ -155,6 +159,10 @@ enum {
        ATA_SHIFT_UDMA          = 0,
        ATA_SHIFT_MWDMA         = 8,
        ATA_SHIFT_PIO           = 11,
+
+       /* 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,
        
        /* Masks for port functions */
        ATA_PORT_PRIMARY        = (1 << 0),
@@ -172,6 +180,13 @@ enum hsm_task_states {
        HSM_ST_ERR,
 };
 
+enum ata_completion_errors {
+       AC_ERR_OTHER            = (1 << 0),
+       AC_ERR_DEV              = (1 << 1),
+       AC_ERR_ATA_BUS          = (1 << 2),
+       AC_ERR_HOST_BUS         = (1 << 3),
+};
+
 /* forward declarations */
 struct scsi_device;
 struct ata_port_operations;
@@ -179,7 +194,7 @@ struct ata_port;
 struct ata_queued_cmd;
 
 /* typedefs */
-typedef int (*ata_qc_cb_t) (struct ata_queued_cmd *qc, u8 drv_stat);
+typedef int (*ata_qc_cb_t) (struct ata_queued_cmd *qc);
 
 struct ata_ioports {
        unsigned long           cmd_addr;
@@ -203,7 +218,7 @@ struct ata_probe_ent {
        struct list_head        node;
        struct device           *dev;
        const struct ata_port_operations *port_ops;
-       Scsi_Host_Template      *sht;
+       struct scsi_host_template *sht;
        struct ata_ioports      port[ATA_MAX_PORTS];
        unsigned int            n_ports;
        unsigned int            hard_port_no;
@@ -242,9 +257,12 @@ struct ata_queued_cmd {
        unsigned long           flags;          /* ATA_QCFLAG_xxx */
        unsigned int            tag;
        unsigned int            n_elem;
+       unsigned int            orig_n_elem;
 
        int                     dma_dir;
 
+       unsigned int            pad_len;
+
        unsigned int            nsect;
        unsigned int            cursect;
 
@@ -255,9 +273,13 @@ struct ata_queued_cmd {
        unsigned int            cursg_ofs;
 
        struct scatterlist      sgent;
+       struct scatterlist      pad_sgent;
        void                    *buf_virt;
 
-       struct scatterlist      *sg;
+       /* DO NOT iterate over __sg manually, use ata_for_each_sg() */
+       struct scatterlist      *__sg;
+
+       unsigned int            err_mask;
 
        ata_qc_cb_t             complete_fn;
 
@@ -303,12 +325,13 @@ struct ata_port {
        struct ata_prd          *prd;    /* our SG list */
        dma_addr_t              prd_dma; /* and its DMA mapping */
 
+       void                    *pad;   /* array of DMA pad buffers */
+       dma_addr_t              pad_dma;
+
        struct ata_ioports      ioaddr; /* ATA cmd/ctl/dma register blocks */
 
        u8                      ctl;    /* cache of ATA control register */
        u8                      last_ctl;       /* Cache last written value */
-       unsigned int            bus_state;
-       unsigned int            port_state;
        unsigned int            pio_mask;
        unsigned int            mwdma_mask;
        unsigned int            udma_mask;
@@ -347,7 +370,6 @@ struct ata_port_operations {
        void (*exec_command)(struct ata_port *ap, const struct ata_taskfile *tf);
        u8   (*check_status)(struct ata_port *ap);
        u8   (*check_altstatus)(struct ata_port *ap);
-       u8   (*check_err)(struct ata_port *ap);
        void (*dev_select)(struct ata_port *ap, unsigned int device);
 
        void (*phy_reset) (struct ata_port *ap);
@@ -380,12 +402,13 @@ struct ata_port_operations {
 };
 
 struct ata_port_info {
-       Scsi_Host_Template      *sht;
+       struct scsi_host_template       *sht;
        unsigned long           host_flags;
        unsigned long           pio_mask;
        unsigned long           mwdma_mask;
        unsigned long           udma_mask;
        const struct ata_port_operations *port_ops;
+       void                    *private_data;
 };
 
 struct ata_timing {
@@ -415,7 +438,7 @@ extern void ata_pci_remove_one (struct pci_dev *pdev);
 #endif /* CONFIG_PCI */
 extern int ata_device_add(const struct ata_probe_ent *ent);
 extern void ata_host_set_remove(struct ata_host_set *host_set);
-extern int ata_scsi_detect(Scsi_Host_Template *sht);
+extern int ata_scsi_detect(struct scsi_host_template *sht);
 extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg);
 extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *));
 extern int ata_scsi_error(struct Scsi_Host *host);
@@ -434,7 +457,6 @@ 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);
 extern u8 ata_altstatus(struct ata_port *ap);
-extern u8 ata_chk_err(struct ata_port *ap);
 extern void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf);
 extern int ata_port_start (struct ata_port *ap);
 extern void ata_port_stop (struct ata_port *ap);
@@ -455,7 +477,7 @@ extern void ata_bmdma_start (struct ata_queued_cmd *qc);
 extern void ata_bmdma_stop(struct ata_queued_cmd *qc);
 extern u8   ata_bmdma_status(struct ata_port *ap);
 extern void ata_bmdma_irq_clear(struct ata_port *ap);
-extern void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat);
+extern void ata_qc_complete(struct ata_queued_cmd *qc);
 extern void ata_eng_timeout(struct ata_port *ap);
 extern void ata_scsi_simulate(u16 *id, struct scsi_cmnd *cmd,
                              void (*done)(struct scsi_cmnd *));
@@ -507,6 +529,31 @@ extern int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bit
 #endif /* CONFIG_PCI */
 
 
+static inline int
+ata_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_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;
+       return qc->pad_len ? &qc->pad_sgent : NULL;
+}
+
+#define ata_for_each_sg(sg, qc) \
+       for (sg = qc->__sg; 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;
@@ -615,6 +662,18 @@ static inline void ata_tf_init(struct ata_port *ap, struct ata_taskfile *tf, uns
                tf->device = ATA_DEVICE_OBS | ATA_DEV1;
 }
 
+static inline void ata_qc_reinit(struct ata_queued_cmd *qc)
+{
+       qc->__sg = NULL;
+       qc->flags = 0;
+       qc->cursect = qc->cursg = qc->cursg_ofs = 0;
+       qc->nsect = 0;
+       qc->nbytes = qc->curbytes = 0;
+       qc->err_mask = 0;
+
+       ata_tf_init(qc->ap, &qc->tf, qc->dev->devno);
+}
+
 
 /**
  *     ata_irq_on - Enable interrupts on a port.
@@ -718,4 +777,34 @@ static inline int ata_try_flush_cache(const struct ata_device *dev)
               ata_id_has_flush_ext(dev->id);
 }
 
+static inline unsigned int ac_err_mask(u8 status)
+{
+       if (status & ATA_BUSY)
+               return AC_ERR_ATA_BUS;
+       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);
+}
+
 #endif /* __LINUX_LIBATA_H__ */