Commit 3af70258 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://gkernel.bkbits.net/libata-2.6

into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents d2d4b0f3 2b50a905
...@@ -138,9 +138,12 @@ static struct ata_port_operations piix_pata_ops = { ...@@ -138,9 +138,12 @@ static struct ata_port_operations piix_pata_ops = {
.bmdma_setup = ata_bmdma_setup_pio, .bmdma_setup = ata_bmdma_setup_pio,
.bmdma_start = ata_bmdma_start_pio, .bmdma_start = ata_bmdma_start_pio,
.qc_prep = ata_qc_prep, .qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
.eng_timeout = ata_eng_timeout, .eng_timeout = ata_eng_timeout,
.irq_handler = ata_interrupt, .irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
.port_start = ata_port_start, .port_start = ata_port_start,
.port_stop = ata_port_stop, .port_stop = ata_port_stop,
...@@ -161,9 +164,12 @@ static struct ata_port_operations piix_sata_ops = { ...@@ -161,9 +164,12 @@ static struct ata_port_operations piix_sata_ops = {
.bmdma_setup = ata_bmdma_setup_pio, .bmdma_setup = ata_bmdma_setup_pio,
.bmdma_start = ata_bmdma_start_pio, .bmdma_start = ata_bmdma_start_pio,
.qc_prep = ata_qc_prep, .qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
.eng_timeout = ata_eng_timeout, .eng_timeout = ata_eng_timeout,
.irq_handler = ata_interrupt, .irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
.port_start = ata_port_start, .port_start = ata_port_start,
.port_stop = ata_port_stop, .port_stop = ata_port_stop,
......
...@@ -55,7 +55,6 @@ static void ata_host_set_udma(struct ata_port *ap); ...@@ -55,7 +55,6 @@ static void ata_host_set_udma(struct ata_port *ap);
static void ata_dev_set_pio(struct ata_port *ap, unsigned int device); static void ata_dev_set_pio(struct ata_port *ap, unsigned int device);
static void ata_dev_set_udma(struct ata_port *ap, unsigned int device); static void ata_dev_set_udma(struct ata_port *ap, unsigned int device);
static void ata_set_mode(struct ata_port *ap); static void ata_set_mode(struct ata_port *ap);
static int ata_qc_issue_prot(struct ata_queued_cmd *qc);
static unsigned int ata_unique_id = 1; static unsigned int ata_unique_id = 1;
static struct workqueue_struct *ata_wq; static struct workqueue_struct *ata_wq;
...@@ -1751,26 +1750,24 @@ static void ata_dev_set_pio(struct ata_port *ap, unsigned int device) ...@@ -1751,26 +1750,24 @@ static void ata_dev_set_pio(struct ata_port *ap, unsigned int device)
static void ata_sg_clean(struct ata_queued_cmd *qc) static void ata_sg_clean(struct ata_queued_cmd *qc)
{ {
struct ata_port *ap = qc->ap; struct ata_port *ap = qc->ap;
struct scsi_cmnd *cmd = qc->scsicmd;
struct scatterlist *sg = qc->sg; struct scatterlist *sg = qc->sg;
int dir = scsi_to_pci_dma_dir(cmd->sc_data_direction); int dir = qc->pci_dma_dir;
assert(dir == SCSI_DATA_READ || dir == SCSI_DATA_WRITE); assert(qc->flags & ATA_QCFLAG_DMAMAP);
assert(qc->flags & ATA_QCFLAG_SG);
assert(sg != NULL); assert(sg != NULL);
if (!cmd->use_sg) if (qc->flags & ATA_QCFLAG_SINGLE)
assert(qc->n_elem == 1); assert(qc->n_elem == 1);
DPRINTK("unmapping %u sg elements\n", qc->n_elem); DPRINTK("unmapping %u sg elements\n", qc->n_elem);
if (cmd->use_sg) if (qc->flags & ATA_QCFLAG_SG)
pci_unmap_sg(ap->host_set->pdev, sg, qc->n_elem, dir); pci_unmap_sg(ap->host_set->pdev, sg, qc->n_elem, dir);
else else
pci_unmap_single(ap->host_set->pdev, sg_dma_address(&sg[0]), pci_unmap_single(ap->host_set->pdev, sg_dma_address(&sg[0]),
sg_dma_len(&sg[0]), dir); sg_dma_len(&sg[0]), dir);
qc->flags &= ~ATA_QCFLAG_SG; qc->flags &= ~ATA_QCFLAG_DMAMAP;
qc->sg = NULL; qc->sg = NULL;
} }
...@@ -1831,12 +1828,39 @@ static void ata_fill_sg(struct ata_queued_cmd *qc) ...@@ -1831,12 +1828,39 @@ static void ata_fill_sg(struct ata_queued_cmd *qc)
*/ */
void ata_qc_prep(struct ata_queued_cmd *qc) void ata_qc_prep(struct ata_queued_cmd *qc)
{ {
if (!(qc->flags & ATA_QCFLAG_SG)) if (!(qc->flags & ATA_QCFLAG_DMAMAP))
return; return;
ata_fill_sg(qc); ata_fill_sg(qc);
} }
void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen)
{
struct scatterlist *sg;
qc->flags |= ATA_QCFLAG_SINGLE;
memset(&qc->sgent, 0, sizeof(qc->sgent));
qc->sg = &qc->sgent;
qc->n_elem = 1;
qc->buf_virt = buf;
sg = qc->sg;
sg->page = virt_to_page(buf);
sg->offset = (unsigned long) buf & ~PAGE_MASK;
sg_dma_len(sg) = buflen;
WARN_ON(buflen > PAGE_SIZE);
}
void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
unsigned int n_elem)
{
qc->flags |= ATA_QCFLAG_SG;
qc->sg = sg;
qc->n_elem = n_elem;
}
/** /**
* ata_sg_setup_one - * ata_sg_setup_one -
* @qc: * @qc:
...@@ -1851,26 +1875,18 @@ void ata_qc_prep(struct ata_queued_cmd *qc) ...@@ -1851,26 +1875,18 @@ void ata_qc_prep(struct ata_queued_cmd *qc)
static int ata_sg_setup_one(struct ata_queued_cmd *qc) static int ata_sg_setup_one(struct ata_queued_cmd *qc)
{ {
struct ata_port *ap = qc->ap; struct ata_port *ap = qc->ap;
struct scsi_cmnd *cmd = qc->scsicmd; int dir = qc->pci_dma_dir;
int dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
struct scatterlist *sg = qc->sg; struct scatterlist *sg = qc->sg;
dma_addr_t dma_address; dma_addr_t dma_address;
assert(sg == &qc->sgent); dma_address = pci_map_single(ap->host_set->pdev, qc->buf_virt,
assert(qc->n_elem == 1); sg_dma_len(sg), dir);
sg->page = virt_to_page(cmd->request_buffer);
sg->offset = (unsigned long) cmd->request_buffer & ~PAGE_MASK;
sg_dma_len(sg) = cmd->request_bufflen;
dma_address = pci_map_single(ap->host_set->pdev, cmd->request_buffer,
cmd->request_bufflen, dir);
if (pci_dma_mapping_error(dma_address)) if (pci_dma_mapping_error(dma_address))
return -1; return -1;
sg_dma_address(sg) = dma_address; sg_dma_address(sg) = dma_address;
DPRINTK("mapped buffer of %d bytes for %s\n", cmd->request_bufflen, DPRINTK("mapped buffer of %d bytes for %s\n", sg_dma_len(sg),
qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read"); qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read");
return 0; return 0;
...@@ -1890,16 +1906,14 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc) ...@@ -1890,16 +1906,14 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc)
static int ata_sg_setup(struct ata_queued_cmd *qc) static int ata_sg_setup(struct ata_queued_cmd *qc)
{ {
struct ata_port *ap = qc->ap; struct ata_port *ap = qc->ap;
struct scsi_cmnd *cmd = qc->scsicmd; struct scatterlist *sg = qc->sg;
struct scatterlist *sg;
int n_elem, dir; int n_elem, dir;
VPRINTK("ENTER, ata%u, use_sg %d\n", ap->id, cmd->use_sg); VPRINTK("ENTER, ata%u\n", ap->id);
assert(cmd->use_sg > 0); assert(qc->flags & ATA_QCFLAG_SG);
sg = (struct scatterlist *)cmd->request_buffer; dir = qc->pci_dma_dir;
dir = scsi_to_pci_dma_dir(cmd->sc_data_direction); n_elem = pci_map_sg(ap->host_set->pdev, sg, qc->n_elem, dir);
n_elem = pci_map_sg(ap->host_set->pdev, sg, cmd->use_sg, dir);
if (n_elem < 1) if (n_elem < 1)
return -1; return -1;
...@@ -2015,7 +2029,6 @@ static void ata_pio_sector(struct ata_port *ap) ...@@ -2015,7 +2029,6 @@ static void ata_pio_sector(struct ata_port *ap)
{ {
struct ata_queued_cmd *qc; struct ata_queued_cmd *qc;
struct scatterlist *sg; struct scatterlist *sg;
struct scsi_cmnd *cmd;
unsigned char *buf; unsigned char *buf;
u8 status; u8 status;
...@@ -2047,7 +2060,6 @@ static void ata_pio_sector(struct ata_port *ap) ...@@ -2047,7 +2060,6 @@ static void ata_pio_sector(struct ata_port *ap)
qc = ata_qc_from_tag(ap, ap->active_tag); qc = ata_qc_from_tag(ap, ap->active_tag);
assert(qc != NULL); assert(qc != NULL);
cmd = qc->scsicmd;
sg = qc->sg; sg = qc->sg;
if (qc->cursect == (qc->nsect - 1)) if (qc->cursect == (qc->nsect - 1))
...@@ -2059,7 +2071,7 @@ static void ata_pio_sector(struct ata_port *ap) ...@@ -2059,7 +2071,7 @@ static void ata_pio_sector(struct ata_port *ap)
qc->cursect++; qc->cursect++;
qc->cursg_ofs++; qc->cursg_ofs++;
if (cmd->use_sg) if (qc->flags & ATA_QCFLAG_SG)
if ((qc->cursg_ofs * ATA_SECT_SIZE) == sg_dma_len(&sg[qc->cursg])) { if ((qc->cursg_ofs * ATA_SECT_SIZE) == sg_dma_len(&sg[qc->cursg])) {
qc->cursg++; qc->cursg++;
qc->cursg_ofs = 0; qc->cursg_ofs = 0;
...@@ -2294,27 +2306,23 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, ...@@ -2294,27 +2306,23 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
{ {
struct ata_port *ap = qc->ap; struct ata_port *ap = qc->ap;
struct scsi_cmnd *cmd = qc->scsicmd;
unsigned int tag, do_clear = 0; unsigned int tag, do_clear = 0;
int rc;
assert(qc != NULL); /* ata_qc_from_tag _might_ return NULL */ assert(qc != NULL); /* ata_qc_from_tag _might_ return NULL */
assert(qc->flags & ATA_QCFLAG_ACTIVE); assert(qc->flags & ATA_QCFLAG_ACTIVE);
if (likely(qc->flags & ATA_QCFLAG_SG)) if (likely(qc->flags & ATA_QCFLAG_DMAMAP))
ata_sg_clean(qc); ata_sg_clean(qc);
if (cmd) { /* call completion callback */
if (unlikely(drv_stat & (ATA_ERR | ATA_BUSY | ATA_DRQ))) { rc = qc->complete_fn(qc, drv_stat);
if (is_atapi_taskfile(&qc->tf))
cmd->result = SAM_STAT_CHECK_CONDITION;
else
ata_to_sense_error(qc);
} else {
cmd->result = SAM_STAT_GOOD;
}
qc->scsidone(cmd); /* if callback indicates not to complete command (non-zero),
} * return immediately
*/
if (rc != 0)
return;
qc->flags = 0; qc->flags = 0;
tag = qc->tag; tag = qc->tag;
...@@ -2351,17 +2359,13 @@ void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) ...@@ -2351,17 +2359,13 @@ void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
int ata_qc_issue(struct ata_queued_cmd *qc) int ata_qc_issue(struct ata_queued_cmd *qc)
{ {
struct ata_port *ap = qc->ap; struct ata_port *ap = qc->ap;
struct scsi_cmnd *cmd = qc->scsicmd;
if (qc->flags & ATA_QCFLAG_SG) { if (qc->flags & ATA_QCFLAG_SG) {
/* set up SG table */ if (ata_sg_setup(qc))
if (cmd->use_sg) { goto err_out;
if (ata_sg_setup(qc)) } else if (qc->flags & ATA_QCFLAG_SINGLE) {
goto err_out; if (ata_sg_setup_one(qc))
} else { goto err_out;
if (ata_sg_setup_one(qc))
goto err_out;
}
} }
ap->ops->qc_prep(qc); ap->ops->qc_prep(qc);
...@@ -2369,7 +2373,7 @@ int ata_qc_issue(struct ata_queued_cmd *qc) ...@@ -2369,7 +2373,7 @@ int ata_qc_issue(struct ata_queued_cmd *qc)
qc->ap->active_tag = qc->tag; qc->ap->active_tag = qc->tag;
qc->flags |= ATA_QCFLAG_ACTIVE; qc->flags |= ATA_QCFLAG_ACTIVE;
return ata_qc_issue_prot(qc); return ap->ops->qc_issue(qc);
err_out: err_out:
return -1; return -1;
...@@ -2391,7 +2395,7 @@ int ata_qc_issue(struct ata_queued_cmd *qc) ...@@ -2391,7 +2395,7 @@ int ata_qc_issue(struct ata_queued_cmd *qc)
* Zero on success, negative on error. * Zero on success, negative on error.
*/ */
static int ata_qc_issue_prot(struct ata_queued_cmd *qc) int ata_qc_issue_prot(struct ata_queued_cmd *qc)
{ {
struct ata_port *ap = qc->ap; struct ata_port *ap = qc->ap;
...@@ -2542,6 +2546,11 @@ void ata_bmdma_start_pio (struct ata_queued_cmd *qc) ...@@ -2542,6 +2546,11 @@ void ata_bmdma_start_pio (struct ata_queued_cmd *qc)
ap->ioaddr.bmdma_addr + ATA_DMA_CMD); ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
} }
void ata_bmdma_irq_clear(struct ata_port *ap)
{
ata_bmdma_ack_irq(ap);
}
/** /**
* ata_host_intr - Handle host interrupt for given (port, task) * ata_host_intr - Handle host interrupt for given (port, task)
* @ap: Port on which interrupt arrived (possibly...) * @ap: Port on which interrupt arrived (possibly...)
...@@ -2884,6 +2893,7 @@ int ata_device_add(struct ata_probe_ent *ent) ...@@ -2884,6 +2893,7 @@ int ata_device_add(struct ata_probe_ent *ent)
host_set->irq = ent->irq; host_set->irq = ent->irq;
host_set->mmio_base = ent->mmio_base; host_set->mmio_base = ent->mmio_base;
host_set->private_data = ent->private_data; host_set->private_data = ent->private_data;
host_set->ops = ent->port_ops;
/* register each port bound to this device */ /* register each port bound to this device */
for (i = 0; i < ent->n_ports; i++) { for (i = 0; i < ent->n_ports; i++) {
...@@ -2906,6 +2916,8 @@ int ata_device_add(struct ata_probe_ent *ent) ...@@ -2906,6 +2916,8 @@ int ata_device_add(struct ata_probe_ent *ent)
ap->ioaddr.bmdma_addr, ap->ioaddr.bmdma_addr,
ent->irq); ent->irq);
ata_chk_status(ap);
host_set->ops->irq_clear(ap);
count++; count++;
} }
...@@ -2914,10 +2926,6 @@ int ata_device_add(struct ata_probe_ent *ent) ...@@ -2914,10 +2926,6 @@ int ata_device_add(struct ata_probe_ent *ent)
return 0; return 0;
} }
/* TODO: ack irq here, to ensure it won't scream
* when we enable it?
*/
/* obtain irq, that is shared between channels */ /* obtain irq, that is shared between channels */
if (request_irq(ent->irq, ent->port_ops->irq_handler, ent->irq_flags, if (request_irq(ent->irq, ent->port_ops->irq_handler, ent->irq_flags,
DRV_NAME, host_set)) DRV_NAME, host_set))
...@@ -3243,8 +3251,8 @@ void ata_pci_remove_one (struct pci_dev *pdev) ...@@ -3243,8 +3251,8 @@ void ata_pci_remove_one (struct pci_dev *pdev)
free_irq(host_set->irq, host_set); free_irq(host_set->irq, host_set);
if (host_set->mmio_base) if (host_set->mmio_base)
iounmap(host_set->mmio_base); iounmap(host_set->mmio_base);
if (host_set->ports[0]->ops->host_stop) if (host_set->ops->host_stop)
host_set->ports[0]->ops->host_stop(host_set); host_set->ops->host_stop(host_set);
for (i = 0; i < host_set->n_ports; i++) { for (i = 0; i < host_set->n_ports; i++) {
ap = host_set->ports[i]; ap = host_set->ports[i];
...@@ -3347,7 +3355,10 @@ EXPORT_SYMBOL_GPL(pci_test_config_bits); ...@@ -3347,7 +3355,10 @@ EXPORT_SYMBOL_GPL(pci_test_config_bits);
EXPORT_SYMBOL_GPL(ata_std_bios_param); EXPORT_SYMBOL_GPL(ata_std_bios_param);
EXPORT_SYMBOL_GPL(ata_std_ports); EXPORT_SYMBOL_GPL(ata_std_ports);
EXPORT_SYMBOL_GPL(ata_device_add); EXPORT_SYMBOL_GPL(ata_device_add);
EXPORT_SYMBOL_GPL(ata_sg_init);
EXPORT_SYMBOL_GPL(ata_sg_init_one);
EXPORT_SYMBOL_GPL(ata_qc_complete); EXPORT_SYMBOL_GPL(ata_qc_complete);
EXPORT_SYMBOL_GPL(ata_qc_issue_prot);
EXPORT_SYMBOL_GPL(ata_eng_timeout); EXPORT_SYMBOL_GPL(ata_eng_timeout);
EXPORT_SYMBOL_GPL(ata_tf_load_pio); EXPORT_SYMBOL_GPL(ata_tf_load_pio);
EXPORT_SYMBOL_GPL(ata_tf_load_mmio); EXPORT_SYMBOL_GPL(ata_tf_load_mmio);
...@@ -3367,6 +3378,7 @@ EXPORT_SYMBOL_GPL(ata_bmdma_setup_pio); ...@@ -3367,6 +3378,7 @@ EXPORT_SYMBOL_GPL(ata_bmdma_setup_pio);
EXPORT_SYMBOL_GPL(ata_bmdma_start_pio); EXPORT_SYMBOL_GPL(ata_bmdma_start_pio);
EXPORT_SYMBOL_GPL(ata_bmdma_setup_mmio); EXPORT_SYMBOL_GPL(ata_bmdma_setup_mmio);
EXPORT_SYMBOL_GPL(ata_bmdma_start_mmio); EXPORT_SYMBOL_GPL(ata_bmdma_start_mmio);
EXPORT_SYMBOL_GPL(ata_bmdma_irq_clear);
EXPORT_SYMBOL_GPL(ata_port_probe); EXPORT_SYMBOL_GPL(ata_port_probe);
EXPORT_SYMBOL_GPL(sata_phy_reset); EXPORT_SYMBOL_GPL(sata_phy_reset);
EXPORT_SYMBOL_GPL(ata_bus_reset); EXPORT_SYMBOL_GPL(ata_bus_reset);
......
...@@ -335,6 +335,24 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) ...@@ -335,6 +335,24 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
return 1; return 1;
} }
static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
{
struct scsi_cmnd *cmd = qc->scsicmd;
if (unlikely(drv_stat & (ATA_ERR | ATA_BUSY | ATA_DRQ))) {
if (is_atapi_taskfile(&qc->tf))
cmd->result = SAM_STAT_CHECK_CONDITION;
else
ata_to_sense_error(qc);
} else {
cmd->result = SAM_STAT_GOOD;
}
qc->scsidone(cmd);
return 0;
}
/** /**
* ata_scsi_translate - Translate then issue SCSI command to ATA device * ata_scsi_translate - Translate then issue SCSI command to ATA device
* @ap: ATA port to which the command is addressed * @ap: ATA port to which the command is addressed
...@@ -368,6 +386,7 @@ static void ata_scsi_translate(struct ata_port *ap, struct ata_device *dev, ...@@ -368,6 +386,7 @@ static void ata_scsi_translate(struct ata_port *ap, struct ata_device *dev,
if (!qc) if (!qc)
return; return;
/* data is present; dma-map it */
if (cmd->sc_data_direction == SCSI_DATA_READ || if (cmd->sc_data_direction == SCSI_DATA_READ ||
cmd->sc_data_direction == SCSI_DATA_WRITE) { cmd->sc_data_direction == SCSI_DATA_WRITE) {
if (unlikely(cmd->request_bufflen < 1)) { if (unlikely(cmd->request_bufflen < 1)) {
...@@ -376,9 +395,17 @@ static void ata_scsi_translate(struct ata_port *ap, struct ata_device *dev, ...@@ -376,9 +395,17 @@ static void ata_scsi_translate(struct ata_port *ap, struct ata_device *dev,
goto err_out; goto err_out;
} }
qc->flags |= ATA_QCFLAG_SG; /* data is present; dma-map it */ if (cmd->use_sg)
ata_sg_init(qc, cmd->request_buffer, cmd->use_sg);
else
ata_sg_init_one(qc, cmd->request_buffer,
cmd->request_bufflen);
qc->pci_dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
} }
qc->complete_fn = ata_scsi_qc_complete;
if (xlat_func(qc, scsicmd)) if (xlat_func(qc, scsicmd))
goto err_out; goto err_out;
......
...@@ -139,8 +139,10 @@ static struct ata_port_operations nv_ops = { ...@@ -139,8 +139,10 @@ static struct ata_port_operations nv_ops = {
.bmdma_setup = ata_bmdma_setup_pio, .bmdma_setup = ata_bmdma_setup_pio,
.bmdma_start = ata_bmdma_start_pio, .bmdma_start = ata_bmdma_start_pio,
.qc_prep = ata_qc_prep, .qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
.eng_timeout = ata_eng_timeout, .eng_timeout = ata_eng_timeout,
.irq_handler = nv_interrupt, .irq_handler = nv_interrupt,
.irq_clear = ata_bmdma_irq_clear,
.scr_read = nv_scr_read, .scr_read = nv_scr_read,
.scr_write = nv_scr_write, .scr_write = nv_scr_write,
.port_start = ata_port_start, .port_start = ata_port_start,
......
...@@ -74,7 +74,6 @@ struct pdc_port_priv { ...@@ -74,7 +74,6 @@ struct pdc_port_priv {
static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg); static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg);
static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
static void pdc_dma_setup(struct ata_queued_cmd *qc);
static void pdc_dma_start(struct ata_queued_cmd *qc); static void pdc_dma_start(struct ata_queued_cmd *qc);
static irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *regs); static irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
static void pdc_eng_timeout(struct ata_port *ap); static void pdc_eng_timeout(struct ata_port *ap);
...@@ -86,6 +85,8 @@ static void pdc_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf); ...@@ -86,6 +85,8 @@ static void pdc_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf);
static void pdc_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf); static void pdc_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf);
static inline void pdc_dma_complete (struct ata_port *ap, static inline void pdc_dma_complete (struct ata_port *ap,
struct ata_queued_cmd *qc, int have_err); struct ata_queued_cmd *qc, int have_err);
static void pdc_irq_clear(struct ata_port *ap);
static int pdc_qc_issue_prot(struct ata_queued_cmd *qc);
static Scsi_Host_Template pdc_sata_sht = { static Scsi_Host_Template pdc_sata_sht = {
.module = THIS_MODULE, .module = THIS_MODULE,
...@@ -112,11 +113,11 @@ static struct ata_port_operations pdc_sata_ops = { ...@@ -112,11 +113,11 @@ static struct ata_port_operations pdc_sata_ops = {
.check_status = ata_check_status_mmio, .check_status = ata_check_status_mmio,
.exec_command = pdc_exec_command_mmio, .exec_command = pdc_exec_command_mmio,
.phy_reset = pdc_phy_reset, .phy_reset = pdc_phy_reset,
.bmdma_setup = pdc_dma_setup,
.bmdma_start = pdc_dma_start,
.qc_prep = pdc_qc_prep, .qc_prep = pdc_qc_prep,
.qc_issue = pdc_qc_issue_prot,
.eng_timeout = pdc_eng_timeout, .eng_timeout = pdc_eng_timeout,
.irq_handler = pdc_interrupt, .irq_handler = pdc_interrupt,
.irq_clear = pdc_irq_clear,
.scr_read = pdc_sata_scr_read, .scr_read = pdc_sata_scr_read,
.scr_write = pdc_sata_scr_write, .scr_write = pdc_sata_scr_write,
.port_start = pdc_port_start, .port_start = pdc_port_start,
...@@ -378,6 +379,14 @@ static inline unsigned int pdc_host_intr( struct ata_port *ap, ...@@ -378,6 +379,14 @@ static inline unsigned int pdc_host_intr( struct ata_port *ap,
return handled; return handled;
} }
static void pdc_irq_clear(struct ata_port *ap)
{
struct ata_host_set *host_set = ap->host_set;
void *mmio = host_set->mmio_base;
readl(mmio + PDC_INT_SEQMASK);
}
static irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *regs) static irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
{ {
struct ata_host_set *host_set = dev_instance; struct ata_host_set *host_set = dev_instance;
...@@ -431,13 +440,7 @@ static irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *r ...@@ -431,13 +440,7 @@ static irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *r
return IRQ_RETVAL(handled); return IRQ_RETVAL(handled);
} }
static void pdc_dma_setup(struct ata_queued_cmd *qc) static inline void pdc_dma_start(struct ata_queued_cmd *qc)
{
/* nothing for now. later, we will call standard
* code in libata-core for ATAPI here */
}
static void pdc_dma_start(struct ata_queued_cmd *qc)
{ {
struct ata_port *ap = qc->ap; struct ata_port *ap = qc->ap;
struct pdc_port_priv *pp = ap->private_data; struct pdc_port_priv *pp = ap->private_data;
...@@ -455,17 +458,35 @@ static void pdc_dma_start(struct ata_queued_cmd *qc) ...@@ -455,17 +458,35 @@ static void pdc_dma_start(struct ata_queued_cmd *qc)
readl((void *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT); /* flush */ readl((void *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT); /* flush */
} }
static int pdc_qc_issue_prot(struct ata_queued_cmd *qc)
{
switch (qc->tf.protocol) {
case ATA_PROT_DMA:
pdc_dma_start(qc);
return 0;
case ATA_PROT_ATAPI_DMA:
BUG();
break;
default:
break;
}
return ata_qc_issue_prot(qc);
}
static void pdc_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf) static void pdc_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf)
{ {
if (tf->protocol != ATA_PROT_DMA) WARN_ON (tf->protocol == ATA_PROT_DMA);
ata_tf_load_mmio(ap, tf); ata_tf_load_mmio(ap, tf);
} }
static void pdc_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf) static void pdc_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf)
{ {
if (tf->protocol != ATA_PROT_DMA) WARN_ON (tf->protocol == ATA_PROT_DMA);
ata_exec_command_mmio(ap, tf); ata_exec_command_mmio(ap, tf);
} }
......
...@@ -86,6 +86,7 @@ struct sil_drivelist { ...@@ -86,6 +86,7 @@ struct sil_drivelist {
{ "ST360015AS", SIL_QUIRK_MOD15WRITE }, { "ST360015AS", SIL_QUIRK_MOD15WRITE },
{ "ST380023AS", SIL_QUIRK_MOD15WRITE }, { "ST380023AS", SIL_QUIRK_MOD15WRITE },
{ "ST3120023AS", SIL_QUIRK_MOD15WRITE }, { "ST3120023AS", SIL_QUIRK_MOD15WRITE },
{ "ST3160023AS", SIL_QUIRK_MOD15WRITE },
{ "ST340014ASL", SIL_QUIRK_MOD15WRITE }, { "ST340014ASL", SIL_QUIRK_MOD15WRITE },
{ "ST360014ASL", SIL_QUIRK_MOD15WRITE }, { "ST360014ASL", SIL_QUIRK_MOD15WRITE },
{ "ST380011ASL", SIL_QUIRK_MOD15WRITE }, { "ST380011ASL", SIL_QUIRK_MOD15WRITE },
...@@ -132,8 +133,10 @@ static struct ata_port_operations sil_ops = { ...@@ -132,8 +133,10 @@ static struct ata_port_operations sil_ops = {
.bmdma_setup = ata_bmdma_setup_mmio, .bmdma_setup = ata_bmdma_setup_mmio,
.bmdma_start = ata_bmdma_start_mmio, .bmdma_start = ata_bmdma_start_mmio,
.qc_prep = ata_qc_prep, .qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
.eng_timeout = ata_eng_timeout, .eng_timeout = ata_eng_timeout,
.irq_handler = ata_interrupt, .irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
.scr_read = sil_scr_read, .scr_read = sil_scr_read,
.scr_write = sil_scr_write, .scr_write = sil_scr_write,
.port_start = ata_port_start, .port_start = ata_port_start,
......
...@@ -101,8 +101,10 @@ static struct ata_port_operations sis_ops = { ...@@ -101,8 +101,10 @@ static struct ata_port_operations sis_ops = {
.bmdma_setup = ata_bmdma_setup_pio, .bmdma_setup = ata_bmdma_setup_pio,
.bmdma_start = ata_bmdma_start_pio, .bmdma_start = ata_bmdma_start_pio,
.qc_prep = ata_qc_prep, .qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
.eng_timeout = ata_eng_timeout, .eng_timeout = ata_eng_timeout,
.irq_handler = ata_interrupt, .irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
.scr_read = sis_scr_read, .scr_read = sis_scr_read,
.scr_write = sis_scr_write, .scr_write = sis_scr_write,
.port_start = ata_port_start, .port_start = ata_port_start,
......
...@@ -234,8 +234,10 @@ static struct ata_port_operations k2_sata_ops = { ...@@ -234,8 +234,10 @@ static struct ata_port_operations k2_sata_ops = {
.bmdma_setup = ata_bmdma_setup_mmio, .bmdma_setup = ata_bmdma_setup_mmio,
.bmdma_start = ata_bmdma_start_mmio, .bmdma_start = ata_bmdma_start_mmio,
.qc_prep = ata_qc_prep, .qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
.eng_timeout = ata_eng_timeout, .eng_timeout = ata_eng_timeout,
.irq_handler = ata_interrupt, .irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
.scr_read = k2_sata_scr_read, .scr_read = k2_sata_scr_read,
.scr_write = k2_sata_scr_write, .scr_write = k2_sata_scr_write,
.port_start = ata_port_start, .port_start = ata_port_start,
......
...@@ -171,6 +171,7 @@ static void pdc20621_get_from_dimm(struct ata_probe_ent *pe, ...@@ -171,6 +171,7 @@ static void pdc20621_get_from_dimm(struct ata_probe_ent *pe,
#endif #endif
static void pdc20621_put_to_dimm(struct ata_probe_ent *pe, static void pdc20621_put_to_dimm(struct ata_probe_ent *pe,
void *psource, u32 offset, u32 size); void *psource, u32 offset, u32 size);
static void pdc20621_irq_clear(struct ata_port *ap);
static Scsi_Host_Template pdc_sata_sht = { static Scsi_Host_Template pdc_sata_sht = {
...@@ -201,8 +202,10 @@ static struct ata_port_operations pdc_20621_ops = { ...@@ -201,8 +202,10 @@ static struct ata_port_operations pdc_20621_ops = {
.bmdma_setup = pdc20621_dma_setup, .bmdma_setup = pdc20621_dma_setup,
.bmdma_start = pdc20621_dma_start, .bmdma_start = pdc20621_dma_start,
.qc_prep = pdc20621_qc_prep, .qc_prep = pdc20621_qc_prep,
.qc_issue = ata_qc_issue_prot,
.eng_timeout = pdc_eng_timeout, .eng_timeout = pdc_eng_timeout,
.irq_handler = pdc20621_interrupt, .irq_handler = pdc20621_interrupt,
.irq_clear = pdc20621_irq_clear,
.port_start = pdc_port_start, .port_start = pdc_port_start,
.port_stop = pdc_port_stop, .port_stop = pdc_port_stop,
.host_stop = pdc20621_host_stop, .host_stop = pdc20621_host_stop,
...@@ -446,7 +449,7 @@ static void pdc20621_qc_prep(struct ata_queued_cmd *qc) ...@@ -446,7 +449,7 @@ static void pdc20621_qc_prep(struct ata_queued_cmd *qc)
unsigned int i, last, idx, total_len = 0, sgt_len; unsigned int i, last, idx, total_len = 0, sgt_len;
u32 *buf = (u32 *) &pp->dimm_buf[PDC_DIMM_HEADER_SZ]; u32 *buf = (u32 *) &pp->dimm_buf[PDC_DIMM_HEADER_SZ];
if (!(qc->flags & ATA_QCFLAG_SG)) if (!(qc->flags & ATA_QCFLAG_DMAMAP))
return; return;
VPRINTK("ata%u: ENTER\n", ap->id); VPRINTK("ata%u: ENTER\n", ap->id);
...@@ -702,6 +705,16 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap, ...@@ -702,6 +705,16 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
return handled; return handled;
} }
static void pdc20621_irq_clear(struct ata_port *ap)
{
struct ata_host_set *host_set = ap->host_set;
void *mmio = host_set->mmio_base;
mmio += PDC_CHIP0_OFS;
readl(mmio + PDC_20621_SEQMASK);
}
static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance, struct pt_regs *regs) static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
{ {
struct ata_host_set *host_set = dev_instance; struct ata_host_set *host_set = dev_instance;
......
...@@ -109,9 +109,12 @@ static struct ata_port_operations svia_sata_ops = { ...@@ -109,9 +109,12 @@ static struct ata_port_operations svia_sata_ops = {
.bmdma_setup = ata_bmdma_setup_pio, .bmdma_setup = ata_bmdma_setup_pio,
.bmdma_start = ata_bmdma_start_pio, .bmdma_start = ata_bmdma_start_pio,
.qc_prep = ata_qc_prep, .qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
.eng_timeout = ata_eng_timeout, .eng_timeout = ata_eng_timeout,
.irq_handler = ata_interrupt, .irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
.scr_read = svia_scr_read, .scr_read = svia_scr_read,
.scr_write = svia_scr_write, .scr_write = svia_scr_write,
......
...@@ -216,8 +216,10 @@ static struct ata_port_operations vsc_sata_ops = { ...@@ -216,8 +216,10 @@ static struct ata_port_operations vsc_sata_ops = {
.bmdma_setup = ata_bmdma_setup_mmio, .bmdma_setup = ata_bmdma_setup_mmio,
.bmdma_start = ata_bmdma_start_mmio, .bmdma_start = ata_bmdma_start_mmio,
.qc_prep = ata_qc_prep, .qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
.eng_timeout = ata_eng_timeout, .eng_timeout = ata_eng_timeout,
.irq_handler = vsc_sata_interrupt, .irq_handler = vsc_sata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
.scr_read = vsc_sata_scr_read, .scr_read = vsc_sata_scr_read,
.scr_write = vsc_sata_scr_write, .scr_write = vsc_sata_scr_write,
.port_start = ata_port_start, .port_start = ata_port_start,
......
...@@ -78,9 +78,11 @@ enum { ...@@ -78,9 +78,11 @@ enum {
ATA_NIEN = (1 << 1), /* disable-irq flag */ ATA_NIEN = (1 << 1), /* disable-irq flag */
ATA_LBA = (1 << 6), /* LBA28 selector */ ATA_LBA = (1 << 6), /* LBA28 selector */
ATA_DEV1 = (1 << 4), /* Select Device 1 (slave) */ ATA_DEV1 = (1 << 4), /* Select Device 1 (slave) */
ATA_BUSY = (1 << 7), /* BSY status bit */
ATA_DEVICE_OBS = (1 << 7) | (1 << 5), /* obs bits in dev reg */ ATA_DEVICE_OBS = (1 << 7) | (1 << 5), /* obs bits in dev reg */
ATA_DEVCTL_OBS = (1 << 3), /* obsolete bit in devctl reg */ ATA_DEVCTL_OBS = (1 << 3), /* obsolete bit in devctl reg */
ATA_BUSY = (1 << 7), /* BSY status bit */
ATA_DRDY = (1 << 6), /* device ready */
ATA_DF = (1 << 5), /* device fault */
ATA_DRQ = (1 << 3), /* data request i/o */ ATA_DRQ = (1 << 3), /* data request i/o */
ATA_ERR = (1 << 0), /* have an error */ ATA_ERR = (1 << 0), /* have an error */
ATA_SRST = (1 << 2), /* software reset */ ATA_SRST = (1 << 2), /* software reset */
...@@ -224,4 +226,10 @@ static inline int is_atapi_taskfile(struct ata_taskfile *tf) ...@@ -224,4 +226,10 @@ static inline int is_atapi_taskfile(struct ata_taskfile *tf)
(tf->protocol == ATA_PROT_ATAPI_DMA); (tf->protocol == ATA_PROT_ATAPI_DMA);
} }
static inline int ata_ok(u8 status)
{
return ((status & (ATA_BUSY | ATA_DRDY | ATA_DF | ATA_DRQ | ATA_ERR))
== ATA_DRDY);
}
#endif /* __LINUX_ATA_H__ */ #endif /* __LINUX_ATA_H__ */
...@@ -112,7 +112,9 @@ enum { ...@@ -112,7 +112,9 @@ enum {
ATA_QCFLAG_ACTIVE = (1 << 1), /* cmd not yet ack'd to scsi lyer */ ATA_QCFLAG_ACTIVE = (1 << 1), /* cmd not yet ack'd to scsi lyer */
ATA_QCFLAG_DMA = (1 << 2), /* data delivered via DMA */ ATA_QCFLAG_DMA = (1 << 2), /* data delivered via DMA */
ATA_QCFLAG_SG = (1 << 4), /* have s/g table? */ ATA_QCFLAG_SG = (1 << 3), /* have s/g table? */
ATA_QCFLAG_SINGLE = (1 << 4), /* no s/g, just a single buffer */
ATA_QCFLAG_DMAMAP = ATA_QCFLAG_SG | ATA_QCFLAG_SINGLE,
/* various lengths of time */ /* various lengths of time */
ATA_TMOUT_EDD = 5 * HZ, /* hueristic */ ATA_TMOUT_EDD = 5 * HZ, /* hueristic */
...@@ -158,7 +160,7 @@ struct ata_port; ...@@ -158,7 +160,7 @@ struct ata_port;
struct ata_queued_cmd; struct ata_queued_cmd;
/* typedefs */ /* typedefs */
typedef void (*ata_qc_cb_t) (struct ata_queued_cmd *qc, unsigned int flags); typedef int (*ata_qc_cb_t) (struct ata_queued_cmd *qc, u8 drv_stat);
struct ata_ioports { struct ata_ioports {
unsigned long cmd_addr; unsigned long cmd_addr;
...@@ -202,6 +204,7 @@ struct ata_host_set { ...@@ -202,6 +204,7 @@ struct ata_host_set {
void *mmio_base; void *mmio_base;
unsigned int n_ports; unsigned int n_ports;
void *private_data; void *private_data;
struct ata_port_operations *ops;
struct ata_port * ports[0]; struct ata_port * ports[0];
}; };
...@@ -215,16 +218,21 @@ struct ata_queued_cmd { ...@@ -215,16 +218,21 @@ struct ata_queued_cmd {
unsigned long flags; /* ATA_QCFLAG_xxx */ unsigned long flags; /* ATA_QCFLAG_xxx */
unsigned int tag; unsigned int tag;
unsigned int n_elem; unsigned int n_elem;
int pci_dma_dir;
unsigned int nsect; unsigned int nsect;
unsigned int cursect; unsigned int cursect;
unsigned int cursg; unsigned int cursg;
unsigned int cursg_ofs; unsigned int cursg_ofs;
struct ata_taskfile tf; struct ata_taskfile tf;
struct scatterlist sgent; struct scatterlist sgent;
void *buf_virt;
struct scatterlist *sg; struct scatterlist *sg;
ata_qc_cb_t callback; ata_qc_cb_t complete_fn;
struct completion *waiting; struct completion *waiting;
...@@ -311,10 +319,14 @@ struct ata_port_operations { ...@@ -311,10 +319,14 @@ 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 (*qc_prep) (struct ata_queued_cmd *qc); void (*qc_prep) (struct ata_queued_cmd *qc);
int (*qc_issue) (struct ata_queued_cmd *qc);
void (*eng_timeout) (struct ata_port *ap); void (*eng_timeout) (struct ata_port *ap);
irqreturn_t (*irq_handler)(int, void *, struct pt_regs *); irqreturn_t (*irq_handler)(int, void *, struct pt_regs *);
void (*irq_clear) (struct ata_port *);
u32 (*scr_read) (struct ata_port *ap, unsigned int sc_reg); u32 (*scr_read) (struct ata_port *ap, unsigned int sc_reg);
void (*scr_write) (struct ata_port *ap, unsigned int sc_reg, void (*scr_write) (struct ata_port *ap, unsigned int sc_reg,
...@@ -372,12 +384,18 @@ extern int ata_port_start (struct ata_port *ap); ...@@ -372,12 +384,18 @@ extern int ata_port_start (struct ata_port *ap);
extern void ata_port_stop (struct ata_port *ap); extern void ata_port_stop (struct ata_port *ap);
extern irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs); extern irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
extern void ata_qc_prep(struct ata_queued_cmd *qc); extern void ata_qc_prep(struct ata_queued_cmd *qc);
extern int ata_qc_issue_prot(struct ata_queued_cmd *qc);
extern void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf,
unsigned int buflen);
extern void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
unsigned int n_elem);
extern void ata_dev_id_string(struct ata_device *dev, unsigned char *s, extern void ata_dev_id_string(struct ata_device *dev, unsigned char *s,
unsigned int ofs, unsigned int len); unsigned int ofs, unsigned int len);
extern void ata_bmdma_setup_mmio (struct ata_queued_cmd *qc); extern void ata_bmdma_setup_mmio (struct ata_queued_cmd *qc);
extern void ata_bmdma_start_mmio (struct ata_queued_cmd *qc); extern void ata_bmdma_start_mmio (struct ata_queued_cmd *qc);
extern void ata_bmdma_setup_pio (struct ata_queued_cmd *qc); extern void ata_bmdma_setup_pio (struct ata_queued_cmd *qc);
extern void ata_bmdma_start_pio (struct ata_queued_cmd *qc); extern void ata_bmdma_start_pio (struct ata_queued_cmd *qc);
extern void ata_bmdma_irq_clear(struct ata_port *ap);
extern int pci_test_config_bits(struct pci_dev *pdev, struct pci_bits *bits); extern int pci_test_config_bits(struct pci_dev *pdev, struct pci_bits *bits);
extern void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat); extern void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat);
extern void ata_eng_timeout(struct ata_port *ap); extern void ata_eng_timeout(struct ata_port *ap);
...@@ -480,6 +498,7 @@ static inline void ata_tf_init(struct ata_port *ap, struct ata_taskfile *tf, uns ...@@ -480,6 +498,7 @@ static inline void ata_tf_init(struct ata_port *ap, struct ata_taskfile *tf, uns
static inline u8 ata_irq_on(struct ata_port *ap) static inline u8 ata_irq_on(struct ata_port *ap)
{ {
struct ata_ioports *ioaddr = &ap->ioaddr; struct ata_ioports *ioaddr = &ap->ioaddr;
u8 tmp;
ap->ctl &= ~ATA_NIEN; ap->ctl &= ~ATA_NIEN;
ap->last_ctl = ap->ctl; ap->last_ctl = ap->ctl;
...@@ -488,7 +507,11 @@ static inline u8 ata_irq_on(struct ata_port *ap) ...@@ -488,7 +507,11 @@ static inline u8 ata_irq_on(struct ata_port *ap)
writeb(ap->ctl, ioaddr->ctl_addr); writeb(ap->ctl, ioaddr->ctl_addr);
else else
outb(ap->ctl, ioaddr->ctl_addr); outb(ap->ctl, ioaddr->ctl_addr);
return ata_wait_idle(ap); tmp = ata_wait_idle(ap);
ap->ops->irq_clear(ap);
return tmp;
} }
static inline u8 ata_irq_ack(struct ata_port *ap, unsigned int chk_drq) static inline u8 ata_irq_ack(struct ata_port *ap, unsigned int chk_drq)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment