static int rtl8150_open(struct net_device *netdev) { rtl8150_t *dev; int res; dev = netdev->priv; if (dev == NULL) { return -ENODEV; } down(&dev->sem); set_registers(dev, IDR, 6, netdev->dev_addr); FILL_BULK_URB(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1), dev->rx_buff, RTL8150_MAX_MTU, read_bulk_callback, dev); if ((res = usb_submit_urb(dev->rx_urb))) warn("%s: rx_urb submit failed: %d", __FUNCTION__, res); FILL_INT_URB(dev->intr_urb, dev->udev, usb_rcvintpipe(dev->udev, 3), dev->intr_buff, sizeof(dev->intr_buff), intr_callback, dev, dev->intr_interval); if ((res = usb_submit_urb(dev->intr_urb))) warn("%s: intr_urb submit failed: %d", __FUNCTION__, res); netif_start_queue(netdev); enable_net_traffic(dev); up(&dev->sem); return res; }
/* Don't start the URB */ static void auerisdn_bintbo_setup(struct auerisdn *ip, unsigned int len) { ip->intbo_state = INTBOS_IDLE; FILL_INT_URB(ip->intbo_urbp, ip->usbdev, usb_sndintpipe(ip->usbdev, ip->intbo_endp), ip->intbo_bufp, len, auerisdn_bintbo_complete, ip, ip->outInterval); ip->intbo_urbp->transfer_flags |= USB_ASYNC_UNLINK; ip->intbo_urbp->status = 0; }
/* This function is called to activate the interrupt endpoint. This function returns 0 if successfull or an error code. NOTE: no mutex please! */ static int auerswald_int_open(struct auerswald *cp) { int ret; struct usb_endpoint_descriptor *ep; int irqsize; dbg("auerswald_int_open"); ep = usb_epnum_to_ep_desc(cp->usbdev, USB_DIR_IN | AU_IRQENDP); if (!ep) { ret = -EFAULT; goto intoend; } irqsize = ep->wMaxPacketSize; cp->irqsize = irqsize; /* allocate the urb and data buffer */ if (!cp->inturbp) { cp->inturbp = usb_alloc_urb(0); if (!cp->inturbp) { ret = -ENOMEM; goto intoend; } } if (!cp->intbufp) { cp->intbufp = (char *) kmalloc(irqsize, GFP_KERNEL); if (!cp->intbufp) { ret = -ENOMEM; goto intoend; } } /* setup urb */ FILL_INT_URB(cp->inturbp, cp->usbdev, usb_rcvintpipe(cp->usbdev, AU_IRQENDP), cp->intbufp, irqsize, auerswald_int_complete, cp, ep->bInterval); /* start the urb */ cp->inturbp->status = 0; /* needed! */ ret = usb_submit_urb(cp->inturbp); intoend: if (ret < 0) { /* activation of interrupt endpoint has failed. Now clean up. */ dbg("auerswald_int_open: activation of int endpoint failed"); /* deallocate memory */ auerswald_int_free(cp); } return ret; }
static int rtl8150_open(struct net_device *netdev) { rtl8150_t *dev; int res; dev = netdev->priv; if (dev == NULL) { return -ENODEV; } down(&dev->sem); set_registers(dev, IDR, 6, netdev->dev_addr); FILL_BULK_URB(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1), dev->rx_buff, RTL8150_MAX_MTU, read_bulk_callback, dev); if ((res = usb_submit_urb(dev->rx_urb))) warn("%s: rx_urb submit failed: %d", __FUNCTION__, res); FILL_INT_URB(dev->intr_urb, dev->udev, usb_rcvintpipe(dev->udev, 3), dev->intr_buff, sizeof(dev->intr_buff), intr_callback, dev, dev->intr_interval); if ((res = usb_submit_urb(dev->intr_urb))) warn("%s: intr_urb submit failed: %d", __FUNCTION__, res); netif_start_queue(netdev); enable_net_traffic(dev); up(&dev->sem); #ifdef CONFIG_RTL865XB_3G { if (0!=reCore_registerWANDevice(netdev)) printk("XXX Can't register wan device\n"); if(0!=devglue_regExtDevice(netdev->name, 8, CONFIG_RTL865XB_3G_PORT, &myLinkID2)) printk("XXX Can't register a link ID for device %s on extPort 0x%x!!!\n", netdev->name,CONFIG_RTL865XB_3G_PORT ); else printk("Device %s on vlan ID %d using Link ID %d. Loopback/Ext port is %d\n", netdev->name, 8, myLinkID2, CONFIG_RTL865XB_3G_PORT); } #endif return res; }
static int usb_hub_configure(struct usb_hub *hub, struct usb_endpoint_descriptor *endpoint) { struct usb_device *dev = hub->dev; struct usb_hub_status hubstatus; char portstr[USB_MAXCHILDREN + 1]; unsigned int pipe; int i, maxp, ret; DBG_HOST_HUB("### >>> Enter hub.c file --> usb_hub_configure function \n"); hub->descriptor = kmalloc(sizeof(*hub->descriptor), GFP_KERNEL); if (!hub->descriptor) { err("Unable to kmalloc %Zd bytes for hub descriptor", sizeof(*hub->descriptor)); return -1; } /* Request the entire hub descriptor. */ ret = usb_get_hub_descriptor(dev, hub->descriptor, sizeof(*hub->descriptor)); /* <hub->descriptor> is large enough for a hub with 127 ports; * the hub can/will return fewer bytes here. */ if (ret < 0) { err("Unable to get hub descriptor (err = %d)", ret); kfree(hub->descriptor); return -1; } dev->maxchild = hub->descriptor->bNbrPorts; info("%d port%s detected", hub->descriptor->bNbrPorts, (hub->descriptor->bNbrPorts == 1) ? "" : "s"); le16_to_cpus(&hub->descriptor->wHubCharacteristics); if (hub->descriptor->wHubCharacteristics & HUB_CHAR_COMPOUND) dbg("part of a compound device"); else dbg("standalone hub"); switch (hub->descriptor->wHubCharacteristics & HUB_CHAR_LPSM) { case 0x00: dbg("ganged power switching"); break; case 0x01: dbg("individual port power switching"); break; case 0x02: case 0x03: dbg("unknown reserved power switching mode"); break; } switch (hub->descriptor->wHubCharacteristics & HUB_CHAR_OCPM) { case 0x00: dbg("global over-current protection"); break; case 0x08: dbg("individual port over-current protection"); break; case 0x10: case 0x18: dbg("no over-current protection"); break; } switch (dev->descriptor.bDeviceProtocol) { case 0: break; case 1: dbg("Single TT"); hub->tt.hub = dev; break; case 2: dbg("TT per port"); hub->tt.hub = dev; hub->tt.multi = 1; break; default: dbg("Unrecognized hub protocol %d", dev->descriptor.bDeviceProtocol); break; } switch (hub->descriptor->wHubCharacteristics & HUB_CHAR_TTTT) { case 0x00: if (dev->descriptor.bDeviceProtocol != 0) dbg("TT requires at most 8 FS bit times"); break; case 0x20: dbg("TT requires at most 16 FS bit times"); break; case 0x40: dbg("TT requires at most 24 FS bit times"); break; case 0x60: dbg("TT requires at most 32 FS bit times"); break; } dbg("Port indicators are %s supported", (hub->descriptor->wHubCharacteristics & HUB_CHAR_PORTIND) ? "" : "not"); dbg("power on to power good time: %dms", hub->descriptor->bPwrOn2PwrGood * 2); dbg("hub controller current requirement: %dmA", hub->descriptor->bHubContrCurrent); for (i = 0; i < dev->maxchild; i++) portstr[i] = hub->descriptor->DeviceRemovable[((i + 1) / 8)] & (1 << ((i + 1) % 8)) ? 'F' : 'R'; portstr[dev->maxchild] = 0; dbg("port removable status: %s", portstr); ret = usb_get_hub_status(dev, &hubstatus); if (ret < 0) { err("Unable to get hub status (err = %d)", ret); kfree(hub->descriptor); return -1; } le16_to_cpus(&hubstatus.wHubStatus); dbg("local power source is %s", (hubstatus.wHubStatus & HUB_STATUS_LOCAL_POWER) ? "lost (inactive)" : "good"); dbg("%sover-current condition exists", (hubstatus.wHubStatus & HUB_STATUS_OVERCURRENT) ? "" : "no "); /* Start the interrupt endpoint */ pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); if (maxp > sizeof(hub->buffer)) maxp = sizeof(hub->buffer); hub->urb = usb_alloc_urb(0); if (!hub->urb) { err("couldn't allocate interrupt urb"); kfree(hub->descriptor); return -1; } FILL_INT_URB(hub->urb, dev, pipe, hub->buffer, maxp, hub_irq, hub, endpoint->bInterval); ret = usb_submit_urb(hub->urb); if (ret) { err("usb_submit_urb failed (%d)", ret); kfree(hub->descriptor); return -1; } /* Wake up khubd */ wake_up(&khubd_wait); usb_hub_power_on(hub); return 0; }
/* * Callback to search the Mustek MDC800 on the USB Bus */ static void* mdc800_usb_probe (struct usb_device *dev ,unsigned int ifnum, const struct usb_device_id *id) { int i,j; struct usb_interface_descriptor *intf_desc; int irq_interval=0; dbg ("(mdc800_usb_probe) called."); if (mdc800->dev != 0) { warn ("only one Mustek MDC800 is supported."); return 0; } if (dev->descriptor.bNumConfigurations != 1) { err ("probe fails -> wrong Number of Configuration"); return 0; } intf_desc=&dev->actconfig->interface[ifnum].altsetting[0]; if ( ( intf_desc->bInterfaceClass != 0xff ) || ( intf_desc->bInterfaceSubClass != 0 ) || ( intf_desc->bInterfaceProtocol != 0 ) || ( intf_desc->bNumEndpoints != 4) ) { err ("probe fails -> wrong Interface"); return 0; } /* Check the Endpoints */ for (i=0; i<4; i++) { mdc800->endpoint[i]=-1; for (j=0; j<4; j++) { if (mdc800_endpoint_equals (&intf_desc->endpoint [j],&mdc800_ed [i])) { mdc800->endpoint[i]=intf_desc->endpoint [j].bEndpointAddress ; if (i==1) { irq_interval=intf_desc->endpoint [j].bInterval; } continue; } } if (mdc800->endpoint[i] == -1) { err ("probe fails -> Wrong Endpoints."); return 0; } } usb_driver_claim_interface (&mdc800_usb_driver, &dev->actconfig->interface[ifnum], mdc800); if (usb_set_interface (dev, ifnum, 0) < 0) { err ("MDC800 Configuration fails."); return 0; } info ("Found Mustek MDC800 on USB."); down (&mdc800->io_lock); mdc800->dev=dev; mdc800->open=0; /* Setup URB Structs */ FILL_INT_URB ( mdc800->irq_urb, mdc800->dev, usb_rcvintpipe (mdc800->dev,mdc800->endpoint [1]), mdc800->irq_urb_buffer, 8, mdc800_usb_irq, mdc800, irq_interval ); FILL_BULK_URB ( mdc800->write_urb, mdc800->dev, usb_sndbulkpipe (mdc800->dev, mdc800->endpoint[0]), mdc800->write_urb_buffer, 8, mdc800_usb_write_notify, mdc800 ); FILL_BULK_URB ( mdc800->download_urb, mdc800->dev, usb_rcvbulkpipe (mdc800->dev, mdc800->endpoint [3]), mdc800->download_urb_buffer, 64, mdc800_usb_download_notify, mdc800 ); mdc800->state=READY; up (&mdc800->io_lock); return mdc800; }
static void * usb_hpna_probe( struct usb_device *dev, unsigned int ifnum ) { // struct net_device *net_dev; struct device *net_dev; usb_hpna_t *hpna = &usb_dev_hpna; #ifdef PEGASUS_PRINT_PRODUCT_NAME int dev_index; #endif spinlock_t xxx = { }; #ifdef PEGASUS_PRINT_PRODUCT_NAME /* XXX */ if ( (dev_index = match_product(dev->descriptor.idVendor, dev->descriptor.idProduct)) == -1 ) { return NULL; } printk("USB Ethernet(Pegasus) %s found\n", product_list[dev_index].name); #else if ( dev->descriptor.idVendor != ADMTEK_VENDOR_ID || dev->descriptor.idProduct != ADMTEK_HPNA_PEGASUS ) { return NULL; } printk("USB HPNA Pegasus found\n"); #endif if ( usb_set_configuration(dev, dev->config[0].bConfigurationValue)) { err("usb_set_configuration() failed"); return NULL; } hpna->usb_dev = dev; hpna->rx_pipe = usb_rcvbulkpipe(hpna->usb_dev, 1); hpna->tx_pipe = usb_sndbulkpipe(hpna->usb_dev, 2); hpna->intr_pipe = usb_rcvintpipe(hpna->usb_dev, 0); if ( reset_mac(dev) ) { err("can't reset MAC"); } hpna->present = 1; if(!(hpna->rx_buff=kmalloc(MAX_MTU, GFP_KERNEL))) { err("not enough mem for out buff"); return NULL; } if(!(hpna->tx_buff=kmalloc(MAX_MTU, GFP_KERNEL))) { kfree_s(hpna->rx_buff, MAX_MTU); err("not enough mem for out buff"); return NULL; } net_dev = init_etherdev( 0, 0 ); hpna->net_dev = net_dev; net_dev->priv = hpna; net_dev->open = hpna_open; net_dev->stop = hpna_close; // net_dev->watchdog_timeo = TX_TIMEOUT; // net_dev->tx_timeout = tx_timeout; net_dev->do_ioctl = hpna_ioctl; net_dev->hard_start_xmit = hpna_start_xmit; net_dev->set_multicast_list = set_rx_mode; net_dev->get_stats = hpna_netdev_stats; net_dev->mtu = HPNA_MTU; #if 1 { /* * to support dhcp client daemon(dhcpcd), it needs to get HW address * in probe routine. */ struct usb_device *usb_dev = hpna->usb_dev; __u8 node_id[6]; if ( get_node_id(usb_dev, node_id) ) { printk("USB Pegasus can't get HW address in probe routine.\n"); printk("But Pegasus will re-try in open routine.\n"); goto next; } hpna_set_registers(usb_dev, 0x10, 6, node_id); memcpy(net_dev->dev_addr, node_id, 6); } next: #endif hpna->hpna_lock = xxx; //SPIN_LOCK_UNLOCKED; FILL_BULK_URB( &hpna->rx_urb, hpna->usb_dev, hpna->rx_pipe, hpna->rx_buff, MAX_MTU, hpna_read_irq, net_dev ); FILL_BULK_URB( &hpna->tx_urb, hpna->usb_dev, hpna->tx_pipe, hpna->tx_buff, MAX_MTU, hpna_write_irq, net_dev ); FILL_INT_URB( &hpna->intr_urb, hpna->usb_dev, hpna->intr_pipe, hpna->intr_buff, 8, hpna_irq, net_dev, 250 ); /* list_add( &hpna->list, &hpna_list );*/ return net_dev; }
int __devinit st5481_setup_usb(struct st5481_adapter *adapter) { struct usb_device *dev = adapter->usb_dev; struct st5481_ctrl *ctrl = &adapter->ctrl; struct st5481_intr *intr = &adapter->intr; struct usb_interface_descriptor *altsetting; struct usb_endpoint_descriptor *endpoint; int status; urb_t *urb; u_char *buf; DBG(1,""); if ((status = usb_set_configuration (dev,dev->config[0].bConfigurationValue)) < 0) { WARN("set_configuration failed,status=%d",status); return status; } altsetting = &(dev->config->interface[0].altsetting[3]); // Check if the config is sane if ( altsetting->bNumEndpoints != 7 ) { WARN("expecting 7 got %d endpoints!", altsetting->bNumEndpoints); return -EINVAL; } // The descriptor is wrong for some early samples of the ST5481 chip altsetting->endpoint[3].wMaxPacketSize = 32; altsetting->endpoint[4].wMaxPacketSize = 32; // Use alternative setting 3 on interface 0 to have 2B+D if ((status = usb_set_interface (dev, 0, 3)) < 0) { WARN("usb_set_interface failed,status=%d",status); return status; } // Allocate URB for control endpoint urb = usb_alloc_urb(0); if (!urb) { return -ENOMEM; } ctrl->urb = urb; // Fill the control URB FILL_CONTROL_URB (urb, dev, usb_sndctrlpipe(dev, 0), NULL, NULL, 0, usb_ctrl_complete, adapter); fifo_init(&ctrl->msg_fifo.f, ARRAY_SIZE(ctrl->msg_fifo.data)); // Allocate URBs and buffers for interrupt endpoint urb = usb_alloc_urb(0); if (!urb) { return -ENOMEM; } intr->urb = urb; buf = kmalloc(INT_PKT_SIZE, GFP_KERNEL); if (!buf) { return -ENOMEM; } endpoint = &altsetting->endpoint[EP_INT-1]; // Fill the interrupt URB FILL_INT_URB(urb, dev, usb_rcvintpipe(dev, endpoint->bEndpointAddress), buf, INT_PKT_SIZE, usb_int_complete, adapter, endpoint->bInterval); return 0; }
/* Connect to the HISAX interface. Returns 0 if successfull */ int auerisdn_probe(struct auerswald *cp) { struct hisax_b_if *b_if[AUISDN_BCHANNELS]; struct usb_endpoint_descriptor *ep; struct auerhisax *ahp; DECLARE_WAIT_QUEUE_HEAD(wqh); unsigned int u; unsigned char *ucp; unsigned int first_time; int ret; /* First allocate resources, then register hisax interface */ /* Allocate RX buffers */ for (u = 0; u < AUISDN_BCHANNELS; u++) { if (!cp->isdn.bc[u].rxbuf) { cp->isdn.bc[u].rxbuf = (char *) kmalloc(AUISDN_RXSIZE, GFP_KERNEL); if (!cp->isdn.bc[u].rxbuf) { err("can't allocate buffer for B channel RX data"); return -1; } } } /* Read out B-Channel output fifo size */ ucp = kmalloc(32, GFP_KERNEL); if (!ucp) { err("Out of memory"); return -3; } ret = usb_control_msg(cp->usbdev, /* pointer to device */ usb_rcvctrlpipe(cp->usbdev, 0), /* pipe to control endpoint */ AUV_GETINFO, /* USB message request value */ AUT_RREQ, /* USB message request type value */ 0, /* USB message value */ AUDI_OUTFSIZE, /* USB message index value */ ucp, /* pointer to the receive buffer */ 32, /* length of the buffer */ HZ * 2); /* time to wait for the message to complete before timing out */ if (ret < 4) { kfree(ucp); err("can't read TX Fifo sizes for B1,B2"); return -4; } for (u = 0; u < AUISDN_BCHANNELS; u++) { ret = le16_to_cpup(ucp + u * 2); cp->isdn.bc[u].ofsize = ret; cp->isdn.bc[u].txfree = ret; } kfree(ucp); for (u = 0; u < AUISDN_BCHANNELS; u++) { dbg("B%d buffer size is %d", u, cp->isdn.bc[u].ofsize); } /* get the B channel output INT size */ cp->isdn.intbo_endp = AU_IRQENDPBO; ep = usb_epnum_to_ep_desc(cp->usbdev, USB_DIR_OUT | AU_IRQENDPBO); if (!ep) { /* Some devices have another endpoint number here ... */ cp->isdn.intbo_endp = AU_IRQENDPBO_2; ep = usb_epnum_to_ep_desc(cp->usbdev, USB_DIR_OUT | AU_IRQENDPBO_2); if (!ep) { err("can't get B channel OUT endpoint"); return -5; } } cp->isdn.outsize = ep->wMaxPacketSize; cp->isdn.outInterval = ep->bInterval; cp->isdn.usbdev = cp->usbdev; /* allocate the urb and data buffer */ if (!cp->isdn.intbo_urbp) { cp->isdn.intbo_urbp = usb_alloc_urb(0); if (!cp->isdn.intbo_urbp) { err("can't allocate urb for B channel output endpoint"); return -6; } } if (!cp->isdn.intbo_bufp) { cp->isdn.intbo_bufp = (char *) kmalloc(cp->isdn.outsize, GFP_KERNEL); if (!cp->isdn.intbo_bufp) { err("can't allocate buffer for B channel output endpoint"); return -7; } } /* get the B channel input INT size */ ep = usb_epnum_to_ep_desc(cp->usbdev, USB_DIR_IN | AU_IRQENDPBI); if (!ep) { err("can't get B channel IN endpoint"); return -8; } cp->isdn.insize = ep->wMaxPacketSize; /* allocate the urb and data buffer */ if (!cp->isdn.intbi_urbp) { cp->isdn.intbi_urbp = usb_alloc_urb(0); if (!cp->isdn.intbi_urbp) { err("can't allocate urb for B channel input endpoint"); return -9; } } if (!cp->isdn.intbi_bufp) { cp->isdn.intbi_bufp = (char *) kmalloc(cp->isdn.insize, GFP_KERNEL); if (!cp->isdn.intbi_bufp) { err("can't allocate buffer for B channel input endpoint"); return -10; } } /* setup urb */ FILL_INT_URB(cp->isdn.intbi_urbp, cp->usbdev, usb_rcvintpipe(cp->usbdev, AU_IRQENDPBI), cp->isdn.intbi_bufp, cp->isdn.insize, auerisdn_intbi_complete, cp, ep->bInterval); /* start the urb */ cp->isdn.intbi_urbp->status = 0; /* needed! */ ret = usb_submit_urb(cp->isdn.intbi_urbp); if (ret < 0) { err("activation of B channel input int failed %d", ret); usb_free_urb(cp->isdn.intbi_urbp); cp->isdn.intbi_urbp = NULL; return -11; } /* request the D-channel service now */ dbg("Requesting D channel now"); cp->isdn.dchannelservice.id = AUH_DCHANNEL; if (auerswald_addservice(cp, &cp->isdn.dchannelservice)) { err("can not open D-channel"); cp->isdn.dchannelservice.id = AUH_UNASSIGNED; return -2; } /* Find a free hisax interface */ for (u = 0; u < AUER_MAX_DEVICES; u++) { ahp = &auerhisax_table[u]; if (!ahp->cp) { first_time = (u == 0); goto ahp_found; } } /* no free interface found */ return -12; /* we found a free hisax interface */ ahp_found: /* Wait until ipppd timeout expired. The reason behind this ugly construct: If we connect to a hisax device without waiting for ipppd we are not able to make a new IP connection. */ if (ahp->last_close) { unsigned long timeout = jiffies - ahp->last_close; if (timeout < AUISDN_IPTIMEOUT) { info("waiting for ipppd to timeout"); sleep_on_timeout(&wqh, AUISDN_IPTIMEOUT - timeout); } } cp->isdn.ahp = ahp; u = ahp->hisax_registered; ahp->hisax_registered = 1; ahp->cp = cp; /* now do the registration */ if (!u) { for (u = 0; u < AUISDN_BCHANNELS; u++) { b_if[u] = &ahp->hisax_b_if[u]; } if (hisax_register (&ahp->hisax_d_if, b_if, "auerswald_usb", ISDN_PTYPE_EURO)) { err("hisax registration failed"); ahp->cp = NULL; cp->isdn.ahp = NULL; ahp->hisax_registered = 0; return -13; } dbg("hisax interface registered"); } /* send a D channel L1 activation indication to hisax */ auerisdn_d_l1l2(&cp->isdn, PH_ACTIVATE | INDICATION, NULL); cp->isdn.dc_activated = 1; /* do another D channel activation for problematic devices */ cp->isdn.dcopen_timer.expires = jiffies + HZ; dbg("add timer"); add_timer(&cp->isdn.dcopen_timer); return 0; }
static void * hci_usb_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id) { struct usb_endpoint_descriptor *bulk_out_ep, *intr_in_ep, *bulk_in_ep; struct usb_interface_descriptor *uif; struct usb_endpoint_descriptor *ep; struct hci_usb *husb; struct hci_dev *hdev; int i, size, pipe; __u8 * buf; DBG("udev %p ifnum %d", udev, ifnum); /* Check device signature */ if ((udev->descriptor.bDeviceClass != HCI_DEV_CLASS) || (udev->descriptor.bDeviceSubClass != HCI_DEV_SUBCLASS)|| (udev->descriptor.bDeviceProtocol != HCI_DEV_PROTOCOL) ) return NULL; MOD_INC_USE_COUNT; uif = &udev->actconfig->interface[ifnum].altsetting[0]; if (uif->bNumEndpoints != 3) { DBG("Wrong number of endpoints %d", uif->bNumEndpoints); MOD_DEC_USE_COUNT; return NULL; } bulk_out_ep = intr_in_ep = bulk_in_ep = NULL; /* Find endpoints that we need */ for ( i = 0; i < uif->bNumEndpoints; ++i) { ep = &uif->endpoint[i]; switch (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { case USB_ENDPOINT_XFER_BULK: if (ep->bEndpointAddress & USB_DIR_IN) bulk_in_ep = ep; else bulk_out_ep = ep; break; case USB_ENDPOINT_XFER_INT: intr_in_ep = ep; break; }; } if (!bulk_in_ep || !bulk_out_ep || !intr_in_ep) { DBG("Endpoints not found: %p %p %p", bulk_in_ep, bulk_out_ep, intr_in_ep); MOD_DEC_USE_COUNT; return NULL; } if (!(husb = kmalloc(sizeof(struct hci_usb), GFP_KERNEL))) { ERR("Can't allocate: control structure"); MOD_DEC_USE_COUNT; return NULL; } memset(husb, 0, sizeof(struct hci_usb)); husb->udev = udev; husb->bulk_out_ep_addr = bulk_out_ep->bEndpointAddress; if (!(husb->ctrl_urb = usb_alloc_urb(0))) { ERR("Can't allocate: control URB"); goto probe_error; } if (!(husb->write_urb = usb_alloc_urb(0))) { ERR("Can't allocate: write URB"); goto probe_error; } if (!(husb->read_urb = usb_alloc_urb(0))) { ERR("Can't allocate: read URB"); goto probe_error; } ep = bulk_in_ep; pipe = usb_rcvbulkpipe(udev, ep->bEndpointAddress); size = HCI_MAX_FRAME_SIZE; if (!(buf = kmalloc(size, GFP_KERNEL))) { ERR("Can't allocate: read buffer"); goto probe_error; } FILL_BULK_URB(husb->read_urb, udev, pipe, buf, size, hci_usb_bulk_read, husb); husb->read_urb->transfer_flags |= USB_QUEUE_BULK; ep = intr_in_ep; pipe = usb_rcvintpipe(udev, ep->bEndpointAddress); size = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); if (!(husb->intr_urb = usb_alloc_urb(0))) { ERR("Can't allocate: interrupt URB"); goto probe_error; } if (!(buf = kmalloc(size, GFP_KERNEL))) { ERR("Can't allocate: interrupt buffer"); goto probe_error; } FILL_INT_URB(husb->intr_urb, udev, pipe, buf, size, hci_usb_intr, husb, ep->bInterval); skb_queue_head_init(&husb->tx_ctrl_q); skb_queue_head_init(&husb->tx_write_q); /* Initialize and register HCI device */ hdev = &husb->hdev; hdev->type = HCI_USB; hdev->driver_data = husb; hdev->open = hci_usb_open; hdev->close = hci_usb_close; hdev->flush = hci_usb_flush; hdev->send = hci_usb_send_frame; if (hci_register_dev(hdev) < 0) { ERR("Can't register HCI device %s", hdev->name); goto probe_error; } return husb; probe_error: hci_usb_free_bufs(husb); kfree(husb); MOD_DEC_USE_COUNT; return NULL; }
static int usb_hub_configure(USB_HUB_T *hub, EP_INFO_T *ep_info) { USB_DEV_T *dev = hub->dev; USB_HUB_STATUS_T hubstatus; uint32_t pipe; int maxp, ret; USB_info("[HUB] Enter usb_hub_configure()... hub:%d\n", hub->dev->devnum); /* Request the entire hub descriptor. */ ret = usb_get_hub_descriptor(dev, &hub->descriptor, sizeof(USB_HUB_DESC_T)); /* <hub->descriptor> is large enough for a hub with 127 ports; * the hub can/will return fewer bytes here. */ if(ret < 0) { USB_error("Erro - Unable to get hub descriptor (err = %d)\n", ret); return ret; } dev->maxchild = hub->descriptor.bNbrPorts; #ifdef USB_VERBOSE_DEBUG USB_info("%d port%s detected\n", hub->descriptor.bNbrPorts, (hub->descriptor.bNbrPorts == 1) ? "" : "s"); /* D2: Identifying a Compound Device */ if(hub->descriptor.wHubCharacteristics & HUB_CHAR_COMPOUND) { USB_info("part of a compound device\n"); } else { USB_info("standalone hub\n"); } /* D1..D0: Logical Power Switching Mode */ switch(hub->descriptor.wHubCharacteristics & HUB_CHAR_LPSM) { case 0x00: USB_info("ganged power switching\n"); break; case 0x01: USB_info("individual port power switching\n"); break; case 0x02: case 0x03: USB_info("unknown reserved power switching mode\n"); break; } /* D4..D3: Over-current Protection Mode */ switch(hub->descriptor.wHubCharacteristics & HUB_CHAR_OCPM) { case 0x00: USB_info("global over-current protection\n"); break; case 0x08: USB_info("individual port over-current protection\n"); break; case 0x10: case 0x18: USB_info("no over-current protection\n"); break; } switch(dev->descriptor.bDeviceProtocol) { case 0: break; case 1: USB_debug("Single TT, "); break; case 2: USB_debug("TT per port, "); break; default: USB_debug("Unrecognized hub protocol %d", dev->descriptor.bDeviceProtocol); break; } USB_info("power on to power good time: %dms\n", hub->descriptor.bPwrOn2PwrGood * 2); USB_info("hub controller current requirement: %dmA\n", hub->descriptor.bHubContrCurrent); #endif ret = usb_get_hub_status(dev, &hubstatus); if(ret < 0) { USB_error("Unable to get hub %d status (err = %d)\n", hub->dev->devnum, ret); return ret; } hubstatus.wHubStatus = USB_SWAP16(hubstatus.wHubStatus); #ifdef USB_VERBOSE_DEBUG /* Hub status bit 0, Local Power Source */ if(hubstatus.wHubStatus & HUB_STATUS_LOCAL_POWER) { USB_info("local power source is lost (inactive)\n"); } else { USB_info("local power source is good\n"); } /* Hub status bit 1, Over-current Indicator */ if(hubstatus.wHubStatus & HUB_STATUS_OVERCURRENT) { USB_info("!! over-current\n"); } else { USB_info("No over-current.\n"); } #endif /* Start the interrupt endpoint */ pipe = usb_rcvintpipe(dev, ep_info->bEndpointAddress); maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); if(maxp > sizeof(hub->buffer)) maxp = sizeof(hub->buffer); hub->urb = USBH_AllocUrb(); if(!hub->urb) { USB_error("Error - couldn't allocate interrupt urb"); return USB_ERR_NOMEM; } #if 1 /* YCHuang 2012.06.01 */ if(ep_info->bInterval < 16) ep_info->bInterval = 16; #endif FILL_INT_URB(hub->urb, dev, pipe, hub->buffer, maxp, hub_irq, hub, ep_info->bInterval); ret = USBH_SubmitUrb(hub->urb); if(ret) { USB_error("Error - USBH_SubmitUrb failed (%d)", ret); USBH_FreeUrb(hub->urb); return ret; } if(g_ohci_bus.root_hub != hub->dev) usb_hub_power_on(hub); return 0; }
static void * probe_scanner(struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id) { struct scn_usb_data *scn; struct usb_interface_descriptor *interface; struct usb_endpoint_descriptor *endpoint; int ep_cnt; int ix; kdev_t scn_minor; char valid_device = 0; char have_bulk_in, have_bulk_out, have_intr; char name[10]; if (vendor != -1 && product != -1) { info("probe_scanner: User specified USB scanner -- Vendor:Product - %x:%x", vendor, product); } dbg("probe_scanner: USB dev address:%p", dev); dbg("probe_scanner: ifnum:%u", ifnum); /* * 1. Check Vendor/Product * 2. Determine/Assign Bulk Endpoints * 3. Determine/Assign Intr Endpoint */ /* * There doesn't seem to be an imaging class defined in the USB * Spec. (yet). If there is, HP isn't following it and it doesn't * look like anybody else is either. Therefore, we have to test the * Vendor and Product ID's to see what we have. Also, other scanners * may be able to use this driver by specifying both vendor and * product ID's as options to the scanner module in conf.modules. * * NOTE: Just because a product is supported here does not mean that * applications exist that support the product. It's in the hopes * that this will allow developers a means to produce applications * that will support USB products. * * Until we detect a device which is pleasing, we silently punt. */ for (ix = 0; ix < sizeof (scanner_device_ids) / sizeof (struct usb_device_id); ix++) { if ((dev->descriptor.idVendor == scanner_device_ids [ix].idVendor) && (dev->descriptor.idProduct == scanner_device_ids [ix].idProduct)) { valid_device = 1; break; } } if (dev->descriptor.idVendor == vendor && /* User specified */ dev->descriptor.idProduct == product) { /* User specified */ valid_device = 1; } if (!valid_device) return NULL; /* We didn't find anything pleasing */ /* * After this point we can be a little noisy about what we are trying to * configure. */ if (dev->descriptor.bNumConfigurations != 1) { info("probe_scanner: Only one device configuration is supported."); return NULL; } if (dev->config[0].bNumInterfaces != 1) { info("probe_scanner: Only one device interface is supported."); return NULL; } interface = dev->config[0].interface[ifnum].altsetting; endpoint = interface[ifnum].endpoint; /* * Start checking for two bulk endpoints OR two bulk endpoints *and* one * interrupt endpoint. If we have an interrupt endpoint go ahead and * setup the handler. FIXME: This is a future enhancement... */ dbg("probe_scanner: Number of Endpoints:%d", (int) interface->bNumEndpoints); if ((interface->bNumEndpoints != 2) && (interface->bNumEndpoints != 3)) { info("probe_scanner: Only two or three endpoints supported."); return NULL; } ep_cnt = have_bulk_in = have_bulk_out = have_intr = 0; while (ep_cnt < interface->bNumEndpoints) { if (!have_bulk_in && IS_EP_BULK_IN(endpoint[ep_cnt])) { ep_cnt++; have_bulk_in = ep_cnt; dbg("probe_scanner: bulk_in_ep:%d", have_bulk_in); continue; } if (!have_bulk_out && IS_EP_BULK_OUT(endpoint[ep_cnt])) { ep_cnt++; have_bulk_out = ep_cnt; dbg("probe_scanner: bulk_out_ep:%d", have_bulk_out); continue; } if (!have_intr && IS_EP_INTR(endpoint[ep_cnt])) { ep_cnt++; have_intr = ep_cnt; dbg("probe_scanner: intr_ep:%d", have_intr); continue; } info("probe_scanner: Undetected endpoint -- consult Documentation/usb/scanner.txt."); return NULL; /* Shouldn't ever get here unless we have something weird */ } /* * Perform a quick check to make sure that everything worked as it * should have. */ switch(interface->bNumEndpoints) { case 2: if (!have_bulk_in || !have_bulk_out) { info("probe_scanner: Two bulk endpoints required."); return NULL; } break; case 3: if (!have_bulk_in || !have_bulk_out || !have_intr) { info("probe_scanner: Two bulk endpoints and one interrupt endpoint required."); return NULL; } break; default: info("probe_scanner: Endpoint determination failed -- consult Documentation/usb/scanner.txt"); return NULL; } /* * Determine a minor number and initialize the structure associated * with it. The problem with this is that we are counting on the fact * that the user will sequentially add device nodes for the scanner * devices. */ down(&scn_mutex); for (scn_minor = 0; scn_minor < SCN_MAX_MNR; scn_minor++) { if (!p_scn_table[scn_minor]) break; } /* Check to make sure that the last slot isn't already taken */ if (p_scn_table[scn_minor]) { err("probe_scanner: No more minor devices remaining."); up(&scn_mutex); return NULL; } dbg("probe_scanner: Allocated minor:%d", scn_minor); if (!(scn = kmalloc (sizeof (struct scn_usb_data), GFP_KERNEL))) { err("probe_scanner: Out of memory."); up(&scn_mutex); return NULL; } memset (scn, 0, sizeof(struct scn_usb_data)); init_MUTEX(&(scn->sem)); /* Initializes to unlocked */ dbg ("probe_scanner(%d): Address of scn:%p", scn_minor, scn); /* Ok, if we detected an interrupt EP, setup a handler for it */ if (have_intr) { dbg("probe_scanner(%d): Configuring IRQ handler for intr EP:%d", scn_minor, have_intr); FILL_INT_URB(&scn->scn_irq, dev, usb_rcvintpipe(dev, have_intr), &scn->button, 1, irq_scanner, scn, // endpoint[(int)have_intr].bInterval); 250); if (usb_submit_urb(&scn->scn_irq)) { err("probe_scanner(%d): Unable to allocate INT URB.", scn_minor); kfree(scn); up(&scn_mutex); return NULL; } } /* Ok, now initialize all the relevant values */ if (!(scn->obuf = (char *)kmalloc(OBUF_SIZE, GFP_KERNEL))) { err("probe_scanner(%d): Not enough memory for the output buffer.", scn_minor); kfree(scn); up(&scn_mutex); return NULL; } dbg("probe_scanner(%d): obuf address:%p", scn_minor, scn->obuf); if (!(scn->ibuf = (char *)kmalloc(IBUF_SIZE, GFP_KERNEL))) { err("probe_scanner(%d): Not enough memory for the input buffer.", scn_minor); kfree(scn->obuf); kfree(scn); up(&scn_mutex); return NULL; } dbg("probe_scanner(%d): ibuf address:%p", scn_minor, scn->ibuf); switch (dev->descriptor.idVendor) { /* Scanner specific read timeout parameters */ case 0x04b8: /* Seiko/Epson */ scn->rd_nak_timeout = HZ * 40; break; case 0x055f: /* Mustek */ case 0x0400: /* Another Mustek */ case 0x0ff5: /* And yet another Mustek */ scn->rd_nak_timeout = HZ * 1; default: scn->rd_nak_timeout = RD_NAK_TIMEOUT; } if (read_timeout > 0) { /* User specified read timeout overrides everything */ info("probe_scanner: User specified USB read timeout - %d", read_timeout); scn->rd_nak_timeout = read_timeout; } scn->bulk_in_ep = have_bulk_in; scn->bulk_out_ep = have_bulk_out; scn->intr_ep = have_intr; scn->present = 1; scn->scn_dev = dev; scn->scn_minor = scn_minor; scn->isopen = 0; sprintf(name, "scanner%d", scn->scn_minor); scn->devfs = devfs_register(usb_devfs_handle, name, DEVFS_FL_DEFAULT, USB_MAJOR, SCN_BASE_MNR + scn->scn_minor, S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, &usb_scanner_fops, NULL); if (scn->devfs == NULL) dbg("scanner%d: device node registration failed", scn_minor); p_scn_table[scn_minor] = scn; up(&scn_mutex); return scn; }