86c86 < "USBA: USB Architecture 2.0 %I%" --- > "USBA: USB Architecture 2.0 1.66" 154a155,159 > boolean_t > usba_owns_ia(dev_info_t *dip) > { > int if_count = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, > "interface-count", 0); 155a161,163 > return ((if_count) ? B_TRUE : B_FALSE); > } > 201a210,217 > } else if (usba_owns_ia(rdip)) { > (void) snprintf(compat_name, > sizeof (compat_name), > "usbia%x,%x.config%x.%x", > usba_device->usb_dev_descr->idVendor, > usba_device->usb_dev_descr->idProduct, > usba_device->usb_cfg_value, > usb_get_if_number(rdip)); 233c249,251 < (usb_owns_device(rdip) ? "device" : "interface"), --- > (usb_owns_device(rdip) ? "device" : > ((usba_owns_ia(rdip) ? "interface-association" : > "interface"))), 1388a1407,1408 > { USB_CLASS_DIAG, DONTCARE, DONTCARE, "diagnostics" }, > { USB_CLASS_MISC, DONTCARE, DONTCARE, "miscellaneous" }, 1391a1412,1421 > /* interface-association node table */ > static node_name_entry_t ia_node_name_table[] = { > { USB_CLASS_AUDIO, DONTCARE, DONTCARE, "audio" }, > { USB_CLASS_VIDEO, DONTCARE, DONTCARE, "video" }, > { USB_CLASS_WIRELESS, USB_SUBCLS_WUSB_2, USB_PROTO_WUSB_DWA, > "device-wire-adaptor" }, > { USB_CLASS_WIRELESS, DONTCARE, DONTCARE, "wireless-controller" }, > { DONTCARE, DONTCARE, DONTCARE, "interface-association" } > }; > 1406c1436 < { USB_CLASS_COMM, DONTCARE, DONTCARE, "control" }, --- > { USB_CLASS_COMM, DONTCARE, DONTCARE, "communications" }, 1415a1446,1447 > { USB_CLASS_IMAGE, DONTCARE, DONTCARE, "image" }, > 1423a1456,1459 > { USB_CLASS_VIDEO, USB_SUBCLS_VIDEO_CONTROL, DONTCARE, "video-control" }, > { USB_CLASS_VIDEO, USB_SUBCLS_VIDEO_STREAM, DONTCARE, "video-stream" }, > { USB_CLASS_VIDEO, DONTCARE, DONTCARE, "video" }, > 1446c1482 < { USB_CLASS_COMM, DONTCARE, DONTCARE, "control" }, --- > { USB_CLASS_COMM, DONTCARE, DONTCARE, "communications" }, 1453a1490,1491 > { USB_CLASS_IMAGE, DONTCARE, DONTCARE, "image" }, > 1455a1494,1499 > { USB_CLASS_MASS_STORAGE, USB_SUBCLS_MS_RBC_T10, DONTCARE, "storage" }, > { USB_CLASS_MASS_STORAGE, USB_SUBCLS_MS_SFF8020I, DONTCARE, "cdrom" }, > { USB_CLASS_MASS_STORAGE, USB_SUBCLS_MS_QIC_157, DONTCARE, "tape" }, > { USB_CLASS_MASS_STORAGE, USB_SUBCLS_MS_UFI, DONTCARE, "floppy" }, > { USB_CLASS_MASS_STORAGE, USB_SUBCLS_MS_SFF8070I, DONTCARE, "storage" }, > { USB_CLASS_MASS_STORAGE, USB_SUBCLS_MS_SCSI, DONTCARE, "storage" }, 1461a1506,1509 > { USB_CLASS_VIDEO, USB_SUBCLS_VIDEO_CONTROL, DONTCARE, "video-control" }, > { USB_CLASS_VIDEO, USB_SUBCLS_VIDEO_STREAM, DONTCARE, "video-stream" }, > { USB_CLASS_VIDEO, DONTCARE, DONTCARE, "video" }, > 1466d1513 < { USB_CLASS_HUB, DONTCARE, DONTCARE, "hub" }, 1468c1515,1518 < { DONTCARE, DONTCARE, DONTCARE, "device" }, --- > { USB_CLASS_HUB, DONTCARE, DONTCARE, "hub" }, > { USB_CLASS_DIAG, DONTCARE, DONTCARE, "diagnostics" }, > { USB_CLASS_MISC, DONTCARE, DONTCARE, "miscellaneous" }, > { DONTCARE, DONTCARE, DONTCARE, "device" } 1472a1523,1524 > static size_t ia_node_name_table_size = > sizeof (ia_node_name_table)/sizeof (struct node_name_entry); 1487a1540,1544 > /* interface share node names with interface-association */ > case FLAG_INTERFACE_ASSOCIATION_NODE: > node_name_table = ia_node_name_table; > size = ia_node_name_table_size; > break; 1513a1571 > 2096a2155,2396 > * driver binding at interface association level. the first arg is the parent > * dip. if_count returns amount of interfaces which are associated within > * this interface-association that starts from first_if. > */ > /*ARGSUSED*/ > dev_info_t * > usba_ready_interface_association_node(dev_info_t *dip, > uint_t first_if, > uint_t *if_count) > { > dev_info_t *child_dip = NULL; > usba_device_t *child_ud = usba_get_usba_device(dip); > usb_dev_descr_t *usb_dev_descr; > size_t usb_cfg_length; > uchar_t *usb_cfg; > usb_ia_descr_t ia_descr; > int i, n, rval; > int reg[2]; > size_t size; > usb_port_status_t port_status; > char *force_bind = NULL; > > usb_cfg = usb_get_raw_cfg_data(dip, &usb_cfg_length); > > mutex_enter(&child_ud->usb_mutex); > > usb_dev_descr = child_ud->usb_dev_descr; > > /* > * for each interface association, determine all compatible names > */ > USB_DPRINTF_L3(DPRINT_MASK_USBA, usba_log_handle, > "usba_ready_ia_node: " > "port %d, interface = %d, port_status = %x", > child_ud->usb_port, first_if, child_ud->usb_port_status); > > /* Parse the interface descriptor */ > size = usb_parse_ia_descr( > usb_cfg, > usb_cfg_length, > first_if, /* interface index */ > &ia_descr, > USB_IA_DESCR_SIZE); > > *if_count = 1; > if (size != USB_IA_DESCR_SIZE) { > USB_DPRINTF_L2(DPRINT_MASK_USBA, usba_log_handle, > "parsing ia: size (%lu) != USB_IA_DESCR_SIZE (%d)", > size, USB_IA_DESCR_SIZE); > mutex_exit(&child_ud->usb_mutex); > > return (NULL); > } > > port_status = child_ud->usb_port_status; > > /* create reg property */ > reg[0] = first_if; > reg[1] = child_ud->usb_cfg_value; > > mutex_exit(&child_ud->usb_mutex); > > /* clone this dip */ > rval = usba_create_child_devi(dip, > "interface-association", > NULL, /* usba_hcdi ops */ > NULL, /* root hub dip */ > port_status, /* port status */ > child_ud, /* share this usba_device */ > &child_dip); > > if (rval != USB_SUCCESS) { > > goto fail; > } > > rval = ndi_prop_update_int_array( > DDI_DEV_T_NONE, child_dip, "reg", reg, 2); > > if (rval != DDI_PROP_SUCCESS) { > > goto fail; > } > > usba_set_node_name(child_dip, ia_descr.bFunctionClass, > ia_descr.bFunctionSubClass, ia_descr.bFunctionProtocol, > FLAG_INTERFACE_ASSOCIATION_NODE); > > /* check force binding */ > if (usba_ugen_force_binding == > USBA_UGEN_INTERFACE_ASSOCIATION_BINDING) { > force_bind = "ugen"; > } > > /* > * check whether there is another dip with this name and address > */ > ASSERT(usba_find_existing_node(child_dip) == NULL); > > mutex_enter(&usba_mutex); > n = 0; > > if (force_bind) { > (void) ndi_devi_set_nodename(child_dip, force_bind, 0); > (void) strncpy(usba_name[n++], force_bind, > USBA_MAX_COMPAT_NAME_LEN); > } > > /* 1) usbiaVID,PID.REV.configCN.FN */ > (void) sprintf(usba_name[n++], > "usbia%x,%x.%x.config%x.%x", > usb_dev_descr->idVendor, > usb_dev_descr->idProduct, > usb_dev_descr->bcdDevice, > child_ud->usb_cfg_value, > first_if); > > /* 2) usbiaVID,PID.configCN.FN */ > (void) sprintf(usba_name[n++], > "usbia%x,%x.config%x.%x", > usb_dev_descr->idVendor, > usb_dev_descr->idProduct, > child_ud->usb_cfg_value, > first_if); > > > if (ia_descr.bFunctionClass) { > /* 3) usbiaVID,classFC.FSC.FPROTO */ > (void) sprintf(usba_name[n++], > "usbia%x,class%x.%x.%x", > usb_dev_descr->idVendor, > ia_descr.bFunctionClass, > ia_descr.bFunctionSubClass, > ia_descr.bFunctionProtocol); > > /* 4) usbiaVID,classFC.FSC */ > (void) sprintf(usba_name[n++], > "usbia%x,class%x.%x", > usb_dev_descr->idVendor, > ia_descr.bFunctionClass, > ia_descr.bFunctionSubClass); > > /* 5) usbiaVID,classFC */ > (void) sprintf(usba_name[n++], > "usbia%x,class%x", > usb_dev_descr->idVendor, > ia_descr.bFunctionClass); > > /* 6) usbia,classFC.FSC.FPROTO */ > (void) sprintf(usba_name[n++], > "usbia,class%x.%x.%x", > ia_descr.bFunctionClass, > ia_descr.bFunctionSubClass, > ia_descr.bFunctionProtocol); > > /* 7) usbia,classFC.FSC */ > (void) sprintf(usba_name[n++], > "usbia,class%x.%x", > ia_descr.bFunctionClass, > ia_descr.bFunctionSubClass); > > /* 8) usbia,classFC */ > (void) sprintf(usba_name[n++], > "usbia,class%x", > ia_descr.bFunctionClass); > } > > if (usba_get_ugen_binding(child_dip) == > USBA_UGEN_INTERFACE_ASSOCIATION_BINDING) { > /* 9) ugen */ > (void) sprintf(usba_name[n++], "ugen"); > } else { > > (void) sprintf(usba_name[n++], "usb,ia"); > } > > for (i = 0; i < n; i += 2) { > USB_DPRINTF_L3(DPRINT_MASK_USBA, usba_log_handle, > "compatible name:\t%s\t%s", usba_compatible[i], > (((i+1) < n)? usba_compatible[i+1] : "")); > } > mutex_exit(&usba_mutex); > > /* create compatible property */ > if (n) { > rval = ndi_prop_update_string_array( > DDI_DEV_T_NONE, child_dip, > "compatible", (char **)usba_compatible, > n); > > if (rval != DDI_PROP_SUCCESS) { > > goto fail; > } > } > > /* update the address property */ > rval = ndi_prop_update_int(DDI_DEV_T_NONE, child_dip, > "assigned-address", child_ud->usb_addr); > if (rval != DDI_PROP_SUCCESS) { > USB_DPRINTF_L2(DPRINT_MASK_USBA, usba_log_handle, > "usba_ready_interface_node: address update failed"); > } > > /* create property with first interface number */ > rval = ndi_prop_update_int(DDI_DEV_T_NONE, child_dip, > "interface", ia_descr.bFirstInterface); > > if (rval != DDI_PROP_SUCCESS) { > > goto fail; > } > > /* create property with the count of interfaces in this ia */ > rval = ndi_prop_update_int(DDI_DEV_T_NONE, child_dip, > "interface-count", ia_descr.bInterfaceCount); > > if (rval != DDI_PROP_SUCCESS) { > > goto fail; > } > > USB_DPRINTF_L2(DPRINT_MASK_USBA, usba_log_handle, > "%s%d port %d: %s, dip = 0x%p", > ddi_node_name(ddi_get_parent(dip)), > ddi_get_instance(ddi_get_parent(dip)), > child_ud->usb_port, ddi_node_name(child_dip), child_dip); > > *if_count = ia_descr.bInterfaceCount; > usba_set_usba_device(child_dip, child_ud); > ASSERT(!mutex_owned(&(usba_get_usba_device(child_dip)->usb_mutex))); > > return (child_dip); > > fail: > (void) usba_destroy_child_devi(child_dip, NDI_DEVI_REMOVE); > > return (NULL); > } > > > /* 2187d2486 < #ifdef DEBUG 2192d2490 < #endif