Commit 1ad2c4d1 authored by Jeff Garzik's avatar Jeff Garzik

Merge redhat.com:/spare/repo/sata-hacks/atapi-hacks-2.6

into redhat.com:/spare/repo/libata-2.6
parents e92f75e7 32b467bb
......@@ -136,6 +136,7 @@ static struct ata_port_operations piix_pata_ops = {
.phy_reset = piix_pata_phy_reset,
.bmdma_setup = ata_bmdma_setup_pio,
.bmdma_start = ata_bmdma_start_pio,
.fill_sg = ata_fill_sg,
.eng_timeout = ata_eng_timeout,
......@@ -158,6 +159,7 @@ static struct ata_port_operations piix_sata_ops = {
.phy_reset = piix_sata_phy_reset,
.bmdma_setup = ata_bmdma_setup_pio,
.bmdma_start = ata_bmdma_start_pio,
.fill_sg = ata_fill_sg,
.eng_timeout = ata_eng_timeout,
......
......@@ -2396,16 +2396,18 @@ int ata_qc_issue(struct ata_queued_cmd *qc)
struct ata_port *ap = qc->ap;
struct scsi_cmnd *cmd = qc->scsicmd;
/* set up SG table */
if (cmd->use_sg) {
if (ata_sg_setup(qc))
goto err_out;
} else {
if (ata_sg_setup_one(qc))
goto err_out;
}
if (qc->flags & ATA_QCFLAG_SG) {
/* set up SG table */
if (cmd->use_sg) {
if (ata_sg_setup(qc))
goto err_out;
} else {
if (ata_sg_setup_one(qc))
goto err_out;
}
ap->ops->fill_sg(qc);
ap->ops->fill_sg(qc);
}
qc->ap->active_tag = qc->tag;
qc->flags |= ATA_QCFLAG_ACTIVE;
......@@ -2445,17 +2447,28 @@ static int ata_qc_issue_prot(struct ata_queued_cmd *qc)
case ATA_PROT_DMA:
ap->ops->tf_load(ap, &qc->tf); /* load tf registers */
ap->ops->bmdma_setup(qc); /* set up bmdma */
ap->ops->bmdma_start(qc); /* initiate bmdma */
break;
case ATA_PROT_PIO: /* load tf registers, initiate polling pio */
qc->flags |= ATA_QCFLAG_POLL;
qc->tf.ctl |= ATA_NIEN; /* disable interrupts */
ata_qc_set_polling(qc);
ata_tf_to_host_nolock(ap, &qc->tf);
ap->pio_task_state = PIO_ST;
queue_work(ata_wq, &ap->pio_task);
break;
case ATA_PROT_ATAPI:
ata_tf_to_host_nolock(ap, &qc->tf);
queue_work(ata_wq, &ap->packet_task);
break;
case ATA_PROT_ATAPI_DMA:
ap->ops->tf_load(ap, &qc->tf); /* load tf registers */
ap->ops->bmdma_setup(qc); /* set up bmdma */
queue_work(ata_wq, &ap->packet_task);
break;
default:
WARN_ON(1);
return -1;
......@@ -2465,14 +2478,14 @@ static int ata_qc_issue_prot(struct ata_queued_cmd *qc)
}
/**
* ata_bmdma_start_mmio -
* @qc:
* ata_bmdma_setup_mmio - Set up PCI IDE BMDMA transaction (MMIO)
* @qc: Info associated with this ATA transaction.
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
*/
void ata_bmdma_start_mmio (struct ata_queued_cmd *qc)
void ata_bmdma_setup_mmio (struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
......@@ -2496,8 +2509,24 @@ void ata_bmdma_start_mmio (struct ata_queued_cmd *qc)
/* issue r/w command */
ap->ops->exec_command(ap, &qc->tf);
}
/**
* ata_bmdma_start_mmio - Start a PCI IDE BMDMA transaction (MMIO)
* @qc: Info associated with this ATA transaction.
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
*/
void ata_bmdma_start_mmio (struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
void *mmio = (void *) ap->ioaddr.bmdma_addr;
u8 dmactl;
/* start host DMA transaction */
dmactl = readb(mmio + ATA_DMA_CMD);
writeb(dmactl | ATA_DMA_START, mmio + ATA_DMA_CMD);
/* Strictly, one may wish to issue a readb() here, to
......@@ -2514,14 +2543,14 @@ void ata_bmdma_start_mmio (struct ata_queued_cmd *qc)
}
/**
* ata_bmdma_start_pio -
* @qc:
* ata_bmdma_setup_pio - Set up PCI IDE BMDMA transaction (PIO)
* @qc: Info associated with this ATA transaction.
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
*/
void ata_bmdma_start_pio (struct ata_queued_cmd *qc)
void ata_bmdma_setup_pio (struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
......@@ -2544,8 +2573,23 @@ void ata_bmdma_start_pio (struct ata_queued_cmd *qc)
/* issue r/w command */
ap->ops->exec_command(ap, &qc->tf);
}
/**
* ata_bmdma_start_pio - Start a PCI IDE BMDMA transaction (PIO)
* @qc: Info associated with this ATA transaction.
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
*/
void ata_bmdma_start_pio (struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
u8 dmactl;
/* start host DMA transaction */
dmactl = inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
outb(dmactl | ATA_DMA_START,
ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
}
......@@ -2689,7 +2733,7 @@ irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
struct ata_queued_cmd *qc;
qc = ata_qc_from_tag(ap, ap->active_tag);
if (qc && ((qc->flags & ATA_QCFLAG_POLL) == 0))
if (qc && (!(qc->tf.ctl & ATA_NIEN)))
handled += ata_host_intr(ap, qc);
}
}
......@@ -2755,20 +2799,6 @@ static unsigned long ata_thread_iter(struct ata_port *ap)
return timeout;
}
void atapi_start(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
qc->flags |= ATA_QCFLAG_ACTIVE;
ap->active_tag = qc->tag;
ata_dev_select(ap, qc->dev->devno, 1, 0);
ata_tf_to_host_nolock(ap, &qc->tf);
queue_work(ata_wq, &ap->packet_task);
VPRINTK("EXIT\n");
}
/**
* atapi_packet_task - Write CDB bytes to hardware
* @_data: Port to which ATAPI device is attached.
......@@ -2811,7 +2841,7 @@ static void atapi_packet_task(void *_data)
/* if we are DMA'ing, irq handler takes over from here */
if (qc->tf.protocol == ATA_PROT_ATAPI_DMA) {
/* FIXME: start DMA here */
ap->ops->bmdma_start(qc); /* initiate bmdma */
} else {
ap->pio_task_state = PIO_ST;
queue_work(ata_wq, &ap->pio_task);
......@@ -3475,7 +3505,9 @@ EXPORT_SYMBOL_GPL(ata_port_start);
EXPORT_SYMBOL_GPL(ata_port_stop);
EXPORT_SYMBOL_GPL(ata_interrupt);
EXPORT_SYMBOL_GPL(ata_fill_sg);
EXPORT_SYMBOL_GPL(ata_bmdma_setup_pio);
EXPORT_SYMBOL_GPL(ata_bmdma_start_pio);
EXPORT_SYMBOL_GPL(ata_bmdma_setup_mmio);
EXPORT_SYMBOL_GPL(ata_bmdma_start_mmio);
EXPORT_SYMBOL_GPL(ata_port_probe);
EXPORT_SYMBOL_GPL(sata_phy_reset);
......
......@@ -885,53 +885,20 @@ void ata_scsi_badcmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), u8
}
/**
* atapi_scsi_queuecmd - Send CDB to ATAPI device
* @ap: Port to which ATAPI device is attached.
* @dev: Target device for CDB.
* @cmd: SCSI command being sent to device.
* @done: SCSI command completion function.
*
* Sends CDB to ATAPI device. If the Linux SCSI layer sends a
* non-data command, then this function handles the command
* directly, via polling. Otherwise, the bmdma engine is started.
* atapi_xlat - Initialize PACKET taskfile
* @qc: command structure to be initialized
* @scsicmd: SCSI CDB associated with this PACKET command
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
*
* RETURNS:
* Zero on success, non-zero on failure.
*/
static void atapi_scsi_queuecmd(struct ata_port *ap, struct ata_device *dev,
struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
static unsigned int atapi_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
{
struct ata_queued_cmd *qc;
u8 *scsicmd = cmd->cmnd;
VPRINTK("ENTER, drv_stat = 0x%x\n", ata_chk_status(ap));
if (cmd->sc_data_direction == SCSI_DATA_UNKNOWN) {
DPRINTK("unknown data, scsicmd 0x%x\n", scsicmd[0]);
ata_bad_cdb(cmd, done);
return;
}
switch(scsicmd[0]) {
case READ_6:
case WRITE_6:
case MODE_SELECT:
case MODE_SENSE:
DPRINTK("read6/write6/modesel/modesense trap\n");
ata_bad_scsiop(cmd, done);
return;
default:
/* do nothing */
break;
}
qc = ata_scsi_qc_new(ap, dev, cmd, done);
if (!qc) {
printk(KERN_ERR "ata%u: command queue empty\n", ap->id);
return;
}
struct scsi_cmnd *cmd = qc->scsicmd;
qc->flags |= ATA_QCFLAG_ATAPI;
......@@ -943,17 +910,19 @@ static void atapi_scsi_queuecmd(struct ata_port *ap, struct ata_device *dev,
qc->tf.command = ATA_CMD_PACKET;
if (cmd->sc_data_direction == SCSI_DATA_NONE) {
if ((cmd->sc_data_direction == SCSI_DATA_NONE) ||
((qc->flags & ATA_QCFLAG_DMA) == 0)) {
ata_qc_set_polling(qc);
qc->tf.protocol = ATA_PROT_ATAPI;
qc->flags |= ATA_QCFLAG_POLL;
qc->tf.ctl |= ATA_NIEN; /* disable interrupts */
qc->tf.lbam = (8 * 1024) & 0xff;
qc->tf.lbah = (8 * 1024) >> 8;
} else {
qc->tf.protocol = ATA_PROT_ATAPI_DMA;
qc->flags |= ATA_QCFLAG_SG; /* data is present; dma-map it */
qc->tf.protocol = ATA_PROT_ATAPI_DMA;
qc->tf.feature |= ATAPI_PKT_DMA;
}
atapi_start(qc);
return 0;
}
/**
......@@ -1092,7 +1061,7 @@ int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
else
ata_scsi_simulate(ap, dev, cmd, done);
} else
atapi_scsi_queuecmd(ap, dev, cmd, done);
ata_scsi_translate(ap, dev, cmd, done, atapi_xlat);
out_unlock:
return 0;
......
......@@ -44,7 +44,6 @@ extern int ata_qc_issue(struct ata_queued_cmd *qc);
extern void ata_dev_select(struct ata_port *ap, unsigned int device,
unsigned int wait, unsigned int can_sleep);
extern void ata_tf_to_host_nolock(struct ata_port *ap, struct ata_taskfile *tf);
extern void atapi_start(struct ata_queued_cmd *qc);
/* libata-scsi.c */
......
......@@ -74,6 +74,7 @@ struct pdc_port_priv {
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 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 irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
static void pdc_eng_timeout(struct ata_port *ap);
......@@ -111,6 +112,7 @@ static struct ata_port_operations pdc_sata_ops = {
.check_status = ata_check_status_mmio,
.exec_command = pdc_exec_command_mmio,
.phy_reset = pdc_phy_reset,
.bmdma_setup = pdc_dma_setup,
.bmdma_start = pdc_dma_start,
.fill_sg = pdc_fill_sg,
.eng_timeout = pdc_eng_timeout,
......@@ -419,7 +421,7 @@ static irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *r
struct ata_queued_cmd *qc;
qc = ata_qc_from_tag(ap, ap->active_tag);
if (qc && ((qc->flags & ATA_QCFLAG_POLL) == 0))
if (qc && (!(qc->tf.ctl & ATA_NIEN)))
handled += pdc_host_intr(ap, qc);
}
}
......@@ -431,6 +433,12 @@ static irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *r
return IRQ_RETVAL(handled);
}
static void pdc_dma_setup(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;
......
......@@ -129,6 +129,7 @@ static struct ata_port_operations sil_ops = {
.exec_command = ata_exec_command_mmio,
.phy_reset = sata_phy_reset,
.post_set_mode = sil_post_set_mode,
.bmdma_setup = ata_bmdma_setup_mmio,
.bmdma_start = ata_bmdma_start_mmio,
.fill_sg = ata_fill_sg,
.eng_timeout = ata_eng_timeout,
......
......@@ -98,6 +98,7 @@ static struct ata_port_operations sis_ops = {
.check_status = ata_check_status_pio,
.exec_command = ata_exec_command_pio,
.phy_reset = sata_phy_reset,
.bmdma_setup = ata_bmdma_setup_pio,
.bmdma_start = ata_bmdma_start_pio,
.fill_sg = ata_fill_sg,
.eng_timeout = ata_eng_timeout,
......
......@@ -231,6 +231,7 @@ static struct ata_port_operations k2_sata_ops = {
.check_status = k2_stat_check_status,
.exec_command = ata_exec_command_mmio,
.phy_reset = sata_phy_reset,
.bmdma_setup = ata_bmdma_setup_mmio,
.bmdma_start = ata_bmdma_start_mmio,
.fill_sg = ata_fill_sg,
.eng_timeout = ata_eng_timeout,
......
......@@ -146,6 +146,7 @@ struct pdc_host_priv {
static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
static void pdc20621_dma_setup(struct ata_queued_cmd *qc);
static void pdc20621_dma_start(struct ata_queued_cmd *qc);
static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
static void pdc_eng_timeout(struct ata_port *ap);
......@@ -197,6 +198,7 @@ static struct ata_port_operations pdc_20621_ops = {
.check_status = ata_check_status_mmio,
.exec_command = pdc_exec_command_mmio,
.phy_reset = pdc_20621_phy_reset,
.bmdma_setup = pdc20621_dma_setup,
.bmdma_start = pdc20621_dma_start,
.fill_sg = pdc20621_fill_sg,
.eng_timeout = pdc_eng_timeout,
......@@ -568,6 +570,12 @@ static void pdc20621_dump_hdma(struct ata_queued_cmd *qc)
static inline void pdc20621_dump_hdma(struct ata_queued_cmd *qc) { }
#endif /* ATA_VERBOSE_DEBUG */
static void pdc20621_dma_setup(struct ata_queued_cmd *qc)
{
/* nothing for now. later, we will call standard
* code in libata-core for ATAPI here */
}
static void pdc20621_dma_start(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
......@@ -740,7 +748,7 @@ static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance, struct pt_re
struct ata_queued_cmd *qc;
qc = ata_qc_from_tag(ap, ap->active_tag);
if (qc && ((qc->flags & ATA_QCFLAG_POLL) == 0))
if (qc && (!(qc->tf.ctl & ATA_NIEN)))
handled += pdc20621_host_intr(ap, qc, (i > 4),
mmio_base);
}
......
......@@ -106,6 +106,7 @@ static struct ata_port_operations svia_sata_ops = {
.phy_reset = sata_phy_reset,
.bmdma_setup = ata_bmdma_setup_pio,
.bmdma_start = ata_bmdma_start_pio,
.fill_sg = ata_fill_sg,
.eng_timeout = ata_eng_timeout,
......
......@@ -175,7 +175,7 @@ irqreturn_t vsc_sata_interrupt (int irq, void *dev_instance, struct pt_regs *reg
struct ata_queued_cmd *qc;
qc = ata_qc_from_tag(ap, ap->active_tag);
if (qc && ((qc->flags & ATA_QCFLAG_POLL) == 0))
if (qc && (!(qc->tf.ctl & ATA_NIEN)))
handled += ata_host_intr(ap, qc);
}
}
......@@ -213,6 +213,7 @@ static struct ata_port_operations vsc_sata_ops = {
.exec_command = ata_exec_command_mmio,
.check_status = ata_check_status_mmio,
.phy_reset = sata_phy_reset,
.bmdma_setup = ata_bmdma_setup_mmio,
.bmdma_start = ata_bmdma_start_mmio,
.fill_sg = ata_fill_sg,
.eng_timeout = ata_eng_timeout,
......
......@@ -112,7 +112,6 @@ enum {
ATA_QCFLAG_DMA = (1 << 2), /* data delivered via DMA */
ATA_QCFLAG_ATAPI = (1 << 3), /* is ATAPI packet command? */
ATA_QCFLAG_SG = (1 << 4), /* have s/g table? */
ATA_QCFLAG_POLL = (1 << 5), /* polling, no interrupts */
/* various lengths of time */
ATA_TMOUT_EDD = 5 * HZ, /* hueristic */
......@@ -335,6 +334,7 @@ struct ata_port_operations {
void (*phy_reset) (struct ata_port *ap);
void (*post_set_mode) (struct ata_port *ap);
void (*bmdma_setup) (struct ata_queued_cmd *qc);
void (*bmdma_start) (struct ata_queued_cmd *qc);
void (*fill_sg) (struct ata_queued_cmd *qc);
void (*eng_timeout) (struct ata_port *ap);
......@@ -397,7 +397,9 @@ extern int ata_port_start (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 void ata_fill_sg(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_setup_pio (struct ata_queued_cmd *qc);
extern void ata_bmdma_start_pio (struct ata_queued_cmd *qc);
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, unsigned int done_late);
......@@ -473,6 +475,12 @@ static inline u8 ata_wait_idle(struct ata_port *ap)
return status;
}
static inline void ata_qc_set_polling(struct ata_queued_cmd *qc)
{
qc->flags &= ~ATA_QCFLAG_DMA;
qc->tf.ctl |= ATA_NIEN;
}
static inline struct ata_queued_cmd *ata_qc_from_tag (struct ata_port *ap,
unsigned int tag)
{
......
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