|
@@ -294,28 +294,6 @@ void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf)
|
|
ata_exec_command_pio(ap, tf);
|
|
ata_exec_command_pio(ap, tf);
|
|
}
|
|
}
|
|
|
|
|
|
-/**
|
|
|
|
- * ata_exec - issue ATA command to host controller
|
|
|
|
- * @ap: port to which command is being issued
|
|
|
|
- * @tf: ATA taskfile register set
|
|
|
|
- *
|
|
|
|
- * Issues PIO/MMIO write to ATA command register, with proper
|
|
|
|
- * synchronization with interrupt handler / other threads.
|
|
|
|
- *
|
|
|
|
- * LOCKING:
|
|
|
|
- * Obtains host_set lock.
|
|
|
|
- */
|
|
|
|
-
|
|
|
|
-static inline void ata_exec(struct ata_port *ap, const struct ata_taskfile *tf)
|
|
|
|
-{
|
|
|
|
- unsigned long flags;
|
|
|
|
-
|
|
|
|
- DPRINTK("ata%u: cmd 0x%X\n", ap->id, tf->command);
|
|
|
|
- spin_lock_irqsave(&ap->host_set->lock, flags);
|
|
|
|
- ap->ops->exec_command(ap, tf);
|
|
|
|
- spin_unlock_irqrestore(&ap->host_set->lock, flags);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
/**
|
|
/**
|
|
* ata_tf_to_host - issue ATA taskfile to host controller
|
|
* ata_tf_to_host - issue ATA taskfile to host controller
|
|
* @ap: port to which command is being issued
|
|
* @ap: port to which command is being issued
|
|
@@ -326,30 +304,11 @@ static inline void ata_exec(struct ata_port *ap, const struct ata_taskfile *tf)
|
|
* other threads.
|
|
* other threads.
|
|
*
|
|
*
|
|
* LOCKING:
|
|
* LOCKING:
|
|
- * Obtains host_set lock.
|
|
|
|
- */
|
|
|
|
-
|
|
|
|
-static void ata_tf_to_host(struct ata_port *ap, const struct ata_taskfile *tf)
|
|
|
|
-{
|
|
|
|
- ap->ops->tf_load(ap, tf);
|
|
|
|
-
|
|
|
|
- ata_exec(ap, tf);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/**
|
|
|
|
- * ata_tf_to_host_nolock - issue ATA taskfile to host controller
|
|
|
|
- * @ap: port to which command is being issued
|
|
|
|
- * @tf: ATA taskfile register set
|
|
|
|
- *
|
|
|
|
- * Issues ATA taskfile register set to ATA host controller,
|
|
|
|
- * with proper synchronization with interrupt handler and
|
|
|
|
- * other threads.
|
|
|
|
- *
|
|
|
|
- * LOCKING:
|
|
|
|
* spin_lock_irqsave(host_set lock)
|
|
* spin_lock_irqsave(host_set lock)
|
|
*/
|
|
*/
|
|
|
|
|
|
-void ata_tf_to_host_nolock(struct ata_port *ap, const struct ata_taskfile *tf)
|
|
|
|
|
|
+static inline void ata_tf_to_host(struct ata_port *ap,
|
|
|
|
+ const struct ata_taskfile *tf)
|
|
{
|
|
{
|
|
ap->ops->tf_load(ap, tf);
|
|
ap->ops->tf_load(ap, tf);
|
|
ap->ops->exec_command(ap, tf);
|
|
ap->ops->exec_command(ap, tf);
|
|
@@ -1912,12 +1871,14 @@ static void ata_bus_post_reset(struct ata_port *ap, unsigned int devmask)
|
|
*
|
|
*
|
|
* LOCKING:
|
|
* LOCKING:
|
|
* PCI/etc. bus probe sem.
|
|
* PCI/etc. bus probe sem.
|
|
|
|
+ * Obtains host_set lock.
|
|
*
|
|
*
|
|
*/
|
|
*/
|
|
|
|
|
|
static unsigned int ata_bus_edd(struct ata_port *ap)
|
|
static unsigned int ata_bus_edd(struct ata_port *ap)
|
|
{
|
|
{
|
|
struct ata_taskfile tf;
|
|
struct ata_taskfile tf;
|
|
|
|
+ unsigned long flags;
|
|
|
|
|
|
/* set up execute-device-diag (bus reset) taskfile */
|
|
/* set up execute-device-diag (bus reset) taskfile */
|
|
/* also, take interrupts to a known state (disabled) */
|
|
/* also, take interrupts to a known state (disabled) */
|
|
@@ -1928,7 +1889,9 @@ static unsigned int ata_bus_edd(struct ata_port *ap)
|
|
tf.protocol = ATA_PROT_NODATA;
|
|
tf.protocol = ATA_PROT_NODATA;
|
|
|
|
|
|
/* do bus reset */
|
|
/* do bus reset */
|
|
|
|
+ spin_lock_irqsave(&ap->host_set->lock, flags);
|
|
ata_tf_to_host(ap, &tf);
|
|
ata_tf_to_host(ap, &tf);
|
|
|
|
+ spin_unlock_irqrestore(&ap->host_set->lock, flags);
|
|
|
|
|
|
/* spec says at least 2ms. but who knows with those
|
|
/* spec says at least 2ms. but who knows with those
|
|
* crazy ATAPI devices...
|
|
* crazy ATAPI devices...
|
|
@@ -3555,7 +3518,7 @@ int ata_qc_issue_prot(struct ata_queued_cmd *qc)
|
|
|
|
|
|
switch (qc->tf.protocol) {
|
|
switch (qc->tf.protocol) {
|
|
case ATA_PROT_NODATA:
|
|
case ATA_PROT_NODATA:
|
|
- ata_tf_to_host_nolock(ap, &qc->tf);
|
|
|
|
|
|
+ ata_tf_to_host(ap, &qc->tf);
|
|
break;
|
|
break;
|
|
|
|
|
|
case ATA_PROT_DMA:
|
|
case ATA_PROT_DMA:
|
|
@@ -3566,20 +3529,20 @@ int ata_qc_issue_prot(struct ata_queued_cmd *qc)
|
|
|
|
|
|
case ATA_PROT_PIO: /* load tf registers, initiate polling pio */
|
|
case ATA_PROT_PIO: /* load tf registers, initiate polling pio */
|
|
ata_qc_set_polling(qc);
|
|
ata_qc_set_polling(qc);
|
|
- ata_tf_to_host_nolock(ap, &qc->tf);
|
|
|
|
|
|
+ ata_tf_to_host(ap, &qc->tf);
|
|
ap->hsm_task_state = HSM_ST;
|
|
ap->hsm_task_state = HSM_ST;
|
|
queue_work(ata_wq, &ap->pio_task);
|
|
queue_work(ata_wq, &ap->pio_task);
|
|
break;
|
|
break;
|
|
|
|
|
|
case ATA_PROT_ATAPI:
|
|
case ATA_PROT_ATAPI:
|
|
ata_qc_set_polling(qc);
|
|
ata_qc_set_polling(qc);
|
|
- ata_tf_to_host_nolock(ap, &qc->tf);
|
|
|
|
|
|
+ ata_tf_to_host(ap, &qc->tf);
|
|
queue_work(ata_wq, &ap->packet_task);
|
|
queue_work(ata_wq, &ap->packet_task);
|
|
break;
|
|
break;
|
|
|
|
|
|
case ATA_PROT_ATAPI_NODATA:
|
|
case ATA_PROT_ATAPI_NODATA:
|
|
ap->flags |= ATA_FLAG_NOINTR;
|
|
ap->flags |= ATA_FLAG_NOINTR;
|
|
- ata_tf_to_host_nolock(ap, &qc->tf);
|
|
|
|
|
|
+ ata_tf_to_host(ap, &qc->tf);
|
|
queue_work(ata_wq, &ap->packet_task);
|
|
queue_work(ata_wq, &ap->packet_task);
|
|
break;
|
|
break;
|
|
|
|
|