AHCI_CMD_SLOT_SZ = 32 * 32,
AHCI_RX_FIS_SZ = 256,
AHCI_CMD_TBL_HDR = 0x80,
+ AHCI_CMD_TBL_CDB = 0x40,
AHCI_CMD_TBL_SZ = AHCI_CMD_TBL_HDR + (AHCI_MAX_SG * 16),
AHCI_PORT_PRIV_DMA_SZ = AHCI_CMD_SLOT_SZ + AHCI_CMD_TBL_SZ +
AHCI_RX_FIS_SZ,
PORT_CMD_ICC_ACTIVE = (0x1 << 28), /* Put i/f in active state */
PORT_CMD_ICC_PARTIAL = (0x2 << 28), /* Put i/f in partial state */
PORT_CMD_ICC_SLUMBER = (0x6 << 28), /* Put i/f in slumber state */
+
+ /* hpriv->flags bits */
+ AHCI_FLAG_MSI = (1 << 0),
};
struct ahci_cmd_hdr {
struct ahci_host_priv {
unsigned long flags;
- unsigned int have_msi; /* is PCI MSI enabled? */
u32 cap; /* cache of HOST_CAP register */
u32 port_map; /* cache of HOST_PORTS_IMPL reg */
};
struct device *dev = ap->host_set->dev;
struct ahci_host_priv *hpriv = ap->host_set->private_data;
struct ahci_port_priv *pp;
- int rc;
void *mem, *mmio = ap->host_set->mmio_base;
void *port_mmio = ahci_port_base(mmio, ap->port_no);
dma_addr_t mem_dma;
- rc = ata_port_start(ap);
- if (rc)
- return rc;
-
pp = kmalloc(sizeof(*pp), GFP_KERNEL);
- if (!pp) {
- rc = -ENOMEM;
- goto err_out;
- }
+ if (!pp)
+ return -ENOMEM;
memset(pp, 0, sizeof(*pp));
mem = dma_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma, GFP_KERNEL);
if (!mem) {
- rc = -ENOMEM;
- goto err_out_kfree;
+ kfree(pp);
+ return -ENOMEM;
}
memset(mem, 0, AHCI_PORT_PRIV_DMA_SZ);
readl(port_mmio + PORT_CMD); /* flush */
return 0;
-
-err_out_kfree:
- kfree(pp);
-err_out:
- ata_port_stop(ap);
- return rc;
}
dma_free_coherent(dev, AHCI_PORT_PRIV_DMA_SZ,
pp->cmd_slot, pp->cmd_slot_dma);
kfree(pp);
- ata_port_stop(ap);
}
static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg_in)
static void ahci_qc_prep(struct ata_queued_cmd *qc)
{
- struct ahci_port_priv *pp = qc->ap->private_data;
+ struct ata_port *ap = qc->ap;
+ struct ahci_port_priv *pp = ap->private_data;
u32 opts;
const u32 cmd_fis_len = 5; /* five dwords */
opts = (qc->n_elem << 16) | cmd_fis_len;
if (qc->tf.flags & ATA_TFLAG_WRITE)
opts |= AHCI_CMD_WRITE;
-
- switch (qc->tf.protocol) {
- case ATA_PROT_ATAPI:
- case ATA_PROT_ATAPI_NODATA:
- case ATA_PROT_ATAPI_DMA:
+ if (is_atapi_taskfile(&qc->tf))
opts |= AHCI_CMD_ATAPI;
- break;
-
- default:
- /* do nothing */
- break;
- }
pp->cmd_slot[0].opts = cpu_to_le32(opts);
pp->cmd_slot[0].status = 0;
* a SATA Register - Host to Device command FIS.
*/
ata_tf_to_fis(&qc->tf, pp->cmd_tbl, 0);
+ if (opts & AHCI_CMD_ATAPI) {
+ memset(pp->cmd_tbl + AHCI_CMD_TBL_CDB, 0, 32);
+ memcpy(pp->cmd_tbl + AHCI_CMD_TBL_CDB, qc->cdb, ap->cdb_len);
+ }
if (!(qc->flags & ATA_QCFLAG_DMAMAP))
return;
return rc;
}
}
-
- hpriv->flags |= HOST_CAP_64;
} else {
rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
if (rc) {
probe_ent->mmio_base = mmio_base;
probe_ent->private_data = hpriv;
- hpriv->have_msi = have_msi;
+ if (have_msi)
+ hpriv->flags |= AHCI_FLAG_MSI;
/* initialize adapter */
rc = ahci_host_init(probe_ent);
scsi_remove_host(ap->host);
}
- have_msi = hpriv->have_msi;
+ have_msi = hpriv->flags & AHCI_FLAG_MSI;
free_irq(host_set->irq, host_set);
for (i = 0; i < host_set->n_ports; i++) {