xref: /onnv-gate/usr/src/cmd/hal/hald/solaris/devinfo_usb.c (revision 2916:ba92c662e4ef)
12912Sartem /***************************************************************************
22912Sartem  *
32912Sartem  * devinfo_usb.h : USB devices
42912Sartem  *
52912Sartem  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
62912Sartem  * Use is subject to license terms.
72912Sartem  *
82912Sartem  * Licensed under the Academic Free License version 2.1
92912Sartem  *
102912Sartem  **************************************************************************/
112912Sartem 
12*2916Sartem #pragma ident	"%Z%%M%	%I%	%E% SMI"
132912Sartem 
142912Sartem #include <stdio.h>
152912Sartem #include <string.h>
162912Sartem #include <libdevinfo.h>
172912Sartem #include <sys/types.h>
182912Sartem #include <sys/mkdev.h>
192912Sartem #include <sys/stat.h>
202912Sartem 
212912Sartem #include "../osspec.h"
222912Sartem #include "../logger.h"
232912Sartem #include "../hald.h"
242912Sartem #include "../hald_dbus.h"
252912Sartem #include "../device_info.h"
262912Sartem #include "../util.h"
272912Sartem #include "../ids.h"
282912Sartem #include "hotplug.h"
292912Sartem #include "devinfo.h"
302912Sartem #include "devinfo_usb.h"
312912Sartem 
322912Sartem HalDevice *devinfo_usb_add(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type);
332912Sartem static HalDevice *devinfo_usb_if_add(HalDevice *d, di_node_t node, gchar *devfs_path, int ifnum);
342912Sartem static HalDevice *devinfo_usb_scsa2usb_add(HalDevice *d, di_node_t node, gchar *devfs_path);
352912Sartem 
362912Sartem DevinfoDevHandler devinfo_usb_handler = {
372912Sartem         devinfo_usb_add,
382912Sartem 	NULL,
392912Sartem 	NULL,
402912Sartem 	NULL,
412912Sartem 	NULL,
422912Sartem         NULL
432912Sartem };
442912Sartem 
452912Sartem HalDevice *
462912Sartem devinfo_usb_add(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type)
472912Sartem {
482912Sartem 	HalDevice *d, *nd = NULL;
492912Sartem 	char	*s;
502912Sartem 	int	*i, *vid;
512912Sartem 	char	*driver_name, *binding_name;
522912Sartem         char    if_devfs_path[HAL_PATH_MAX];
532912Sartem 
542912Sartem 	/*
552912Sartem 	 * we distinguish USB devices by presence of "usb-vendor-id"
562912Sartem 	 * property. should USB devices have "device_type"?
572912Sartem 	 */
582912Sartem         if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "usb-vendor-id", &vid) <= 0) {
592912Sartem 		return (NULL);
602912Sartem 	}
612912Sartem 
622912Sartem 	d = hal_device_new ();
632912Sartem 
642912Sartem 	devinfo_set_default_properties (d, parent, node, devfs_path);
652912Sartem 	hal_device_property_set_string (d, "info.bus", "usb_device");
662912Sartem 	PROP_STR(d, node, s, "usb-product-name", "info.product");
672912Sartem 	PROP_STR(d, node, s, "usb-product-name", "usb_device.product");
682912Sartem 	PROP_STR(d, node, s, "usb-vendor-name", "usb_device.vendor");
692912Sartem 	PROP_INT(d, node, i, "usb-vendor-id", "usb_device.vendor_id");
702912Sartem 	PROP_INT(d, node, i, "usb-product-id", "usb_device.product_id");
712912Sartem 	PROP_INT(d, node, i, "usb-revision-id", "usb_device.device_revision_bcd");
722912Sartem 	PROP_INT(d, node, i, "usb-release-id", "usb_device.version_bcd");
732912Sartem 	PROP_STR(d, node, s, "usb-serialno", "usb_device.serial");
742912Sartem 
752912Sartem 	/* class, subclass */
762912Sartem 	/* hal_device_property_set_int (d, "usb_device.device_class", 8); */
772912Sartem 
782912Sartem 	/* binding name tells us if driver is bound to interface or device */
792912Sartem 	if (((binding_name = di_binding_name(node)) != NULL) &&
802912Sartem 	    (strncmp(binding_name, "usbif,", sizeof ("usbif,") - 1) == 0)) {
812912Sartem 		snprintf(if_devfs_path, sizeof (if_devfs_path), "%s:if%d", devfs_path, 0);
822912Sartem 		if ((nd = devinfo_usb_if_add(d, node, if_devfs_path, 0)) != NULL) {
832912Sartem 			d = nd;
842912Sartem 			nd = NULL;
852912Sartem 			devfs_path = if_devfs_path;
862912Sartem 		}
872912Sartem 	}
882912Sartem 
892912Sartem 	/* driver specific */
902912Sartem 	driver_name = di_driver_name (node);
912912Sartem 	if ((driver_name != NULL) && (strcmp (driver_name, "scsa2usb") == 0)) {
922912Sartem 		nd = devinfo_usb_scsa2usb_add (d, node, devfs_path);
932912Sartem 	} else {
942912Sartem 		devinfo_add_enqueue (d, devfs_path, &devinfo_usb_handler);
952912Sartem 	}
962912Sartem 
972912Sartem out:
982912Sartem 	if (nd != NULL) {
992912Sartem 		return (nd);
1002912Sartem 	} else {
1012912Sartem 		return (d);
1022912Sartem 	}
1032912Sartem }
1042912Sartem 
1052912Sartem static HalDevice *
1062912Sartem devinfo_usb_if_add(HalDevice *parent, di_node_t node, gchar *devfs_path, int ifnum)
1072912Sartem {
1082912Sartem 	HalDevice *d = NULL;
1092912Sartem         char    udi[HAL_PATH_MAX];
1102912Sartem 
1112912Sartem 	devinfo_add_enqueue (parent, devfs_path, &devinfo_usb_handler);
1122912Sartem 
1132912Sartem 	d = hal_device_new ();
1142912Sartem 
1152912Sartem 	devinfo_set_default_properties (d, parent, node, devfs_path);
1162912Sartem         hal_device_property_set_string (d, "info.bus", "usb");
1172912Sartem 
1182912Sartem         hal_util_compute_udi (hald_get_gdl (), udi, sizeof (udi),
1192912Sartem 		"%s_if%d", parent->udi, ifnum);
1202912Sartem         hal_device_set_udi (d, udi);
1212912Sartem         hal_device_property_set_string (d, "info.udi", udi);
1222912Sartem         hal_device_property_set_string (d, "info.product", "USB Device Interface");
1232912Sartem 
1242912Sartem 	/* copy parent's usb_device.* properties */
1252912Sartem 	hal_device_merge_with_rewrite (d, parent, "usb.", "usb_device.");
1262912Sartem 
1272912Sartem 	return (d);
1282912Sartem }
1292912Sartem 
1302912Sartem static int
1312912Sartem walk_devlinks(di_devlink_t devlink, void *arg)
1322912Sartem {
1332912Sartem         char **path = (char **)arg;
1342912Sartem 
1352912Sartem         *path = strdup(di_devlink_path(devlink));
1362912Sartem 
1372912Sartem         return (DI_WALK_TERMINATE);
1382912Sartem }
1392912Sartem 
1402912Sartem static char *
1412912Sartem get_devlink(di_devlink_handle_t devlink_hdl, char *path)
1422912Sartem {
1432912Sartem 	char *devlink = NULL;
1442912Sartem 
1452912Sartem         (void) di_devlink_walk(devlink_hdl, NULL, path,
1462912Sartem             DI_PRIMARY_LINK, &devlink, walk_devlinks);
1472912Sartem 
1482912Sartem         return (devlink);
1492912Sartem }
1502912Sartem 
1512912Sartem static HalDevice *
1522912Sartem devinfo_usb_scsa2usb_add(HalDevice *usbd, di_node_t node, gchar *devfs_path)
1532912Sartem {
1542912Sartem 	HalDevice *d = NULL;
1552912Sartem 	di_devlink_handle_t devlink_hdl;
1562912Sartem         int     major;
1572912Sartem         di_minor_t minor;
1582912Sartem         dev_t   devt;
1592912Sartem         char    *minor_path = NULL;
1602912Sartem 	char	*devlink = NULL;
1612912Sartem         char    udi[HAL_PATH_MAX];
1622912Sartem 
1632912Sartem 	devinfo_add_enqueue (usbd, devfs_path, &devinfo_usb_handler);
1642912Sartem 
1652912Sartem         if ((devlink_hdl = di_devlink_init(NULL, 0)) == NULL) {
1662912Sartem                 printf("di_devlink_init() failed\n");
1672912Sartem                 return (NULL);
1682912Sartem         }
1692912Sartem 
1702912Sartem         major = di_driver_major(node);
1712912Sartem         minor = DI_MINOR_NIL;
1722912Sartem         while ((minor = di_minor_next(node, minor)) != DI_MINOR_NIL) {
1732912Sartem                 devt = di_minor_devt(minor);
1742912Sartem                 if (major != major(devt)) {
1752912Sartem                         continue;
1762912Sartem                 }
1772912Sartem                 if ((minor_path = di_devfs_minor_path(minor)) == NULL) {
1782912Sartem                         continue;
1792912Sartem                 }
1802912Sartem                 if (di_minor_type(minor) != DDM_MINOR) {
1812912Sartem                         continue;
1822912Sartem                 }
1832912Sartem 		if (strcmp (di_minor_nodetype(minor),
1842912Sartem 		    "ddi_ctl:devctl:scsi") == 0) {
1852912Sartem                 	devlink = get_devlink(devlink_hdl, minor_path);
1862912Sartem                 	if (devlink == NULL) {
1872912Sartem 				devlink = strdup("");
1882912Sartem 			}
1892912Sartem 			break;
1902912Sartem 		}
1912912Sartem 		di_devfs_path_free (minor_path);
1922912Sartem 		minor_path = NULL;
1932912Sartem         }
1942912Sartem 
1952912Sartem 	di_devlink_fini (&devlink_hdl);
1962912Sartem 
1972912Sartem 	if (devlink == NULL) {
1982912Sartem 		goto out;
1992912Sartem 	}
2002912Sartem 
2012912Sartem 	d = hal_device_new ();
2022912Sartem 
2032912Sartem 	devinfo_set_default_properties (d, usbd, node, minor_path);
2042912Sartem        	hal_device_property_set_string (d, "scsi_host.solaris.device", devlink);
2052912Sartem         hal_device_property_set_string (d, "info.category", "scsi_host");
2062912Sartem         hal_device_property_set_int (d, "scsi_host.host", 0);
2072912Sartem 
2082912Sartem         hal_util_compute_udi (hald_get_gdl (), udi, sizeof (udi),
2092912Sartem 		"%s/scsi_host%d", usbd->udi,
2102912Sartem 		hal_device_property_get_int (d, "scsi_host.host"));
2112912Sartem         hal_device_set_udi (d, udi);
2122912Sartem         hal_device_property_set_string (d, "info.udi", udi);
2132912Sartem         hal_device_property_set_string (d, "info.product", "SCSI Host Adapter");
2142912Sartem 
2152912Sartem 	devinfo_add_enqueue (d, minor_path, &devinfo_usb_handler);
2162912Sartem 
2172912Sartem out:
2182912Sartem 	if (devlink) {
2192912Sartem 		free(devlink);
2202912Sartem 	}
2212912Sartem 	if (minor_path) {
2222912Sartem 		di_devfs_path_free (minor_path);
2232912Sartem 	}
2242912Sartem 
2252912Sartem 	return (d);
2262912Sartem }
2272912Sartem 
228