aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-transport.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/libata-transport.c')
-rw-r--r--drivers/ata/libata-transport.c71
1 files changed, 56 insertions, 15 deletions
diff --git a/drivers/ata/libata-transport.c b/drivers/ata/libata-transport.c
index 34bb4608bdc6..e4fb9d1b9b39 100644
--- a/drivers/ata/libata-transport.c
+++ b/drivers/ata/libata-transport.c
@@ -9,7 +9,7 @@
* and various sysfs attributes to expose these topologies and management
* interfaces to user-space.
*
- * There are 3 objects defined in in this class:
+ * There are 3 objects defined in this class:
* - ata_port
* - ata_link
* - ata_device
@@ -163,7 +163,7 @@ static struct {
{ AC_ERR_INVALID, "InvalidArg" },
{ AC_ERR_OTHER, "Unknown" },
{ AC_ERR_NODEV_HINT, "NoDeviceHint" },
- { AC_ERR_NCQ, "NCQError" }
+ { AC_ERR_NCQ, "NCQError" }
};
ata_bitfield_name_match(err, ata_err_names)
@@ -196,7 +196,7 @@ static struct {
{ XFER_PIO_0, "XFER_PIO_0" },
{ XFER_PIO_SLOW, "XFER_PIO_SLOW" }
};
-ata_bitfield_name_match(xfer,ata_xfer_names)
+ata_bitfield_name_search(xfer, ata_xfer_names)
/*
* ATA Port attributes
@@ -301,7 +301,9 @@ int ata_tport_add(struct device *parent,
pm_runtime_enable(dev);
pm_runtime_forbid(dev);
- transport_add_device(dev);
+ error = transport_add_device(dev);
+ if (error)
+ goto tport_transport_add_err;
transport_configure_device(dev);
error = ata_tlink_add(&ap->link);
@@ -312,22 +314,52 @@ int ata_tport_add(struct device *parent,
tport_link_err:
transport_remove_device(dev);
+ tport_transport_add_err:
device_del(dev);
tport_err:
transport_destroy_device(dev);
put_device(dev);
- ata_host_put(ap->host);
return error;
}
+/**
+ * ata_port_classify - determine device type based on ATA-spec signature
+ * @ap: ATA port device on which the classification should be run
+ * @tf: ATA taskfile register set for device to be identified
+ *
+ * A wrapper around ata_dev_classify() to provide additional logging
+ *
+ * RETURNS:
+ * Device type, %ATA_DEV_ATA, %ATA_DEV_ATAPI, %ATA_DEV_PMP,
+ * %ATA_DEV_ZAC, or %ATA_DEV_UNKNOWN the event of failure.
+ */
+unsigned int ata_port_classify(struct ata_port *ap,
+ const struct ata_taskfile *tf)
+{
+ int i;
+ unsigned int class = ata_dev_classify(tf);
+
+ /* Start with index '1' to skip the 'unknown' entry */
+ for (i = 1; i < ARRAY_SIZE(ata_class_names); i++) {
+ if (ata_class_names[i].value == class) {
+ ata_port_dbg(ap, "found %s device by sig\n",
+ ata_class_names[i].name);
+ return class;
+ }
+ }
+
+ ata_port_info(ap, "found unknown device (class %u)\n", class);
+ return class;
+}
+EXPORT_SYMBOL_GPL(ata_port_classify);
/*
* ATA link attributes
*/
static int noop(int x) { return x; }
-#define ata_link_show_linkspeed(field, format) \
+#define ata_link_show_linkspeed(field, format) \
static ssize_t \
show_ata_link_##field(struct device *dev, \
struct device_attribute *attr, char *buf) \
@@ -416,7 +448,7 @@ int ata_tlink_add(struct ata_link *link)
dev->release = ata_tlink_release;
if (ata_is_host_link(link))
dev_set_name(dev, "link%d", ap->print_id);
- else
+ else
dev_set_name(dev, "link%d.%d", ap->print_id, link->pmp);
transport_setup_device(dev);
@@ -426,7 +458,9 @@ int ata_tlink_add(struct ata_link *link)
goto tlink_err;
}
- transport_add_device(dev);
+ error = transport_add_device(dev);
+ if (error)
+ goto tlink_transport_err;
transport_configure_device(dev);
ata_for_each_dev(ata_dev, link, ALL) {
@@ -441,6 +475,7 @@ int ata_tlink_add(struct ata_link *link)
ata_tdev_delete(ata_dev);
}
transport_remove_device(dev);
+ tlink_transport_err:
device_del(dev);
tlink_err:
transport_destroy_device(dev);
@@ -472,7 +507,7 @@ ata_dev_attr(xfer, dma_mode);
ata_dev_attr(xfer, xfer_mode);
-#define ata_dev_show_simple(field, format_string, cast) \
+#define ata_dev_show_simple(field, format_string, cast) \
static ssize_t \
show_ata_dev_##field(struct device *dev, \
struct device_attribute *attr, char *buf) \
@@ -482,9 +517,9 @@ show_ata_dev_##field(struct device *dev, \
return scnprintf(buf, 20, format_string, cast ata_dev->field); \
}
-#define ata_dev_simple_attr(field, format_string, type) \
+#define ata_dev_simple_attr(field, format_string, type) \
ata_dev_show_simple(field, format_string, (type)) \
-static DEVICE_ATTR(field, S_IRUGO, \
+ static DEVICE_ATTR(field, S_IRUGO, \
show_ata_dev_##field, NULL)
ata_dev_simple_attr(spdn_cnt, "%d\n", int);
@@ -502,7 +537,7 @@ static int ata_show_ering(struct ata_ering_entry *ent, void *void_arg)
seconds = div_u64_rem(ent->timestamp, HZ, &rem);
arg->written += sprintf(arg->buf + arg->written,
- "[%5llu.%09lu]", seconds,
+ "[%5llu.%09lu]", seconds,
rem * NSEC_PER_SEC / HZ);
arg->written += get_ata_err_names(ent->err_mask,
arg->buf + arg->written);
@@ -667,7 +702,7 @@ static int ata_tdev_add(struct ata_device *ata_dev)
dev->release = ata_tdev_release;
if (ata_is_host_link(link))
dev_set_name(dev, "dev%d.%d", ap->print_id,ata_dev->devno);
- else
+ else
dev_set_name(dev, "dev%d.%d.0", ap->print_id, link->pmp);
transport_setup_device(dev);
@@ -678,7 +713,13 @@ static int ata_tdev_add(struct ata_device *ata_dev)
return error;
}
- transport_add_device(dev);
+ error = transport_add_device(dev);
+ if (error) {
+ device_del(dev);
+ ata_tdev_free(ata_dev);
+ return error;
+ }
+
transport_configure_device(dev);
return 0;
}
@@ -689,7 +730,7 @@ static int ata_tdev_add(struct ata_device *ata_dev)
*/
#define SETUP_TEMPLATE(attrb, field, perm, test) \
- i->private_##attrb[count] = dev_attr_##field; \
+ i->private_##attrb[count] = dev_attr_##field; \
i->private_##attrb[count].attr.mode = perm; \
i->attrb[count] = &i->private_##attrb[count]; \
if (test) \