12912Sartem /*************************************************************************** 22912Sartem * 32912Sartem * devinfo_usb.h : USB devices 42912Sartem * 5*3536Sjacobs * Copyright 2007 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 143121Sartem #ifdef HAVE_CONFIG_H 153121Sartem # include <config.h> 163121Sartem #endif 173121Sartem 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); 39*3536Sjacobs static HalDevice *devinfo_usb_printer_add(HalDevice *usbd, di_node_t node, gchar *devfs_path); 40*3536Sjacobs const gchar *devinfo_printer_prnio_get_prober (HalDevice *d, int *timeout); 412912Sartem 422912Sartem DevinfoDevHandler devinfo_usb_handler = { 432912Sartem devinfo_usb_add, 442912Sartem NULL, 452912Sartem NULL, 462912Sartem NULL, 472912Sartem NULL, 482912Sartem NULL 492912Sartem }; 502912Sartem 51*3536Sjacobs DevinfoDevHandler devinfo_usb_printer_handler = { 52*3536Sjacobs devinfo_usb_add, 53*3536Sjacobs NULL, 54*3536Sjacobs NULL, 55*3536Sjacobs NULL, 56*3536Sjacobs NULL, 57*3536Sjacobs devinfo_printer_prnio_get_prober 58*3536Sjacobs }; 59*3536Sjacobs 602912Sartem HalDevice * 612912Sartem devinfo_usb_add(HalDevice *parent, di_node_t node, char *devfs_path, char *device_type) 622912Sartem { 632912Sartem HalDevice *d, *nd = NULL; 642912Sartem char *s; 652912Sartem int *i, *vid; 662912Sartem char *driver_name, *binding_name; 672912Sartem char if_devfs_path[HAL_PATH_MAX]; 682912Sartem 692912Sartem /* 702912Sartem * we distinguish USB devices by presence of "usb-vendor-id" 712912Sartem * property. should USB devices have "device_type"? 722912Sartem */ 732912Sartem if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "usb-vendor-id", &vid) <= 0) { 742912Sartem return (NULL); 752912Sartem } 762912Sartem 772912Sartem d = hal_device_new (); 782912Sartem 792912Sartem devinfo_set_default_properties (d, parent, node, devfs_path); 802912Sartem hal_device_property_set_string (d, "info.bus", "usb_device"); 812912Sartem PROP_STR(d, node, s, "usb-product-name", "info.product"); 822912Sartem PROP_STR(d, node, s, "usb-product-name", "usb_device.product"); 832912Sartem PROP_STR(d, node, s, "usb-vendor-name", "usb_device.vendor"); 842912Sartem PROP_INT(d, node, i, "usb-vendor-id", "usb_device.vendor_id"); 852912Sartem PROP_INT(d, node, i, "usb-product-id", "usb_device.product_id"); 862912Sartem PROP_INT(d, node, i, "usb-revision-id", "usb_device.device_revision_bcd"); 872912Sartem PROP_INT(d, node, i, "usb-release-id", "usb_device.version_bcd"); 882912Sartem PROP_STR(d, node, s, "usb-serialno", "usb_device.serial"); 892912Sartem 902912Sartem /* class, subclass */ 912912Sartem /* hal_device_property_set_int (d, "usb_device.device_class", 8); */ 922912Sartem 932912Sartem /* binding name tells us if driver is bound to interface or device */ 942912Sartem if (((binding_name = di_binding_name(node)) != NULL) && 952912Sartem (strncmp(binding_name, "usbif,", sizeof ("usbif,") - 1) == 0)) { 962912Sartem snprintf(if_devfs_path, sizeof (if_devfs_path), "%s:if%d", devfs_path, 0); 972912Sartem if ((nd = devinfo_usb_if_add(d, node, if_devfs_path, 0)) != NULL) { 982912Sartem d = nd; 992912Sartem nd = NULL; 1002912Sartem devfs_path = if_devfs_path; 1012912Sartem } 1022912Sartem } 1032912Sartem 1042912Sartem /* driver specific */ 1052912Sartem driver_name = di_driver_name (node); 1062912Sartem if ((driver_name != NULL) && (strcmp (driver_name, "scsa2usb") == 0)) { 1072912Sartem nd = devinfo_usb_scsa2usb_add (d, node, devfs_path); 108*3536Sjacobs } else if ((driver_name != NULL) && 109*3536Sjacobs (strcmp (driver_name, "usbprn") == 0)) { 110*3536Sjacobs nd = devinfo_usb_printer_add (d, node, devfs_path); 1112912Sartem } else { 1122912Sartem devinfo_add_enqueue (d, devfs_path, &devinfo_usb_handler); 1132912Sartem } 1142912Sartem 1152912Sartem out: 1162912Sartem if (nd != NULL) { 1172912Sartem return (nd); 1182912Sartem } else { 1192912Sartem return (d); 1202912Sartem } 1212912Sartem } 1222912Sartem 1232912Sartem static HalDevice * 1242912Sartem devinfo_usb_if_add(HalDevice *parent, di_node_t node, gchar *devfs_path, int ifnum) 1252912Sartem { 1262912Sartem HalDevice *d = NULL; 1272912Sartem char udi[HAL_PATH_MAX]; 1282912Sartem 1292912Sartem devinfo_add_enqueue (parent, devfs_path, &devinfo_usb_handler); 1302912Sartem 1312912Sartem d = hal_device_new (); 1322912Sartem 1332912Sartem devinfo_set_default_properties (d, parent, node, devfs_path); 1342912Sartem hal_device_property_set_string (d, "info.bus", "usb"); 1352912Sartem hal_device_property_set_string (d, "info.product", "USB Device Interface"); 1362912Sartem 1372912Sartem /* copy parent's usb_device.* properties */ 1382912Sartem hal_device_merge_with_rewrite (d, parent, "usb.", "usb_device."); 1392912Sartem 1402912Sartem return (d); 1412912Sartem } 1422912Sartem 1432912Sartem 144*3536Sjacobs static void 145*3536Sjacobs get_dev_link_path(di_node_t node, char *nodetype, char *re, char **devlink, char **minor_path) 146*3536Sjacobs { 147*3536Sjacobs di_devlink_handle_t devlink_hdl; 148*3536Sjacobs int major; 149*3536Sjacobs di_minor_t minor; 150*3536Sjacobs dev_t devt; 1512912Sartem 152*3536Sjacobs *devlink = NULL; 153*3536Sjacobs *minor_path = NULL; 154*3536Sjacobs 155*3536Sjacobs if ((devlink_hdl = di_devlink_init(NULL, 0)) == NULL) { 156*3536Sjacobs printf("di_devlink_init() failed\n"); 157*3536Sjacobs return; 158*3536Sjacobs } 1592912Sartem 160*3536Sjacobs major = di_driver_major(node); 161*3536Sjacobs minor = DI_MINOR_NIL; 162*3536Sjacobs while ((minor = di_minor_next(node, minor)) != DI_MINOR_NIL) { 163*3536Sjacobs devt = di_minor_devt(minor); 164*3536Sjacobs if (major != major(devt)) { 165*3536Sjacobs continue; 166*3536Sjacobs } 167*3536Sjacobs 168*3536Sjacobs if (di_minor_type(minor) != DDM_MINOR) { 169*3536Sjacobs continue; 170*3536Sjacobs } 1712912Sartem 172*3536Sjacobs if ((*minor_path = di_devfs_minor_path(minor)) == NULL) { 173*3536Sjacobs continue; 174*3536Sjacobs } 1752912Sartem 176*3536Sjacobs if ((strcmp (di_minor_nodetype(minor), nodetype) == 0) && 177*3536Sjacobs ((*devlink = get_devlink(devlink_hdl, re, *minor_path)) != NULL)) { 178*3536Sjacobs break; 179*3536Sjacobs } 180*3536Sjacobs di_devfs_path_free (*minor_path); 181*3536Sjacobs minor_path = NULL; 182*3536Sjacobs } 183*3536Sjacobs di_devlink_fini (&devlink_hdl); 1842912Sartem } 1852912Sartem 1862912Sartem static HalDevice * 1872912Sartem devinfo_usb_scsa2usb_add(HalDevice *usbd, di_node_t node, gchar *devfs_path) 1882912Sartem { 1892912Sartem HalDevice *d = NULL; 1902912Sartem di_devlink_handle_t devlink_hdl; 1912912Sartem int major; 1922912Sartem di_minor_t minor; 1932912Sartem dev_t devt; 1942912Sartem char *minor_path = NULL; 1952912Sartem char *devlink = NULL; 1962912Sartem char udi[HAL_PATH_MAX]; 1972912Sartem 1982912Sartem devinfo_add_enqueue (usbd, devfs_path, &devinfo_usb_handler); 1992912Sartem 200*3536Sjacobs get_dev_link_path(node, "ddi_ctl:devctl:scsi", NULL, &devlink, &minor_path); 2012912Sartem 202*3536Sjacobs if ((devlink == NULL) || (minor_path == NULL)) { 2032912Sartem goto out; 2042912Sartem } 2052912Sartem 2062912Sartem d = hal_device_new (); 2072912Sartem 2082912Sartem devinfo_set_default_properties (d, usbd, node, minor_path); 2092912Sartem hal_device_property_set_string (d, "scsi_host.solaris.device", devlink); 2102912Sartem hal_device_property_set_string (d, "info.category", "scsi_host"); 2112912Sartem hal_device_property_set_int (d, "scsi_host.host", 0); 2122912Sartem 2132912Sartem hal_util_compute_udi (hald_get_gdl (), udi, sizeof (udi), 2143121Sartem "%s/scsi_host%d", hal_device_get_udi (usbd), 2152912Sartem hal_device_property_get_int (d, "scsi_host.host")); 2162912Sartem hal_device_set_udi (d, udi); 2172912Sartem hal_device_property_set_string (d, "info.udi", udi); 2182912Sartem hal_device_property_set_string (d, "info.product", "SCSI Host Adapter"); 2192912Sartem 2202912Sartem devinfo_add_enqueue (d, minor_path, &devinfo_usb_handler); 2212912Sartem 2222912Sartem out: 2232912Sartem if (devlink) { 2242912Sartem free(devlink); 2252912Sartem } 2262912Sartem if (minor_path) { 2272912Sartem di_devfs_path_free (minor_path); 2282912Sartem } 2292912Sartem 2302912Sartem return (d); 2312912Sartem } 2322912Sartem 233*3536Sjacobs static HalDevice * 234*3536Sjacobs devinfo_usb_printer_add(HalDevice *parent, di_node_t node, gchar *devfs_path) 235*3536Sjacobs { 236*3536Sjacobs HalDevice *d = NULL; 237*3536Sjacobs char udi[HAL_PATH_MAX]; 238*3536Sjacobs char *s; 239*3536Sjacobs char *devlink = NULL, *minor_path = NULL; 240*3536Sjacobs 241*3536Sjacobs devinfo_add_enqueue (parent, devfs_path, &devinfo_usb_handler); 242*3536Sjacobs 243*3536Sjacobs get_dev_link_path(node, "ddi_printer", "printers/.+", &devlink, &minor_path); 244*3536Sjacobs 245*3536Sjacobs if ((devlink == NULL) || (minor_path == NULL)) { 246*3536Sjacobs goto out; 247*3536Sjacobs } 248*3536Sjacobs 249*3536Sjacobs d = hal_device_new (); 250*3536Sjacobs 251*3536Sjacobs devinfo_set_default_properties (d, parent, node, minor_path); 252*3536Sjacobs hal_device_property_set_string (d, "info.category", "printer"); 253*3536Sjacobs hal_device_add_capability (d, "printer"); 254*3536Sjacobs 255*3536Sjacobs /* copy parent's usb_device.* properties */ 256*3536Sjacobs hal_device_merge_with_rewrite (d, parent, "usb.", "usb_device."); 257*3536Sjacobs 258*3536Sjacobs /* add printer properties */ 259*3536Sjacobs hal_device_property_set_string (d, "printer.device", devlink); 260*3536Sjacobs PROP_STR(d, node, s, "usb-vendor-name", "printer.vendor"); 261*3536Sjacobs PROP_STR(d, node, s, "usb-product-name", "printer.product"); 262*3536Sjacobs PROP_STR(d, node, s, "usb-serialno", "printer.serial"); 263*3536Sjacobs 264*3536Sjacobs devinfo_add_enqueue (d, minor_path, &devinfo_usb_printer_handler); 265*3536Sjacobs 266*3536Sjacobs out: 267*3536Sjacobs if (devlink) { 268*3536Sjacobs free(devlink); 269*3536Sjacobs } 270*3536Sjacobs if (minor_path) { 271*3536Sjacobs di_devfs_path_free (minor_path); 272*3536Sjacobs } 273*3536Sjacobs 274*3536Sjacobs return (d); 275*3536Sjacobs } 276*3536Sjacobs 277*3536Sjacobs const gchar * 278*3536Sjacobs devinfo_printer_prnio_get_prober (HalDevice *d, int *timeout) 279*3536Sjacobs { 280*3536Sjacobs *timeout = 5 * 1000; /* 5 second timeout */ 281*3536Sjacobs return ("hald-probe-printer"); 282*3536Sjacobs } 283