}
/**
+ * ata_tf_read_block - Read block address from ATA taskfile
+ * @tf: ATA taskfile of interest
+ * @dev: ATA device @tf belongs to
+ *
+ * LOCKING:
+ * None.
+ *
+ * Read block address from @tf. This function can handle all
+ * three address formats - LBA, LBA48 and CHS. tf->protocol and
+ * flags select the address format to use.
+ *
+ * RETURNS:
+ * Block address read from @tf.
+ */
+u64 ata_tf_read_block(struct ata_taskfile *tf, struct ata_device *dev)
+{
+ u64 block = 0;
+
+ if (tf->flags & ATA_TFLAG_LBA) {
+ if (tf->flags & ATA_TFLAG_LBA48) {
+ block |= (u64)tf->hob_lbah << 40;
+ block |= (u64)tf->hob_lbam << 32;
+ block |= tf->hob_lbal << 24;
+ } else
+ block |= (tf->device & 0xf) << 24;
+
+ block |= tf->lbah << 16;
+ block |= tf->lbam << 8;
+ block |= tf->lbal;
+ } else {
+ u32 cyl, head, sect;
+
+ cyl = tf->lbam | (tf->lbah << 8);
+ head = tf->device & 0xf;
+ sect = tf->lbal;
+
+ block = (cyl * dev->heads + head) * dev->sectors + sect;
+ }
+
+ return block;
+}
+
+/**
* ata_pack_xfermask - Pack pio, mwdma and udma masks into xfer_mask
* @pio_mask: pio_mask
* @mwdma_mask: mwdma_mask
* ata_dev_read_id - Read ID data from the specified device
* @dev: target device
* @p_class: pointer to class of the target device (may be changed)
- * @post_reset: is this read ID post-reset?
+ * @flags: ATA_READID_* flags
* @id: buffer to read IDENTIFY data into
*
* Read ID data from the specified device. ATA_CMD_ID_ATA is
* 0 on success, -errno otherwise.
*/
int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
- int post_reset, u16 *id)
+ unsigned int flags, u16 *id)
{
struct ata_port *ap = dev->ap;
unsigned int class = *p_class;
tf.protocol = ATA_PROT_PIO;
+ /* presence detection using polling IDENTIFY? */
+ if (flags & ATA_READID_DETECT)
+ tf.flags |= ATA_TFLAG_POLLING;
+
err_mask = ata_exec_internal(dev, &tf, NULL, DMA_FROM_DEVICE,
id, sizeof(id[0]) * ATA_ID_WORDS);
if (err_mask) {
+ if ((flags & ATA_READID_DETECT) &&
+ (err_mask & AC_ERR_NODEV_HINT)) {
+ DPRINTK("ata%u.%d: NODEV after polling detection\n",
+ ap->id, dev->devno);
+ return -ENOENT;
+ }
+
rc = -EIO;
reason = "I/O error";
goto err_out;
goto err_out;
}
- if (post_reset && class == ATA_DEV_ATA) {
+ if ((flags & ATA_READID_POSTRESET) && class == ATA_DEV_ATA) {
/*
* The exact sequence expected by certain pre-ATA4 drives is:
* SRST RESET
/* current CHS translation info (id[53-58]) might be
* changed. reread the identify device info.
*/
- post_reset = 0;
+ flags &= ~ATA_READID_POSTRESET;
goto retry;
}
}
if (ata_id_has_lba48(id)) {
dev->flags |= ATA_DFLAG_LBA48;
lba_desc = "LBA48";
+
+ if (dev->n_sectors >= (1UL << 28) &&
+ ata_id_has_flush_ext(id))
+ dev->flags |= ATA_DFLAG_FLUSH_EXT;
}
/* config NCQ */
cdb_intr_string);
}
+ /* determine max_sectors */
+ dev->max_sectors = ATA_MAX_SECTORS;
+ if (dev->flags & ATA_DFLAG_LBA48)
+ dev->max_sectors = ATA_MAX_SECTORS_LBA48;
+
if (dev->horkage & ATA_HORKAGE_DIAGNOSTIC) {
/* Let the user know. We don't want to disallow opens for
rescue purposes, or in case the vendor is just a blithering
if (!ata_dev_enabled(dev))
continue;
- rc = ata_dev_read_id(dev, &dev->class, 1, dev->id);
+ rc = ata_dev_read_id(dev, &dev->class, ATA_READID_POSTRESET,
+ dev->id);
if (rc)
goto fail;
/**
* ata_dev_revalidate - Revalidate ATA device
* @dev: device to revalidate
- * @post_reset: is this revalidation after reset?
+ * @readid_flags: read ID flags
*
* Re-read IDENTIFY page and make sure @dev is still attached to
* the port.
* RETURNS:
* 0 on success, negative errno otherwise
*/
-int ata_dev_revalidate(struct ata_device *dev, int post_reset)
+int ata_dev_revalidate(struct ata_device *dev, unsigned int readid_flags)
{
unsigned int class = dev->class;
u16 *id = (void *)dev->ap->sector_buf;
}
/* read ID data */
- rc = ata_dev_read_id(dev, &class, post_reset, id);
+ rc = ata_dev_read_id(dev, &class, readid_flags, id);
if (rc)
goto fail;
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->orig_n_elem = 1;
qc->buf_virt = buf;
qc->nbytes = buflen;
- sg = qc->__sg;
- sg_init_one(sg, buf, buflen);
+ sg_init_one(&qc->sgent, buf, buflen);
}
/**
/* device stops HSM for abort/error */
qc->err_mask |= AC_ERR_DEV;
else
- /* HSM violation. Let EH handle this */
- qc->err_mask |= AC_ERR_HSM;
+ /* HSM violation. Let EH handle this.
+ * Phantom devices also trigger this
+ * condition. Mark hint.
+ */
+ qc->err_mask |= AC_ERR_HSM |
+ AC_ERR_NODEV_HINT;
ap->hsm_task_state = HSM_ST_ERR;
goto fsm_start;
qc->complete_fn(qc);
}
+static void fill_result_tf(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+
+ ap->ops->tf_read(ap, &qc->result_tf);
+ qc->result_tf.flags = qc->tf.flags;
+}
+
/**
* ata_qc_complete - Complete an active ATA command
* @qc: Command to complete
if (unlikely(qc->flags & ATA_QCFLAG_FAILED)) {
if (!ata_tag_internal(qc->tag)) {
/* always fill result TF for failed qc */
- ap->ops->tf_read(ap, &qc->result_tf);
+ fill_result_tf(qc);
ata_qc_schedule_eh(qc);
return;
}
/* read result TF if requested */
if (qc->flags & ATA_QCFLAG_RESULT_TF)
- ap->ops->tf_read(ap, &qc->result_tf);
+ fill_result_tf(qc);
__ata_qc_complete(qc);
} else {
/* read result TF if failed or requested */
if (qc->err_mask || qc->flags & ATA_QCFLAG_RESULT_TF)
- ap->ops->tf_read(ap, &qc->result_tf);
+ fill_result_tf(qc);
__ata_qc_complete(qc);
}
if (!ata_try_flush_cache(dev))
return 0;
- if (ata_id_has_flush_ext(dev->id))
+ if (dev->flags & ATA_DFLAG_FLUSH_EXT)
cmd = ATA_CMD_FLUSH_EXT;
else
cmd = ATA_CMD_FLUSH;