struct ata_device *dev,
u16 heads,
u16 sectors);
-static int ata_down_xfermask_limit(struct ata_port *ap, struct ata_device *dev,
- int force_pio0);
-static int ata_down_sata_spd_limit(struct ata_port *ap);
-static int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev);
static unsigned int ata_dev_set_xfermode(struct ata_port *ap,
struct ata_device *dev);
static void ata_dev_xfermask(struct ata_port *ap, struct ata_device *dev);
module_param(atapi_enabled, int, 0444);
MODULE_PARM_DESC(atapi_enabled, "Enable discovery of ATAPI devices (0=off, 1=on)");
+int atapi_dmadir = 0;
+module_param(atapi_dmadir, int, 0444);
+MODULE_PARM_DESC(atapi_dmadir, "Enable ATAPI DMADIR bridge support (0=off, 1=on)");
+
int libata_fua = 0;
module_param_named(fua, libata_fua, int, 0444);
MODULE_PARM_DESC(fua, "FUA support (0=off, 1=on)");
return spd_str[spd - 1];
}
-static void ata_dev_disable(struct ata_port *ap, struct ata_device *dev)
+void ata_dev_disable(struct ata_port *ap, struct ata_device *dev)
{
if (ata_dev_enabled(dev)) {
printk(KERN_WARNING "ata%u: dev %u disabled\n",
* @ap: Port to which the command is sent
* @dev: Device to which the command is sent
* @tf: Taskfile registers for the command and the result
+ * @cdb: CDB for packet command
* @dma_dir: Data tranfer direction of the command
* @buf: Data buffer of the command
* @buflen: Length of data buffer
* None. Should be called with kernel context, might sleep.
*/
-static unsigned
-ata_exec_internal(struct ata_port *ap, struct ata_device *dev,
- struct ata_taskfile *tf,
- int dma_dir, void *buf, unsigned int buflen)
+unsigned ata_exec_internal(struct ata_port *ap, struct ata_device *dev,
+ struct ata_taskfile *tf, const u8 *cdb,
+ int dma_dir, void *buf, unsigned int buflen)
{
u8 command = tf->command;
struct ata_queued_cmd *qc;
BUG_ON(qc == NULL);
qc->tf = *tf;
+ if (cdb)
+ memcpy(qc->cdb, cdb, ATAPI_CDB_LEN);
qc->dma_dir = dma_dir;
if (dma_dir != DMA_NONE) {
ata_sg_init_one(qc, buf, buflen);
tf.protocol = ATA_PROT_PIO;
- err_mask = ata_exec_internal(ap, dev, &tf, DMA_FROM_DEVICE,
+ err_mask = ata_exec_internal(ap, dev, &tf, NULL, DMA_FROM_DEVICE,
id, sizeof(id[0]) * ATA_ID_WORDS);
if (err_mask) {
rc = -EIO;
id[84], id[85], id[86], id[87], id[88]);
/* initialize to-be-configured parameters */
- dev->flags = 0;
+ dev->flags &= ~ATA_DFLAG_CFG_MASK;
dev->max_sectors = 0;
dev->cdb_len = 0;
dev->n_sectors = 0;
*/
static void sata_print_link_status(struct ata_port *ap)
{
- u32 sstatus, tmp;
+ u32 sstatus, scontrol, tmp;
if (!ap->ops->scr_read)
return;
sstatus = scr_read(ap, SCR_STATUS);
+ scontrol = scr_read(ap, SCR_CONTROL);
if (sata_dev_present(ap)) {
tmp = (sstatus >> 4) & 0xf;
- printk(KERN_INFO "ata%u: SATA link up %s (SStatus %X)\n",
- ap->id, sata_spd_string(tmp), sstatus);
+ printk(KERN_INFO
+ "ata%u: SATA link up %s (SStatus %X SControl %X)\n",
+ ap->id, sata_spd_string(tmp), sstatus, scontrol);
} else {
- printk(KERN_INFO "ata%u: SATA link down (SStatus %X)\n",
- ap->id, sstatus);
+ printk(KERN_INFO
+ "ata%u: SATA link down (SStatus %X SControl %X)\n",
+ ap->id, sstatus, scontrol);
}
}
* RETURNS:
* 0 on success, negative errno on failure
*/
-static int ata_down_sata_spd_limit(struct ata_port *ap)
+int ata_down_sata_spd_limit(struct ata_port *ap)
{
u32 spd, mask;
int highbit;
* RETURNS:
* 1 if SATA spd configuration is needed, 0 otherwise.
*/
-static int ata_set_sata_spd_needed(struct ata_port *ap)
+int ata_set_sata_spd_needed(struct ata_port *ap)
{
u32 scontrol;
* RETURNS:
* 0 on success, negative errno on failure
*/
-static int ata_down_xfermask_limit(struct ata_port *ap, struct ata_device *dev,
- int force_pio0)
+int ata_down_xfermask_limit(struct ata_port *ap, struct ata_device *dev,
+ int force_pio0)
{
unsigned long xfer_mask;
int highbit;
unsigned int err_mask;
int rc;
+ dev->flags &= ~ATA_DFLAG_PIO;
if (dev->xfer_shift == ATA_SHIFT_PIO)
dev->flags |= ATA_DFLAG_PIO;
* RETURNS:
* 0 on success, negative errno otherwise
*/
-static int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)
+int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)
{
struct ata_device *dev;
int i, rc = 0, used_dma = 0, found = 0;
ata_std_postreset, classes);
}
-static int ata_do_reset(struct ata_port *ap,
- ata_reset_fn_t reset, ata_postreset_fn_t postreset,
- int verbose, unsigned int *classes)
+int ata_do_reset(struct ata_port *ap,
+ ata_reset_fn_t reset, ata_postreset_fn_t postreset,
+ int verbose, unsigned int *classes)
{
int i, rc;
tf.protocol = ATA_PROT_NODATA;
tf.nsect = dev->xfer_mode;
- err_mask = ata_exec_internal(ap, dev, &tf, DMA_NONE, NULL, 0);
+ err_mask = ata_exec_internal(ap, dev, &tf, NULL, DMA_NONE, NULL, 0);
DPRINTK("EXIT, err_mask=%x\n", err_mask);
return err_mask;
tf.nsect = sectors;
tf.device |= (heads - 1) & 0x0f; /* max head = num. of heads - 1 */
- err_mask = ata_exec_internal(ap, dev, &tf, DMA_NONE, NULL, 0);
+ err_mask = ata_exec_internal(ap, dev, &tf, NULL, DMA_NONE, NULL, 0);
DPRINTK("EXIT, err_mask=%x\n", err_mask);
return err_mask;
/**
* ata_pio_poll - poll using PIO, depending on current state
- * @ap: the target ata_port
+ * @qc: qc in progress
*
* LOCKING:
* None. (executing in kernel thread context)
* RETURNS:
* timeout value to use
*/
-
-static unsigned long ata_pio_poll(struct ata_port *ap)
+static unsigned long ata_pio_poll(struct ata_queued_cmd *qc)
{
- struct ata_queued_cmd *qc;
+ struct ata_port *ap = qc->ap;
u8 status;
unsigned int poll_state = HSM_ST_UNKNOWN;
unsigned int reg_state = HSM_ST_UNKNOWN;
- qc = ata_qc_from_tag(ap, ap->active_tag);
- WARN_ON(qc == NULL);
-
switch (ap->hsm_task_state) {
case HSM_ST:
case HSM_ST_POLL:
/**
* ata_pio_complete - check if drive is busy or idle
- * @ap: the target ata_port
+ * @qc: qc to complete
*
* LOCKING:
* None. (executing in kernel thread context)
* RETURNS:
* Non-zero if qc completed, zero otherwise.
*/
-
-static int ata_pio_complete (struct ata_port *ap)
+static int ata_pio_complete(struct ata_queued_cmd *qc)
{
- struct ata_queued_cmd *qc;
+ struct ata_port *ap = qc->ap;
u8 drv_stat;
/*
}
}
- qc = ata_qc_from_tag(ap, ap->active_tag);
- WARN_ON(qc == NULL);
-
drv_stat = ata_wait_idle(ap);
if (!ata_ok(drv_stat)) {
qc->err_mask |= __ac_err_mask(drv_stat);
/**
* ata_pio_block - start PIO on a block
- * @ap: the target ata_port
+ * @qc: qc to transfer block for
*
* LOCKING:
* None. (executing in kernel thread context)
*/
-
-static void ata_pio_block(struct ata_port *ap)
+static void ata_pio_block(struct ata_queued_cmd *qc)
{
- struct ata_queued_cmd *qc;
+ struct ata_port *ap = qc->ap;
u8 status;
/*
}
}
- qc = ata_qc_from_tag(ap, ap->active_tag);
- WARN_ON(qc == NULL);
-
/* check error */
if (status & (ATA_ERR | ATA_DF)) {
qc->err_mask |= AC_ERR_DEV;
}
}
-static void ata_pio_error(struct ata_port *ap)
+static void ata_pio_error(struct ata_queued_cmd *qc)
{
- struct ata_queued_cmd *qc;
-
- qc = ata_qc_from_tag(ap, ap->active_tag);
- WARN_ON(qc == NULL);
+ struct ata_port *ap = qc->ap;
if (qc->tf.command != ATA_CMD_PACKET)
printk(KERN_WARNING "ata%u: dev %u PIO error\n",
static void ata_pio_task(void *_data)
{
- struct ata_port *ap = _data;
+ struct ata_queued_cmd *qc = _data;
+ struct ata_port *ap = qc->ap;
unsigned long timeout;
int qc_completed;
return;
case HSM_ST:
- ata_pio_block(ap);
+ ata_pio_block(qc);
break;
case HSM_ST_LAST:
- qc_completed = ata_pio_complete(ap);
+ qc_completed = ata_pio_complete(qc);
break;
case HSM_ST_POLL:
case HSM_ST_LAST_POLL:
- timeout = ata_pio_poll(ap);
+ timeout = ata_pio_poll(qc);
break;
case HSM_ST_TMOUT:
case HSM_ST_ERR:
- ata_pio_error(ap);
+ ata_pio_error(qc);
return;
}
if (timeout)
- ata_port_queue_task(ap, ata_pio_task, ap, timeout);
+ ata_port_queue_task(ap, ata_pio_task, qc, timeout);
else if (!qc_completed)
goto fsm_start;
}
/**
* atapi_packet_task - Write CDB bytes to hardware
- * @_data: Port to which ATAPI device is attached.
+ * @_data: qc in progress
*
* When device has indicated its readiness to accept
* a CDB, this function is called. Send the CDB.
* LOCKING:
* Kernel thread context (may sleep)
*/
-
static void atapi_packet_task(void *_data)
{
- struct ata_port *ap = _data;
- struct ata_queued_cmd *qc;
+ struct ata_queued_cmd *qc = _data;
+ struct ata_port *ap = qc->ap;
u8 status;
- qc = ata_qc_from_tag(ap, ap->active_tag);
- WARN_ON(qc == NULL);
- WARN_ON(!(qc->flags & ATA_QCFLAG_ACTIVE));
-
/* sleep-wait for BSY to clear */
DPRINTK("busy wait\n");
if (ata_busy_sleep(ap, ATA_TMOUT_CDB_QUICK, ATA_TMOUT_CDB)) {
/* PIO commands are handled by polling */
ap->hsm_task_state = HSM_ST;
- ata_port_queue_task(ap, ata_pio_task, ap, 0);
+ ata_port_queue_task(ap, ata_pio_task, qc, 0);
}
return;
ata_poll_qc_complete(qc);
}
-/**
- * ata_qc_timeout - Handle timeout of queued command
- * @qc: Command that timed out
- *
- * Some part of the kernel (currently, only the SCSI layer)
- * has noticed that the active command on port @ap has not
- * completed after a specified length of time. Handle this
- * condition by disabling DMA (if necessary) and completing
- * transactions, with error if necessary.
- *
- * This also handles the case of the "lost interrupt", where
- * for some reason (possibly hardware bug, possibly driver bug)
- * an interrupt was not delivered to the driver, even though the
- * transaction completed successfully.
- *
- * LOCKING:
- * Inherited from SCSI layer (none, can sleep)
- */
-
-static void ata_qc_timeout(struct ata_queued_cmd *qc)
-{
- struct ata_port *ap = qc->ap;
- struct ata_host_set *host_set = ap->host_set;
- u8 host_stat = 0, drv_stat;
- unsigned long flags;
-
- DPRINTK("ENTER\n");
-
- ap->hsm_task_state = HSM_ST_IDLE;
-
- spin_lock_irqsave(&host_set->lock, flags);
-
- switch (qc->tf.protocol) {
-
- case ATA_PROT_DMA:
- case ATA_PROT_ATAPI_DMA:
- host_stat = ap->ops->bmdma_status(ap);
-
- /* before we do anything else, clear DMA-Start bit */
- ap->ops->bmdma_stop(qc);
-
- /* fall through */
-
- default:
- ata_altstatus(ap);
- drv_stat = ata_chk_status(ap);
-
- /* ack bmdma irq events */
- ap->ops->irq_clear(ap);
-
- printk(KERN_ERR "ata%u: command 0x%x timeout, stat 0x%x host_stat 0x%x\n",
- ap->id, qc->tf.command, drv_stat, host_stat);
-
- /* complete taskfile transaction */
- qc->err_mask |= ac_err_mask(drv_stat);
- break;
- }
-
- spin_unlock_irqrestore(&host_set->lock, flags);
-
- ata_eh_qc_complete(qc);
-
- DPRINTK("EXIT\n");
-}
-
-/**
- * ata_eng_timeout - Handle timeout of queued command
- * @ap: Port on which timed-out command is active
- *
- * Some part of the kernel (currently, only the SCSI layer)
- * has noticed that the active command on port @ap has not
- * completed after a specified length of time. Handle this
- * condition by disabling DMA (if necessary) and completing
- * transactions, with error if necessary.
- *
- * This also handles the case of the "lost interrupt", where
- * for some reason (possibly hardware bug, possibly driver bug)
- * an interrupt was not delivered to the driver, even though the
- * transaction completed successfully.
- *
- * LOCKING:
- * Inherited from SCSI layer (none, can sleep)
- */
-
-void ata_eng_timeout(struct ata_port *ap)
-{
- DPRINTK("ENTER\n");
-
- ata_qc_timeout(ata_qc_from_tag(ap, ap->active_tag));
-
- DPRINTK("EXIT\n");
-}
-
/**
* ata_qc_new - Request an available ATA command, for queueing
* @ap: Port associated with device @dev
ata_qc_set_polling(qc);
ata_tf_to_host(ap, &qc->tf);
ap->hsm_task_state = HSM_ST;
- ata_port_queue_task(ap, ata_pio_task, ap, 0);
+ ata_port_queue_task(ap, ata_pio_task, qc, 0);
break;
case ATA_PROT_ATAPI:
ata_qc_set_polling(qc);
ata_tf_to_host(ap, &qc->tf);
- ata_port_queue_task(ap, atapi_packet_task, ap, 0);
+ ata_port_queue_task(ap, atapi_packet_task, qc, 0);
break;
case ATA_PROT_ATAPI_NODATA:
ap->flags |= ATA_FLAG_NOINTR;
ata_tf_to_host(ap, &qc->tf);
- ata_port_queue_task(ap, atapi_packet_task, ap, 0);
+ ata_port_queue_task(ap, atapi_packet_task, qc, 0);
break;
case ATA_PROT_ATAPI_DMA:
ap->flags |= ATA_FLAG_NOINTR;
ap->ops->tf_load(ap, &qc->tf); /* load tf registers */
ap->ops->bmdma_setup(qc); /* set up bmdma */
- ata_port_queue_task(ap, atapi_packet_task, ap, 0);
+ ata_port_queue_task(ap, atapi_packet_task, qc, 0);
break;
default:
tf.flags |= ATA_TFLAG_DEVICE;
tf.protocol = ATA_PROT_NODATA;
- err = ata_exec_internal(ap, dev, &tf, DMA_NONE, NULL, 0);
+ err = ata_exec_internal(ap, dev, &tf, NULL, DMA_NONE, NULL, 0);
if (err)
printk(KERN_ERR "%s: ata command failed: %d\n",
__FUNCTION__, err);
EXPORT_SYMBOL_GPL(ata_sg_init_one);
EXPORT_SYMBOL_GPL(__ata_qc_complete);
EXPORT_SYMBOL_GPL(ata_qc_issue_prot);
-EXPORT_SYMBOL_GPL(ata_eng_timeout);
EXPORT_SYMBOL_GPL(ata_tf_load);
EXPORT_SYMBOL_GPL(ata_tf_read);
EXPORT_SYMBOL_GPL(ata_noop_dev_select);
EXPORT_SYMBOL_GPL(ata_port_queue_task);
EXPORT_SYMBOL_GPL(ata_scsi_ioctl);
EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
-EXPORT_SYMBOL_GPL(ata_scsi_error);
EXPORT_SYMBOL_GPL(ata_scsi_slave_config);
EXPORT_SYMBOL_GPL(ata_scsi_release);
EXPORT_SYMBOL_GPL(ata_host_intr);
EXPORT_SYMBOL_GPL(ata_id_string);
EXPORT_SYMBOL_GPL(ata_id_c_string);
EXPORT_SYMBOL_GPL(ata_scsi_simulate);
-EXPORT_SYMBOL_GPL(ata_eh_qc_complete);
-EXPORT_SYMBOL_GPL(ata_eh_qc_retry);
EXPORT_SYMBOL_GPL(ata_pio_need_iordy);
EXPORT_SYMBOL_GPL(ata_timing_compute);
EXPORT_SYMBOL_GPL(ata_device_resume);
EXPORT_SYMBOL_GPL(ata_scsi_device_suspend);
EXPORT_SYMBOL_GPL(ata_scsi_device_resume);
+
+EXPORT_SYMBOL_GPL(ata_scsi_error);
+EXPORT_SYMBOL_GPL(ata_eng_timeout);
+EXPORT_SYMBOL_GPL(ata_eh_qc_complete);
+EXPORT_SYMBOL_GPL(ata_eh_qc_retry);