static struct fritz_adapter * __devinit new_adapter(void) { struct fritz_adapter *adapter; struct hisax_b_if *b_if[2]; int i; adapter = kzalloc(sizeof(struct fritz_adapter), GFP_KERNEL); if (!adapter) return NULL; adapter->isac.hisax_d_if.owner = THIS_MODULE; adapter->isac.hisax_d_if.ifc.priv = &adapter->isac; adapter->isac.hisax_d_if.ifc.l2l1 = isac_d_l2l1; for (i = 0; i < 2; i++) { adapter->bcs[i].adapter = adapter; adapter->bcs[i].channel = i; adapter->bcs[i].b_if.ifc.priv = &adapter->bcs[i]; adapter->bcs[i].b_if.ifc.l2l1 = fritz_b_l2l1; } for (i = 0; i < 2; i++) b_if[i] = &adapter->bcs[i].b_if; if (hisax_register(&adapter->isac.hisax_d_if, b_if, "fcpcipnp", protocol) != 0) { kfree(adapter); adapter = NULL; } return adapter; }
static struct fritz_adapter * __devinit new_adapter(struct pci_dev *pdev) { struct fritz_adapter *adapter; struct hisax_b_if *b_if[2]; int i; adapter = kmalloc(sizeof(struct fritz_adapter), GFP_KERNEL); if (!adapter) return NULL; memset(adapter, 0, sizeof(struct fritz_adapter)); SET_MODULE_OWNER(&adapter->isac.hisax_d_if); adapter->isac.hisax_d_if.ifc.priv = &adapter->isac; adapter->isac.hisax_d_if.ifc.l2l1 = isac_d_l2l1; for (i = 0; i < 2; i++) { adapter->bcs[i].adapter = adapter; adapter->bcs[i].channel = i; adapter->bcs[i].b_if.ifc.priv = &adapter->bcs[i]; adapter->bcs[i].b_if.ifc.l2l1 = fritz_b_l2l1; } pci_set_drvdata(pdev, adapter); for (i = 0; i < 2; i++) b_if[i] = &adapter->bcs[i].b_if; hisax_register(&adapter->isac.hisax_d_if, b_if, "fcpcipnp", protocol); return adapter; }
/* * This function will be called when the adapter is plugged * into the USB bus. */ static int probe_st5481(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *dev = interface_to_usbdev(intf); struct st5481_adapter *adapter; struct hisax_b_if *b_if[2]; int retval, i; printk(KERN_INFO "st541: found adapter VendorId %04x, ProductId %04x, LEDs %d\n", le16_to_cpu(dev->descriptor.idVendor), le16_to_cpu(dev->descriptor.idProduct), number_of_leds); adapter = kzalloc(sizeof(struct st5481_adapter), GFP_KERNEL); if (!adapter) return -ENOMEM; adapter->number_of_leds = number_of_leds; adapter->usb_dev = dev; adapter->hisax_d_if.owner = THIS_MODULE; adapter->hisax_d_if.ifc.priv = adapter; adapter->hisax_d_if.ifc.l2l1 = st5481_d_l2l1; for (i = 0; i < 2; i++) { adapter->bcs[i].adapter = adapter; adapter->bcs[i].channel = i; adapter->bcs[i].b_if.ifc.priv = &adapter->bcs[i]; adapter->bcs[i].b_if.ifc.l2l1 = st5481_b_l2l1; } retval = st5481_setup_usb(adapter); if (retval < 0) goto err; retval = st5481_setup_d(adapter); if (retval < 0) goto err_usb; retval = st5481_setup_b(&adapter->bcs[0]); if (retval < 0) goto err_d; retval = st5481_setup_b(&adapter->bcs[1]); if (retval < 0) goto err_b; for (i = 0; i < 2; i++) b_if[i] = &adapter->bcs[i].b_if; if (hisax_register(&adapter->hisax_d_if, b_if, "st5481_usb", protocol) != 0) goto err_b1; st5481_start(adapter); usb_set_intfdata(intf, adapter); return 0; err_b1: st5481_release_b(&adapter->bcs[1]); err_b: st5481_release_b(&adapter->bcs[0]); err_d: st5481_release_d(adapter); err_usb: st5481_release_usb(adapter); err: kfree(adapter); return -EIO; }
/* 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; }
/* * This function will be called when the adapter is plugged * into the USB bus. */ static void * __devinit probe_st5481(struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id) { struct st5481_adapter *adapter; struct hisax_b_if *b_if[2]; int retval, i; printk(KERN_INFO "st541: found adapter VendorId %04x, ProductId %04x, LEDs %d\n", dev->descriptor.idVendor, dev->descriptor.idProduct, number_of_leds); adapter = kmalloc(sizeof(struct st5481_adapter), GFP_KERNEL); if (!adapter) return NULL; memset(adapter, 0, sizeof(struct st5481_adapter)); adapter->number_of_leds = number_of_leds; adapter->usb_dev = dev; SET_MODULE_OWNER(&adapter->hisax_d_if); adapter->hisax_d_if.ifc.priv = adapter; adapter->hisax_d_if.ifc.l2l1 = st5481_d_l2l1; for (i = 0; i < 2; i++) { adapter->bcs[i].adapter = adapter; adapter->bcs[i].channel = i; adapter->bcs[i].b_if.ifc.priv = &adapter->bcs[i]; adapter->bcs[i].b_if.ifc.l2l1 = st5481_b_l2l1; } list_add(&adapter->list, &adapter_list); retval = st5481_setup_usb(adapter); if (retval < 0) goto err; retval = st5481_setup_d(adapter); if (retval < 0) goto err_usb; retval = st5481_setup_b(&adapter->bcs[0]); if (retval < 0) goto err_d; retval = st5481_setup_b(&adapter->bcs[1]); if (retval < 0) goto err_b; for (i = 0; i < 2; i++) b_if[i] = &adapter->bcs[i].b_if; hisax_register(&adapter->hisax_d_if, b_if, "st5481_usb", protocol); st5481_start(adapter); return adapter; err_b: st5481_release_b(&adapter->bcs[0]); err_d: st5481_release_d(adapter); err_usb: st5481_release_usb(adapter); err: return NULL; }