mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 20:51:44 +00:00
libata: update ->data_xfer hook for ATAPI
Depending on how many bytes are transferred as a unit, PIO data transfer may consume more bytes than requested. Knowing how much data is consumed is necessary to determine how much is left for draining. This patch update ->data_xfer such that it returns the number of consumed bytes. While at it, it also makes the following changes. * s/adev/dev/ * use READ/WRITE constants for rw indication * misc clean ups Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
This commit is contained in:
parent
ceb0c64262
commit
55dba3120f
@ -4994,7 +4994,7 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* ata_data_xfer - Transfer data by PIO
|
* ata_data_xfer - Transfer data by PIO
|
||||||
* @adev: device to target
|
* @dev: device to target
|
||||||
* @buf: data buffer
|
* @buf: data buffer
|
||||||
* @buflen: buffer length
|
* @buflen: buffer length
|
||||||
* @write_data: read/write
|
* @write_data: read/write
|
||||||
@ -5003,37 +5003,44 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words)
|
|||||||
*
|
*
|
||||||
* LOCKING:
|
* LOCKING:
|
||||||
* Inherited from caller.
|
* Inherited from caller.
|
||||||
|
*
|
||||||
|
* RETURNS:
|
||||||
|
* Bytes consumed.
|
||||||
*/
|
*/
|
||||||
void ata_data_xfer(struct ata_device *adev, unsigned char *buf,
|
unsigned int ata_data_xfer(struct ata_device *dev, unsigned char *buf,
|
||||||
unsigned int buflen, int write_data)
|
unsigned int buflen, int rw)
|
||||||
{
|
{
|
||||||
struct ata_port *ap = adev->link->ap;
|
struct ata_port *ap = dev->link->ap;
|
||||||
|
void __iomem *data_addr = ap->ioaddr.data_addr;
|
||||||
unsigned int words = buflen >> 1;
|
unsigned int words = buflen >> 1;
|
||||||
|
|
||||||
/* Transfer multiple of 2 bytes */
|
/* Transfer multiple of 2 bytes */
|
||||||
if (write_data)
|
if (rw == READ)
|
||||||
iowrite16_rep(ap->ioaddr.data_addr, buf, words);
|
ioread16_rep(data_addr, buf, words);
|
||||||
else
|
else
|
||||||
ioread16_rep(ap->ioaddr.data_addr, buf, words);
|
iowrite16_rep(data_addr, buf, words);
|
||||||
|
|
||||||
/* Transfer trailing 1 byte, if any. */
|
/* Transfer trailing 1 byte, if any. */
|
||||||
if (unlikely(buflen & 0x01)) {
|
if (unlikely(buflen & 0x01)) {
|
||||||
u16 align_buf[1] = { 0 };
|
u16 align_buf[1] = { 0 };
|
||||||
unsigned char *trailing_buf = buf + buflen - 1;
|
unsigned char *trailing_buf = buf + buflen - 1;
|
||||||
|
|
||||||
if (write_data) {
|
if (rw == READ) {
|
||||||
memcpy(align_buf, trailing_buf, 1);
|
align_buf[0] = cpu_to_le16(ioread16(data_addr));
|
||||||
iowrite16(le16_to_cpu(align_buf[0]), ap->ioaddr.data_addr);
|
|
||||||
} else {
|
|
||||||
align_buf[0] = cpu_to_le16(ioread16(ap->ioaddr.data_addr));
|
|
||||||
memcpy(trailing_buf, align_buf, 1);
|
memcpy(trailing_buf, align_buf, 1);
|
||||||
|
} else {
|
||||||
|
memcpy(align_buf, trailing_buf, 1);
|
||||||
|
iowrite16(le16_to_cpu(align_buf[0]), data_addr);
|
||||||
}
|
}
|
||||||
|
words++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return words << 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ata_data_xfer_noirq - Transfer data by PIO
|
* ata_data_xfer_noirq - Transfer data by PIO
|
||||||
* @adev: device to target
|
* @dev: device to target
|
||||||
* @buf: data buffer
|
* @buf: data buffer
|
||||||
* @buflen: buffer length
|
* @buflen: buffer length
|
||||||
* @write_data: read/write
|
* @write_data: read/write
|
||||||
@ -5043,14 +5050,21 @@ void ata_data_xfer(struct ata_device *adev, unsigned char *buf,
|
|||||||
*
|
*
|
||||||
* LOCKING:
|
* LOCKING:
|
||||||
* Inherited from caller.
|
* Inherited from caller.
|
||||||
|
*
|
||||||
|
* RETURNS:
|
||||||
|
* Bytes consumed.
|
||||||
*/
|
*/
|
||||||
void ata_data_xfer_noirq(struct ata_device *adev, unsigned char *buf,
|
unsigned int ata_data_xfer_noirq(struct ata_device *dev, unsigned char *buf,
|
||||||
unsigned int buflen, int write_data)
|
unsigned int buflen, int rw)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
unsigned int consumed;
|
||||||
|
|
||||||
local_irq_save(flags);
|
local_irq_save(flags);
|
||||||
ata_data_xfer(adev, buf, buflen, write_data);
|
consumed = ata_data_xfer(dev, buf, buflen, rw);
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
|
|
||||||
|
return consumed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1167,34 +1167,36 @@ static unsigned char bfin_bmdma_status(struct ata_port *ap)
|
|||||||
* Note: Original code is ata_data_xfer().
|
* Note: Original code is ata_data_xfer().
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void bfin_data_xfer(struct ata_device *adev, unsigned char *buf,
|
static unsigned int bfin_data_xfer(struct ata_device *dev, unsigned char *buf,
|
||||||
unsigned int buflen, int write_data)
|
unsigned int buflen, int rw)
|
||||||
{
|
{
|
||||||
struct ata_port *ap = adev->link->ap;
|
struct ata_port *ap = dev->link->ap;
|
||||||
unsigned int words = buflen >> 1;
|
|
||||||
unsigned short *buf16 = (u16 *) buf;
|
|
||||||
void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
|
void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
|
||||||
|
unsigned int words = buflen >> 1;
|
||||||
|
unsigned short *buf16 = (u16 *)buf;
|
||||||
|
|
||||||
/* Transfer multiple of 2 bytes */
|
/* Transfer multiple of 2 bytes */
|
||||||
if (write_data) {
|
if (rw == READ)
|
||||||
write_atapi_data(base, words, buf16);
|
|
||||||
} else {
|
|
||||||
read_atapi_data(base, words, buf16);
|
read_atapi_data(base, words, buf16);
|
||||||
}
|
else
|
||||||
|
write_atapi_data(base, words, buf16);
|
||||||
|
|
||||||
/* Transfer trailing 1 byte, if any. */
|
/* Transfer trailing 1 byte, if any. */
|
||||||
if (unlikely(buflen & 0x01)) {
|
if (unlikely(buflen & 0x01)) {
|
||||||
unsigned short align_buf[1] = { 0 };
|
unsigned short align_buf[1] = { 0 };
|
||||||
unsigned char *trailing_buf = buf + buflen - 1;
|
unsigned char *trailing_buf = buf + buflen - 1;
|
||||||
|
|
||||||
if (write_data) {
|
if (rw == READ) {
|
||||||
memcpy(align_buf, trailing_buf, 1);
|
|
||||||
write_atapi_data(base, 1, align_buf);
|
|
||||||
} else {
|
|
||||||
read_atapi_data(base, 1, align_buf);
|
read_atapi_data(base, 1, align_buf);
|
||||||
memcpy(trailing_buf, align_buf, 1);
|
memcpy(trailing_buf, align_buf, 1);
|
||||||
|
} else {
|
||||||
|
memcpy(align_buf, trailing_buf, 1);
|
||||||
|
write_atapi_data(base, 1, align_buf);
|
||||||
}
|
}
|
||||||
|
words++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return words << 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -42,13 +42,13 @@ static int ixp4xx_set_mode(struct ata_link *link, struct ata_device **error)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ixp4xx_mmio_data_xfer(struct ata_device *adev, unsigned char *buf,
|
static unsigned int ixp4xx_mmio_data_xfer(struct ata_device *dev,
|
||||||
unsigned int buflen, int write_data)
|
unsigned char *buf, unsigned int buflen, int rw)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
unsigned int words = buflen >> 1;
|
unsigned int words = buflen >> 1;
|
||||||
u16 *buf16 = (u16 *) buf;
|
u16 *buf16 = (u16 *) buf;
|
||||||
struct ata_port *ap = adev->link->ap;
|
struct ata_port *ap = dev->link->ap;
|
||||||
void __iomem *mmio = ap->ioaddr.data_addr;
|
void __iomem *mmio = ap->ioaddr.data_addr;
|
||||||
struct ixp4xx_pata_data *data = ap->host->dev->platform_data;
|
struct ixp4xx_pata_data *data = ap->host->dev->platform_data;
|
||||||
|
|
||||||
@ -59,30 +59,32 @@ static void ixp4xx_mmio_data_xfer(struct ata_device *adev, unsigned char *buf,
|
|||||||
udelay(100);
|
udelay(100);
|
||||||
|
|
||||||
/* Transfer multiple of 2 bytes */
|
/* Transfer multiple of 2 bytes */
|
||||||
if (write_data) {
|
if (rw == READ)
|
||||||
for (i = 0; i < words; i++)
|
|
||||||
writew(buf16[i], mmio);
|
|
||||||
} else {
|
|
||||||
for (i = 0; i < words; i++)
|
for (i = 0; i < words; i++)
|
||||||
buf16[i] = readw(mmio);
|
buf16[i] = readw(mmio);
|
||||||
}
|
else
|
||||||
|
for (i = 0; i < words; i++)
|
||||||
|
writew(buf16[i], mmio);
|
||||||
|
|
||||||
/* Transfer trailing 1 byte, if any. */
|
/* Transfer trailing 1 byte, if any. */
|
||||||
if (unlikely(buflen & 0x01)) {
|
if (unlikely(buflen & 0x01)) {
|
||||||
u16 align_buf[1] = { 0 };
|
u16 align_buf[1] = { 0 };
|
||||||
unsigned char *trailing_buf = buf + buflen - 1;
|
unsigned char *trailing_buf = buf + buflen - 1;
|
||||||
|
|
||||||
if (write_data) {
|
if (rw == READ) {
|
||||||
memcpy(align_buf, trailing_buf, 1);
|
|
||||||
writew(align_buf[0], mmio);
|
|
||||||
} else {
|
|
||||||
align_buf[0] = readw(mmio);
|
align_buf[0] = readw(mmio);
|
||||||
memcpy(trailing_buf, align_buf, 1);
|
memcpy(trailing_buf, align_buf, 1);
|
||||||
|
} else {
|
||||||
|
memcpy(align_buf, trailing_buf, 1);
|
||||||
|
writew(align_buf[0], mmio);
|
||||||
}
|
}
|
||||||
|
words++;
|
||||||
}
|
}
|
||||||
|
|
||||||
udelay(100);
|
udelay(100);
|
||||||
*data->cs0_cfg |= 0x01;
|
*data->cs0_cfg |= 0x01;
|
||||||
|
|
||||||
|
return words << 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct scsi_host_template ixp4xx_sht = {
|
static struct scsi_host_template ixp4xx_sht = {
|
||||||
|
@ -249,13 +249,14 @@ static void pdc20230_set_piomode(struct ata_port *ap, struct ata_device *adev)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pdc_data_xfer_vlb(struct ata_device *adev, unsigned char *buf, unsigned int buflen, int write_data)
|
static unsigned int pdc_data_xfer_vlb(struct ata_device *dev,
|
||||||
|
unsigned char *buf, unsigned int buflen, int rw)
|
||||||
{
|
{
|
||||||
struct ata_port *ap = adev->link->ap;
|
|
||||||
int slop = buflen & 3;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
if (ata_id_has_dword_io(adev->id)) {
|
if (ata_id_has_dword_io(adev->id)) {
|
||||||
|
struct ata_port *ap = dev->link->ap;
|
||||||
|
int slop = buflen & 3;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
local_irq_save(flags);
|
local_irq_save(flags);
|
||||||
|
|
||||||
/* Perform the 32bit I/O synchronization sequence */
|
/* Perform the 32bit I/O synchronization sequence */
|
||||||
@ -264,26 +265,27 @@ static void pdc_data_xfer_vlb(struct ata_device *adev, unsigned char *buf, unsig
|
|||||||
ioread8(ap->ioaddr.nsect_addr);
|
ioread8(ap->ioaddr.nsect_addr);
|
||||||
|
|
||||||
/* Now the data */
|
/* Now the data */
|
||||||
|
if (rw == READ)
|
||||||
if (write_data)
|
|
||||||
iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
|
|
||||||
else
|
|
||||||
ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
|
ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
|
||||||
|
else
|
||||||
|
iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
|
||||||
|
|
||||||
if (unlikely(slop)) {
|
if (unlikely(slop)) {
|
||||||
__le32 pad = 0;
|
u32 pad;
|
||||||
if (write_data) {
|
if (rw == READ) {
|
||||||
memcpy(&pad, buf + buflen - slop, slop);
|
|
||||||
iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr);
|
|
||||||
} else {
|
|
||||||
pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr));
|
pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr));
|
||||||
memcpy(buf + buflen - slop, &pad, slop);
|
memcpy(buf + buflen - slop, &pad, slop);
|
||||||
|
} else {
|
||||||
|
memcpy(&pad, buf + buflen - slop, slop);
|
||||||
|
iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr);
|
||||||
}
|
}
|
||||||
|
buflen += 4 - slop;
|
||||||
}
|
}
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
}
|
} else
|
||||||
else
|
buflen = ata_data_xfer_noirq(dev, buf, buflen, rw);
|
||||||
ata_data_xfer_noirq(adev, buf, buflen, write_data);
|
|
||||||
|
return buflen;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct ata_port_operations pdc20230_port_ops = {
|
static struct ata_port_operations pdc20230_port_ops = {
|
||||||
|
@ -124,29 +124,33 @@ static unsigned int qdi_qc_issue_prot(struct ata_queued_cmd *qc)
|
|||||||
return ata_qc_issue_prot(qc);
|
return ata_qc_issue_prot(qc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qdi_data_xfer(struct ata_device *adev, unsigned char *buf, unsigned int buflen, int write_data)
|
static unsigned int qdi_data_xfer(struct ata_device *dev, unsigned char *buf,
|
||||||
|
unsigned int buflen, int rw)
|
||||||
{
|
{
|
||||||
struct ata_port *ap = adev->link->ap;
|
if (ata_id_has_dword_io(dev->id)) {
|
||||||
int slop = buflen & 3;
|
struct ata_port *ap = dev->link->ap;
|
||||||
|
int slop = buflen & 3;
|
||||||
|
|
||||||
if (ata_id_has_dword_io(adev->id)) {
|
if (rw == READ)
|
||||||
if (write_data)
|
|
||||||
iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
|
|
||||||
else
|
|
||||||
ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
|
ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
|
||||||
|
else
|
||||||
|
iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
|
||||||
|
|
||||||
if (unlikely(slop)) {
|
if (unlikely(slop)) {
|
||||||
__le32 pad = 0;
|
u32 pad;
|
||||||
if (write_data) {
|
if (rw == READ) {
|
||||||
memcpy(&pad, buf + buflen - slop, slop);
|
|
||||||
iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr);
|
|
||||||
} else {
|
|
||||||
pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr));
|
pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr));
|
||||||
memcpy(buf + buflen - slop, &pad, slop);
|
memcpy(buf + buflen - slop, &pad, slop);
|
||||||
|
} else {
|
||||||
|
memcpy(&pad, buf + buflen - slop, slop);
|
||||||
|
iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr);
|
||||||
}
|
}
|
||||||
|
buflen += 4 - slop;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
ata_data_xfer(adev, buf, buflen, write_data);
|
buflen = ata_data_xfer(dev, buf, buflen, rw);
|
||||||
|
|
||||||
|
return buflen;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct scsi_host_template qdi_sht = {
|
static struct scsi_host_template qdi_sht = {
|
||||||
|
@ -768,45 +768,47 @@ static u8 scc_bmdma_status (struct ata_port *ap)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* scc_data_xfer - Transfer data by PIO
|
* scc_data_xfer - Transfer data by PIO
|
||||||
* @adev: device for this I/O
|
* @dev: device for this I/O
|
||||||
* @buf: data buffer
|
* @buf: data buffer
|
||||||
* @buflen: buffer length
|
* @buflen: buffer length
|
||||||
* @write_data: read/write
|
* @rw: read/write
|
||||||
*
|
*
|
||||||
* Note: Original code is ata_data_xfer().
|
* Note: Original code is ata_data_xfer().
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void scc_data_xfer (struct ata_device *adev, unsigned char *buf,
|
static unsigned int scc_data_xfer (struct ata_device *dev, unsigned char *buf,
|
||||||
unsigned int buflen, int write_data)
|
unsigned int buflen, int rw)
|
||||||
{
|
{
|
||||||
struct ata_port *ap = adev->link->ap;
|
struct ata_port *ap = dev->link->ap;
|
||||||
unsigned int words = buflen >> 1;
|
unsigned int words = buflen >> 1;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
u16 *buf16 = (u16 *) buf;
|
u16 *buf16 = (u16 *) buf;
|
||||||
void __iomem *mmio = ap->ioaddr.data_addr;
|
void __iomem *mmio = ap->ioaddr.data_addr;
|
||||||
|
|
||||||
/* Transfer multiple of 2 bytes */
|
/* Transfer multiple of 2 bytes */
|
||||||
if (write_data) {
|
if (rw == READ)
|
||||||
for (i = 0; i < words; i++)
|
|
||||||
out_be32(mmio, cpu_to_le16(buf16[i]));
|
|
||||||
} else {
|
|
||||||
for (i = 0; i < words; i++)
|
for (i = 0; i < words; i++)
|
||||||
buf16[i] = le16_to_cpu(in_be32(mmio));
|
buf16[i] = le16_to_cpu(in_be32(mmio));
|
||||||
}
|
else
|
||||||
|
for (i = 0; i < words; i++)
|
||||||
|
out_be32(mmio, cpu_to_le16(buf16[i]));
|
||||||
|
|
||||||
/* Transfer trailing 1 byte, if any. */
|
/* Transfer trailing 1 byte, if any. */
|
||||||
if (unlikely(buflen & 0x01)) {
|
if (unlikely(buflen & 0x01)) {
|
||||||
u16 align_buf[1] = { 0 };
|
u16 align_buf[1] = { 0 };
|
||||||
unsigned char *trailing_buf = buf + buflen - 1;
|
unsigned char *trailing_buf = buf + buflen - 1;
|
||||||
|
|
||||||
if (write_data) {
|
if (rw == READ) {
|
||||||
memcpy(align_buf, trailing_buf, 1);
|
|
||||||
out_be32(mmio, cpu_to_le16(align_buf[0]));
|
|
||||||
} else {
|
|
||||||
align_buf[0] = le16_to_cpu(in_be32(mmio));
|
align_buf[0] = le16_to_cpu(in_be32(mmio));
|
||||||
memcpy(trailing_buf, align_buf, 1);
|
memcpy(trailing_buf, align_buf, 1);
|
||||||
|
} else {
|
||||||
|
memcpy(align_buf, trailing_buf, 1);
|
||||||
|
out_be32(mmio, cpu_to_le16(align_buf[0]));
|
||||||
}
|
}
|
||||||
|
words++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return words << 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -92,29 +92,33 @@ static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void winbond_data_xfer(struct ata_device *adev, unsigned char *buf, unsigned int buflen, int write_data)
|
static void winbond_data_xfer(struct ata_device *dev, unsigned char *buf,
|
||||||
|
unsigned int buflen, int rw)
|
||||||
{
|
{
|
||||||
struct ata_port *ap = adev->link->ap;
|
struct ata_port *ap = dev->link->ap;
|
||||||
int slop = buflen & 3;
|
int slop = buflen & 3;
|
||||||
|
|
||||||
if (ata_id_has_dword_io(adev->id)) {
|
if (ata_id_has_dword_io(dev->id)) {
|
||||||
if (write_data)
|
if (rw == READ)
|
||||||
iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
|
|
||||||
else
|
|
||||||
ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
|
ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
|
||||||
|
else
|
||||||
|
iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
|
||||||
|
|
||||||
if (unlikely(slop)) {
|
if (unlikely(slop)) {
|
||||||
__le32 pad = 0;
|
u32 pad;
|
||||||
if (write_data) {
|
if (rw == READ) {
|
||||||
memcpy(&pad, buf + buflen - slop, slop);
|
|
||||||
iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr);
|
|
||||||
} else {
|
|
||||||
pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr));
|
pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr));
|
||||||
memcpy(buf + buflen - slop, &pad, slop);
|
memcpy(buf + buflen - slop, &pad, slop);
|
||||||
|
} else {
|
||||||
|
memcpy(&pad, buf + buflen - slop, slop);
|
||||||
|
iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr);
|
||||||
}
|
}
|
||||||
|
buflen += 4 - slop;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
ata_data_xfer(adev, buf, buflen, write_data);
|
buflen = ata_data_xfer(dev, buf, buflen, rw);
|
||||||
|
|
||||||
|
return buflen;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct scsi_host_template winbond_sht = {
|
static struct scsi_host_template winbond_sht = {
|
||||||
|
@ -701,7 +701,8 @@ struct ata_port_operations {
|
|||||||
void (*bmdma_setup) (struct ata_queued_cmd *qc);
|
void (*bmdma_setup) (struct ata_queued_cmd *qc);
|
||||||
void (*bmdma_start) (struct ata_queued_cmd *qc);
|
void (*bmdma_start) (struct ata_queued_cmd *qc);
|
||||||
|
|
||||||
void (*data_xfer) (struct ata_device *, unsigned char *, unsigned int, int);
|
unsigned int (*data_xfer) (struct ata_device *dev, unsigned char *buf,
|
||||||
|
unsigned int buflen, int rw);
|
||||||
|
|
||||||
int (*qc_defer) (struct ata_queued_cmd *qc);
|
int (*qc_defer) (struct ata_queued_cmd *qc);
|
||||||
void (*qc_prep) (struct ata_queued_cmd *qc);
|
void (*qc_prep) (struct ata_queued_cmd *qc);
|
||||||
@ -881,10 +882,10 @@ extern void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf)
|
|||||||
extern int ata_port_start(struct ata_port *ap);
|
extern int ata_port_start(struct ata_port *ap);
|
||||||
extern int ata_sff_port_start(struct ata_port *ap);
|
extern int ata_sff_port_start(struct ata_port *ap);
|
||||||
extern irqreturn_t ata_interrupt(int irq, void *dev_instance);
|
extern irqreturn_t ata_interrupt(int irq, void *dev_instance);
|
||||||
extern void ata_data_xfer(struct ata_device *adev, unsigned char *buf,
|
extern unsigned int ata_data_xfer(struct ata_device *dev,
|
||||||
unsigned int buflen, int write_data);
|
unsigned char *buf, unsigned int buflen, int rw);
|
||||||
extern void ata_data_xfer_noirq(struct ata_device *adev, unsigned char *buf,
|
extern unsigned int ata_data_xfer_noirq(struct ata_device *dev,
|
||||||
unsigned int buflen, int write_data);
|
unsigned char *buf, unsigned int buflen, int rw);
|
||||||
extern int ata_std_qc_defer(struct ata_queued_cmd *qc);
|
extern int ata_std_qc_defer(struct ata_queued_cmd *qc);
|
||||||
extern void ata_dumb_qc_prep(struct ata_queued_cmd *qc);
|
extern void ata_dumb_qc_prep(struct ata_queued_cmd *qc);
|
||||||
extern void ata_qc_prep(struct ata_queued_cmd *qc);
|
extern void ata_qc_prep(struct ata_queued_cmd *qc);
|
||||||
|
Loading…
Reference in New Issue
Block a user