Merge branch 'master'
This commit is contained in:
@@ -156,6 +156,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),
|
||||
@@ -252,9 +256,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;
|
||||
|
||||
@@ -265,9 +272,11 @@ 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;
|
||||
|
||||
ata_qc_cb_t complete_fn;
|
||||
|
||||
@@ -313,6 +322,9 @@ 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 */
|
||||
@@ -515,6 +527,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;
|
||||
@@ -743,4 +780,17 @@ static inline unsigned int __ac_err_mask(u8 status)
|
||||
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__ */
|
||||
|
Reference in New Issue
Block a user