pata_it821x: Driver updates and reworking
- Add support for the RDC 1010 variant
- Rework the core library to have a read_id method. This allows the hacky
bits of it821x to go and prepares us for pata_hd
- Switch from WARN to BUG in ata_id_string as it will reboot if you get
it wrong so WARN won't be seen
- Allow the issue of command 0xFC on the 821x. This is needed to query
rebuild status.
- Tidy up printk formatting
- Do more ident rewriting on RAID volumes to handle firmware provided
ident data which is rather wonky
- Report the firmware revision and device layout in RAID mode
- Don't try and disable raid on the 8211 or RDC - they don't have the
relevant bits
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index f69d154..5ba96c5 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -1132,6 +1132,8 @@
{
unsigned int c;
+ BUG_ON(len & 1);
+
while (len > 0) {
c = id[ofs] >> 8;
*s = c;
@@ -1165,8 +1167,6 @@
{
unsigned char *p;
- WARN_ON(!(len & 1));
-
ata_id_string(id, s, ofs, len - 1);
p = s + strnlen(s, len - 1);
@@ -1886,6 +1886,23 @@
}
/**
+ * ata_do_dev_read_id - default ID read method
+ * @dev: device
+ * @tf: proposed taskfile
+ * @id: data buffer
+ *
+ * Issue the identify taskfile and hand back the buffer containing
+ * identify data. For some RAID controllers and for pre ATA devices
+ * this function is wrapped or replaced by the driver
+ */
+unsigned int ata_do_dev_read_id(struct ata_device *dev,
+ struct ata_taskfile *tf, u16 *id)
+{
+ return ata_exec_internal(dev, tf, NULL, DMA_FROM_DEVICE,
+ id, sizeof(id[0]) * ATA_ID_WORDS, 0);
+}
+
+/**
* 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)
@@ -1920,7 +1937,7 @@
if (ata_msg_ctl(ap))
ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __func__);
- retry:
+retry:
ata_tf_init(dev, &tf);
switch (class) {
@@ -1948,8 +1965,11 @@
*/
tf.flags |= ATA_TFLAG_POLLING;
- err_mask = ata_exec_internal(dev, &tf, NULL, DMA_FROM_DEVICE,
- id, sizeof(id[0]) * ATA_ID_WORDS, 0);
+ if (ap->ops->read_id)
+ err_mask = ap->ops->read_id(dev, &tf, id);
+ else
+ err_mask = ata_do_dev_read_id(dev, &tf, id);
+
if (err_mask) {
if (err_mask & AC_ERR_NODEV_HINT) {
ata_dev_printk(dev, KERN_DEBUG,
@@ -6283,6 +6303,7 @@
#endif /* CONFIG_PM */
EXPORT_SYMBOL_GPL(ata_id_string);
EXPORT_SYMBOL_GPL(ata_id_c_string);
+EXPORT_SYMBOL_GPL(ata_do_dev_read_id);
EXPORT_SYMBOL_GPL(ata_scsi_simulate);
EXPORT_SYMBOL_GPL(ata_pio_need_iordy);