sata_promise: handle ATAPI_NODATA ourselves
This patch extends sata_promise to handle ATAPI_NODATA commands internally. However, commands destined to ATA_DFLAG_CDB_INTR devices are excluded from this and continue to be returned to libata. Concrete changes: - pdc_atapi_dma_pkt() is renamed to pdc_atapi_pkt(), and is extended to set up correct headers for NODATA packets - pdc_qc_prep() calls pdc_atapi_pkt() for ATAPI_NODATA - pdc_host_intr() handles ATAPI_NODATA - pdc_qc_issue_prot() sends ATAPI_NODATA packets via the chip's packet mechanism, except for CDB_INTR devices Tested on first- and second-generation chips, SATAPI and PATAPI, with no observable regressions. Signed-off-by: Mikael Pettersson <mikpe@it.uu.se> Signed-off-by: Jeff Garzik <jeff@garzik.org>
This commit is contained in:
committed by
Jeff Garzik
parent
4113bb6b67
commit
fba6edbd3b
@@ -448,7 +448,7 @@ static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg,
|
|||||||
writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
|
writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pdc_atapi_dma_pkt(struct ata_queued_cmd *qc)
|
static void pdc_atapi_pkt(struct ata_queued_cmd *qc)
|
||||||
{
|
{
|
||||||
struct ata_port *ap = qc->ap;
|
struct ata_port *ap = qc->ap;
|
||||||
dma_addr_t sg_table = ap->prd_dma;
|
dma_addr_t sg_table = ap->prd_dma;
|
||||||
@@ -462,10 +462,20 @@ static void pdc_atapi_dma_pkt(struct ata_queued_cmd *qc)
|
|||||||
/* set control bits (byte 0), zero delay seq id (byte 3),
|
/* set control bits (byte 0), zero delay seq id (byte 3),
|
||||||
* and seq id (byte 2)
|
* and seq id (byte 2)
|
||||||
*/
|
*/
|
||||||
if (!(qc->tf.flags & ATA_TFLAG_WRITE))
|
switch (qc->tf.protocol) {
|
||||||
buf32[0] = cpu_to_le32(PDC_PKT_READ);
|
case ATA_PROT_ATAPI_DMA:
|
||||||
else
|
if (!(qc->tf.flags & ATA_TFLAG_WRITE))
|
||||||
buf32[0] = 0;
|
buf32[0] = cpu_to_le32(PDC_PKT_READ);
|
||||||
|
else
|
||||||
|
buf32[0] = 0;
|
||||||
|
break;
|
||||||
|
case ATA_PROT_ATAPI_NODATA:
|
||||||
|
buf32[0] = cpu_to_le32(PDC_PKT_NODATA);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
BUG();
|
||||||
|
break;
|
||||||
|
}
|
||||||
buf32[1] = cpu_to_le32(sg_table); /* S/G table addr */
|
buf32[1] = cpu_to_le32(sg_table); /* S/G table addr */
|
||||||
buf32[2] = 0; /* no next-packet */
|
buf32[2] = 0; /* no next-packet */
|
||||||
|
|
||||||
@@ -549,13 +559,14 @@ static void pdc_qc_prep(struct ata_queued_cmd *qc)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ATA_PROT_ATAPI:
|
case ATA_PROT_ATAPI:
|
||||||
case ATA_PROT_ATAPI_NODATA:
|
|
||||||
ata_qc_prep(qc);
|
ata_qc_prep(qc);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ATA_PROT_ATAPI_DMA:
|
case ATA_PROT_ATAPI_DMA:
|
||||||
ata_qc_prep(qc);
|
ata_qc_prep(qc);
|
||||||
pdc_atapi_dma_pkt(qc);
|
/*FALLTHROUGH*/
|
||||||
|
case ATA_PROT_ATAPI_NODATA:
|
||||||
|
pdc_atapi_pkt(qc);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -672,6 +683,7 @@ static inline unsigned int pdc_host_intr( struct ata_port *ap,
|
|||||||
case ATA_PROT_DMA:
|
case ATA_PROT_DMA:
|
||||||
case ATA_PROT_NODATA:
|
case ATA_PROT_NODATA:
|
||||||
case ATA_PROT_ATAPI_DMA:
|
case ATA_PROT_ATAPI_DMA:
|
||||||
|
case ATA_PROT_ATAPI_NODATA:
|
||||||
qc->err_mask |= ac_err_mask(ata_wait_idle(ap));
|
qc->err_mask |= ac_err_mask(ata_wait_idle(ap));
|
||||||
ata_qc_complete(qc);
|
ata_qc_complete(qc);
|
||||||
handled = 1;
|
handled = 1;
|
||||||
@@ -771,6 +783,10 @@ static inline void pdc_packet_start(struct ata_queued_cmd *qc)
|
|||||||
static unsigned int pdc_qc_issue_prot(struct ata_queued_cmd *qc)
|
static unsigned int pdc_qc_issue_prot(struct ata_queued_cmd *qc)
|
||||||
{
|
{
|
||||||
switch (qc->tf.protocol) {
|
switch (qc->tf.protocol) {
|
||||||
|
case ATA_PROT_ATAPI_NODATA:
|
||||||
|
if (qc->dev->flags & ATA_DFLAG_CDB_INTR)
|
||||||
|
break;
|
||||||
|
/*FALLTHROUGH*/
|
||||||
case ATA_PROT_ATAPI_DMA:
|
case ATA_PROT_ATAPI_DMA:
|
||||||
case ATA_PROT_DMA:
|
case ATA_PROT_DMA:
|
||||||
case ATA_PROT_NODATA:
|
case ATA_PROT_NODATA:
|
||||||
|
Reference in New Issue
Block a user