libata: add @timeout to ata_exec_internal[_sg]()

Add @timeout argument to ata_exec_internal[_sg]().  If 0, default
timeout ata_probe_timeout is used.

Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
This commit is contained in:
Tejun Heo 2007-10-09 15:05:44 +09:00 committed by Jeff Garzik
parent 5f226c6bf7
commit 2b789108fc
4 changed files with 26 additions and 17 deletions

View file

@ -478,7 +478,7 @@ static int taskfile_load_raw(struct ata_device *dev,
tf.lbal, tf.lbam, tf.lbah, tf.device); tf.lbal, tf.lbam, tf.lbah, tf.device);
rtf = tf; rtf = tf;
err_mask = ata_exec_internal(dev, &rtf, NULL, DMA_NONE, NULL, 0); err_mask = ata_exec_internal(dev, &rtf, NULL, DMA_NONE, NULL, 0, 0);
if (err_mask) { if (err_mask) {
ata_dev_printk(dev, KERN_ERR, ata_dev_printk(dev, KERN_ERR,
"ACPI cmd %02x/%02x:%02x:%02x:%02x:%02x:%02x failed " "ACPI cmd %02x/%02x:%02x:%02x:%02x:%02x:%02x failed "

View file

@ -926,7 +926,7 @@ static int ata_read_native_max_address(struct ata_device *dev, u64 *max_sectors)
tf.protocol |= ATA_PROT_NODATA; tf.protocol |= ATA_PROT_NODATA;
tf.device |= ATA_LBA; tf.device |= ATA_LBA;
err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0); err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0);
if (err_mask) { if (err_mask) {
ata_dev_printk(dev, KERN_WARNING, "failed to read native " ata_dev_printk(dev, KERN_WARNING, "failed to read native "
"max address (err_mask=0x%x)\n", err_mask); "max address (err_mask=0x%x)\n", err_mask);
@ -988,7 +988,7 @@ static int ata_set_max_sectors(struct ata_device *dev, u64 new_sectors)
tf.lbam = (new_sectors >> 8) & 0xff; tf.lbam = (new_sectors >> 8) & 0xff;
tf.lbah = (new_sectors >> 16) & 0xff; tf.lbah = (new_sectors >> 16) & 0xff;
err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0); err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0);
if (err_mask) { if (err_mask) {
ata_dev_printk(dev, KERN_WARNING, "failed to set " ata_dev_printk(dev, KERN_WARNING, "failed to set "
"max address (err_mask=0x%x)\n", err_mask); "max address (err_mask=0x%x)\n", err_mask);
@ -1394,6 +1394,7 @@ static void ata_qc_complete_internal(struct ata_queued_cmd *qc)
* @dma_dir: Data tranfer direction of the command * @dma_dir: Data tranfer direction of the command
* @sg: sg list for the data buffer of the command * @sg: sg list for the data buffer of the command
* @n_elem: Number of sg entries * @n_elem: Number of sg entries
* @timeout: Timeout in msecs (0 for default)
* *
* Executes libata internal command with timeout. @tf contains * Executes libata internal command with timeout. @tf contains
* command on entry and result on return. Timeout and error * command on entry and result on return. Timeout and error
@ -1410,7 +1411,7 @@ static void ata_qc_complete_internal(struct ata_queued_cmd *qc)
unsigned ata_exec_internal_sg(struct ata_device *dev, unsigned ata_exec_internal_sg(struct ata_device *dev,
struct ata_taskfile *tf, const u8 *cdb, struct ata_taskfile *tf, const u8 *cdb,
int dma_dir, struct scatterlist *sg, int dma_dir, struct scatterlist *sg,
unsigned int n_elem) unsigned int n_elem, unsigned long timeout)
{ {
struct ata_link *link = dev->link; struct ata_link *link = dev->link;
struct ata_port *ap = link->ap; struct ata_port *ap = link->ap;
@ -1486,7 +1487,10 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,
spin_unlock_irqrestore(ap->lock, flags); spin_unlock_irqrestore(ap->lock, flags);
rc = wait_for_completion_timeout(&wait, ata_probe_timeout); if (!timeout)
timeout = ata_probe_timeout * 1000 / HZ;
rc = wait_for_completion_timeout(&wait, msecs_to_jiffies(timeout));
ata_port_flush_task(ap); ata_port_flush_task(ap);
@ -1571,6 +1575,7 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,
* @dma_dir: Data tranfer direction of the command * @dma_dir: Data tranfer direction of the command
* @buf: Data buffer of the command * @buf: Data buffer of the command
* @buflen: Length of data buffer * @buflen: Length of data buffer
* @timeout: Timeout in msecs (0 for default)
* *
* Wrapper around ata_exec_internal_sg() which takes simple * Wrapper around ata_exec_internal_sg() which takes simple
* buffer instead of sg list. * buffer instead of sg list.
@ -1583,7 +1588,8 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,
*/ */
unsigned ata_exec_internal(struct ata_device *dev, unsigned ata_exec_internal(struct ata_device *dev,
struct ata_taskfile *tf, const u8 *cdb, struct ata_taskfile *tf, const u8 *cdb,
int dma_dir, void *buf, unsigned int buflen) int dma_dir, void *buf, unsigned int buflen,
unsigned long timeout)
{ {
struct scatterlist *psg = NULL, sg; struct scatterlist *psg = NULL, sg;
unsigned int n_elem = 0; unsigned int n_elem = 0;
@ -1595,7 +1601,8 @@ unsigned ata_exec_internal(struct ata_device *dev,
n_elem++; n_elem++;
} }
return ata_exec_internal_sg(dev, tf, cdb, dma_dir, psg, n_elem); return ata_exec_internal_sg(dev, tf, cdb, dma_dir, psg, n_elem,
timeout);
} }
/** /**
@ -1622,7 +1629,7 @@ unsigned int ata_do_simple_cmd(struct ata_device *dev, u8 cmd)
tf.flags |= ATA_TFLAG_DEVICE; tf.flags |= ATA_TFLAG_DEVICE;
tf.protocol = ATA_PROT_NODATA; tf.protocol = ATA_PROT_NODATA;
return ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0); return ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0);
} }
/** /**
@ -1737,7 +1744,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
tf.flags |= ATA_TFLAG_POLLING; tf.flags |= ATA_TFLAG_POLLING;
err_mask = ata_exec_internal(dev, &tf, NULL, DMA_FROM_DEVICE, err_mask = ata_exec_internal(dev, &tf, NULL, DMA_FROM_DEVICE,
id, sizeof(id[0]) * ATA_ID_WORDS); id, sizeof(id[0]) * ATA_ID_WORDS, 0);
if (err_mask) { if (err_mask) {
if (err_mask & AC_ERR_NODEV_HINT) { if (err_mask & AC_ERR_NODEV_HINT) {
DPRINTK("ata%u.%d: NODEV after polling detection\n", DPRINTK("ata%u.%d: NODEV after polling detection\n",
@ -1796,7 +1803,8 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
tf.feature = SETFEATURES_SPINUP; tf.feature = SETFEATURES_SPINUP;
tf.protocol = ATA_PROT_NODATA; tf.protocol = ATA_PROT_NODATA;
tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0); err_mask = ata_exec_internal(dev, &tf, NULL,
DMA_NONE, NULL, 0, 0);
if (err_mask && id[2] != 0x738c) { if (err_mask && id[2] != 0x738c) {
rc = -EIO; rc = -EIO;
reason = "SPINUP failed"; reason = "SPINUP failed";
@ -4157,7 +4165,7 @@ static unsigned int ata_dev_set_xfermode(struct ata_device *dev)
tf.protocol = ATA_PROT_NODATA; tf.protocol = ATA_PROT_NODATA;
tf.nsect = dev->xfer_mode; tf.nsect = dev->xfer_mode;
err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0); err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0);
DPRINTK("EXIT, err_mask=%x\n", err_mask); DPRINTK("EXIT, err_mask=%x\n", err_mask);
return err_mask; return err_mask;
@ -4193,7 +4201,7 @@ static unsigned int ata_dev_set_AN(struct ata_device *dev, u8 enable)
tf.protocol = ATA_PROT_NODATA; tf.protocol = ATA_PROT_NODATA;
tf.nsect = SATA_AN; tf.nsect = SATA_AN;
err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0); err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0);
DPRINTK("EXIT, err_mask=%x\n", err_mask); DPRINTK("EXIT, err_mask=%x\n", err_mask);
return err_mask; return err_mask;
@ -4231,7 +4239,7 @@ static unsigned int ata_dev_init_params(struct ata_device *dev,
tf.nsect = sectors; tf.nsect = sectors;
tf.device |= (heads - 1) & 0x0f; /* max head = num. of heads - 1 */ tf.device |= (heads - 1) & 0x0f; /* max head = num. of heads - 1 */
err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0); err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0);
/* A clean abort indicates an original or just out of spec drive /* A clean abort indicates an original or just out of spec drive
and we should continue as we issue the setup based on the and we should continue as we issue the setup based on the
drive reported working geometry */ drive reported working geometry */

View file

@ -1249,7 +1249,7 @@ static unsigned int ata_read_log_page(struct ata_device *dev,
tf.protocol = ATA_PROT_PIO; tf.protocol = ATA_PROT_PIO;
err_mask = ata_exec_internal(dev, &tf, NULL, DMA_FROM_DEVICE, err_mask = ata_exec_internal(dev, &tf, NULL, DMA_FROM_DEVICE,
buf, sectors * ATA_SECT_SIZE); buf, sectors * ATA_SECT_SIZE, 0);
DPRINTK("EXIT, err_mask=%x\n", err_mask); DPRINTK("EXIT, err_mask=%x\n", err_mask);
return err_mask; return err_mask;
@ -1363,7 +1363,7 @@ static unsigned int atapi_eh_request_sense(struct ata_queued_cmd *qc)
} }
return ata_exec_internal(dev, &tf, cdb, DMA_FROM_DEVICE, return ata_exec_internal(dev, &tf, cdb, DMA_FROM_DEVICE,
sense_buf, SCSI_SENSE_BUFFERSIZE); sense_buf, SCSI_SENSE_BUFFERSIZE, 0);
} }
/** /**

View file

@ -69,11 +69,12 @@ extern void ata_dev_disable(struct ata_device *dev);
extern void ata_port_flush_task(struct ata_port *ap); extern void ata_port_flush_task(struct ata_port *ap);
extern unsigned ata_exec_internal(struct ata_device *dev, extern unsigned ata_exec_internal(struct ata_device *dev,
struct ata_taskfile *tf, const u8 *cdb, struct ata_taskfile *tf, const u8 *cdb,
int dma_dir, void *buf, unsigned int buflen); int dma_dir, void *buf, unsigned int buflen,
unsigned long timeout);
extern unsigned ata_exec_internal_sg(struct ata_device *dev, extern unsigned ata_exec_internal_sg(struct ata_device *dev,
struct ata_taskfile *tf, const u8 *cdb, struct ata_taskfile *tf, const u8 *cdb,
int dma_dir, struct scatterlist *sg, int dma_dir, struct scatterlist *sg,
unsigned int n_elem); unsigned int n_elem, unsigned long timeout);
extern unsigned int ata_do_simple_cmd(struct ata_device *dev, u8 cmd); extern unsigned int ata_do_simple_cmd(struct ata_device *dev, u8 cmd);
extern int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, extern int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
unsigned int flags, u16 *id); unsigned int flags, u16 *id);