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