Path: blob/master/drivers/isdn/gigaset/usb-gigaset.c
15111 views
/*1* USB driver for Gigaset 307x directly or using M105 Data.2*3* Copyright (c) 2001 by Stefan Eilers4* and Hansjoerg Lipp <[email protected]>.5*6* This driver was derived from the USB skeleton driver by7* Greg Kroah-Hartman <[email protected]>8*9* =====================================================================10* This program is free software; you can redistribute it and/or11* modify it under the terms of the GNU General Public License as12* published by the Free Software Foundation; either version 2 of13* the License, or (at your option) any later version.14* =====================================================================15*/1617#include "gigaset.h"18#include <linux/usb.h>19#include <linux/module.h>20#include <linux/moduleparam.h>2122/* Version Information */23#define DRIVER_AUTHOR "Hansjoerg Lipp <[email protected]>, Stefan Eilers"24#define DRIVER_DESC "USB Driver for Gigaset 307x using M105"2526/* Module parameters */2728static int startmode = SM_ISDN;29static int cidmode = 1;3031module_param(startmode, int, S_IRUGO);32module_param(cidmode, int, S_IRUGO);33MODULE_PARM_DESC(startmode, "start in isdn4linux mode");34MODULE_PARM_DESC(cidmode, "Call-ID mode");3536#define GIGASET_MINORS 137#define GIGASET_MINOR 838#define GIGASET_MODULENAME "usb_gigaset"39#define GIGASET_DEVNAME "ttyGU"4041/* length limit according to Siemens 3070usb-protokoll.doc ch. 2.1 */42#define IF_WRITEBUF 2644344/* Values for the Gigaset M105 Data */45#define USB_M105_VENDOR_ID 0x068146#define USB_M105_PRODUCT_ID 0x00094748/* table of devices that work with this driver */49static const struct usb_device_id gigaset_table[] = {50{ USB_DEVICE(USB_M105_VENDOR_ID, USB_M105_PRODUCT_ID) },51{ } /* Terminating entry */52};5354MODULE_DEVICE_TABLE(usb, gigaset_table);5556/*57* Control requests (empty fields: 00)58*59* RT|RQ|VALUE|INDEX|LEN |DATA60* In:61* C1 08 0162* Get flags (1 byte). Bits: 0=dtr,1=rts,3-7:?63* C1 0F ll ll64* Get device information/status (llll: 0x200 and 0x40 seen).65* Real size: I only saw MIN(llll,0x64).66* Contents: seems to be always the same...67* offset 0x00: Length of this structure (0x64) (len: 1,2,3 bytes)68* offset 0x3c: String (16 bit chars): "MCCI USB Serial V2.0"69* rest: ?70* Out:71* 41 1172* Initialize/reset device ?73* 41 00 xx 0074* ? (xx=00 or 01; 01 on start, 00 on close)75* 41 07 vv mm76* Set/clear flags vv=value, mm=mask (see RQ 08)77* 41 12 xx78* Used before the following configuration requests are issued79* (with xx=0x0f). I've seen other values<0xf, though.80* 41 01 xx xx81* Set baud rate. xxxx=ceil(0x384000/rate)=trunc(0x383fff/rate)+1.82* 41 03 ps bb83* Set byte size and parity. p: 0x20=even,0x10=odd,0x00=no parity84* [ 0x30: m, 0x40: s ]85* [s: 0: 1 stop bit; 1: 1.5; 2: 2]86* bb: bits/byte (seen 7 and 8)87* 41 13 -- -- -- -- 10 00 ww 00 00 00 xx 00 00 00 yy 00 00 00 zz 00 00 0088* ??89* Initialization: 01, 40, 00, 0090* Open device: 00 40, 00, 0091* yy and zz seem to be equal, either 0x00 or 0x0a92* (ww,xx) pairs seen: (00,00), (00,40), (01,40), (09,80), (19,80)93* 41 19 -- -- -- -- 06 00 00 00 00 xx 11 1394* Used after every "configuration sequence" (RQ 12, RQs 01/03/13).95* xx is usually 0x00 but was 0x7e before starting data transfer96* in unimodem mode. So, this might be an array of characters that97* need special treatment ("commit all bufferd data"?), 11=^Q, 13=^S.98*99* Unimodem mode: use "modprobe ppp_async flag_time=0" as the device _needs_ two100* flags per packet.101*/102103/* functions called if a device of this driver is connected/disconnected */104static int gigaset_probe(struct usb_interface *interface,105const struct usb_device_id *id);106static void gigaset_disconnect(struct usb_interface *interface);107108/* functions called before/after suspend */109static int gigaset_suspend(struct usb_interface *intf, pm_message_t message);110static int gigaset_resume(struct usb_interface *intf);111static int gigaset_pre_reset(struct usb_interface *intf);112113static struct gigaset_driver *driver;114115/* usb specific object needed to register this driver with the usb subsystem */116static struct usb_driver gigaset_usb_driver = {117.name = GIGASET_MODULENAME,118.probe = gigaset_probe,119.disconnect = gigaset_disconnect,120.id_table = gigaset_table,121.suspend = gigaset_suspend,122.resume = gigaset_resume,123.reset_resume = gigaset_resume,124.pre_reset = gigaset_pre_reset,125.post_reset = gigaset_resume,126};127128struct usb_cardstate {129struct usb_device *udev; /* usb device pointer */130struct usb_interface *interface; /* interface for this device */131int busy; /* bulk output in progress */132133/* Output buffer */134unsigned char *bulk_out_buffer;135int bulk_out_size;136__u8 bulk_out_endpointAddr;137struct urb *bulk_out_urb;138139/* Input buffer */140unsigned char *rcvbuf;141int rcvbuf_size;142struct urb *read_urb;143__u8 int_in_endpointAddr;144145char bchars[6]; /* for request 0x19 */146};147148static inline unsigned tiocm_to_gigaset(unsigned state)149{150return ((state & TIOCM_DTR) ? 1 : 0) | ((state & TIOCM_RTS) ? 2 : 0);151}152153static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state,154unsigned new_state)155{156struct usb_device *udev = cs->hw.usb->udev;157unsigned mask, val;158int r;159160mask = tiocm_to_gigaset(old_state ^ new_state);161val = tiocm_to_gigaset(new_state);162163gig_dbg(DEBUG_USBREQ, "set flags 0x%02x with mask 0x%02x", val, mask);164r = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 7, 0x41,165(val & 0xff) | ((mask & 0xff) << 8), 0,166NULL, 0, 2000 /* timeout? */);167if (r < 0)168return r;169return 0;170}171172/*173* Set M105 configuration value174* using undocumented device commands reverse engineered from USB traces175* of the Siemens Windows driver176*/177static int set_value(struct cardstate *cs, u8 req, u16 val)178{179struct usb_device *udev = cs->hw.usb->udev;180int r, r2;181182gig_dbg(DEBUG_USBREQ, "request %02x (%04x)",183(unsigned)req, (unsigned)val);184r = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x12, 0x41,1850xf /*?*/, 0, NULL, 0, 2000 /*?*/);186/* no idea what this does */187if (r < 0) {188dev_err(&udev->dev, "error %d on request 0x12\n", -r);189return r;190}191192r = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), req, 0x41,193val, 0, NULL, 0, 2000 /*?*/);194if (r < 0)195dev_err(&udev->dev, "error %d on request 0x%02x\n",196-r, (unsigned)req);197198r2 = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x19, 0x41,1990, 0, cs->hw.usb->bchars, 6, 2000 /*?*/);200if (r2 < 0)201dev_err(&udev->dev, "error %d on request 0x19\n", -r2);202203return r < 0 ? r : (r2 < 0 ? r2 : 0);204}205206/*207* set the baud rate on the internal serial adapter208* using the undocumented parameter setting command209*/210static int gigaset_baud_rate(struct cardstate *cs, unsigned cflag)211{212u16 val;213u32 rate;214215cflag &= CBAUD;216217switch (cflag) {218case B300: rate = 300; break;219case B600: rate = 600; break;220case B1200: rate = 1200; break;221case B2400: rate = 2400; break;222case B4800: rate = 4800; break;223case B9600: rate = 9600; break;224case B19200: rate = 19200; break;225case B38400: rate = 38400; break;226case B57600: rate = 57600; break;227case B115200: rate = 115200; break;228default:229rate = 9600;230dev_err(cs->dev, "unsupported baudrate request 0x%x,"231" using default of B9600\n", cflag);232}233234val = 0x383fff / rate + 1;235236return set_value(cs, 1, val);237}238239/*240* set the line format on the internal serial adapter241* using the undocumented parameter setting command242*/243static int gigaset_set_line_ctrl(struct cardstate *cs, unsigned cflag)244{245u16 val = 0;246247/* set the parity */248if (cflag & PARENB)249val |= (cflag & PARODD) ? 0x10 : 0x20;250251/* set the number of data bits */252switch (cflag & CSIZE) {253case CS5:254val |= 5 << 8; break;255case CS6:256val |= 6 << 8; break;257case CS7:258val |= 7 << 8; break;259case CS8:260val |= 8 << 8; break;261default:262dev_err(cs->dev, "CSIZE was not CS5-CS8, using default of 8\n");263val |= 8 << 8;264break;265}266267/* set the number of stop bits */268if (cflag & CSTOPB) {269if ((cflag & CSIZE) == CS5)270val |= 1; /* 1.5 stop bits */271else272val |= 2; /* 2 stop bits */273}274275return set_value(cs, 3, val);276}277278279/*============================================================================*/280static int gigaset_init_bchannel(struct bc_state *bcs)281{282/* nothing to do for M10x */283gigaset_bchannel_up(bcs);284return 0;285}286287static int gigaset_close_bchannel(struct bc_state *bcs)288{289/* nothing to do for M10x */290gigaset_bchannel_down(bcs);291return 0;292}293294static int write_modem(struct cardstate *cs);295static int send_cb(struct cardstate *cs, struct cmdbuf_t *cb);296297298/* Write tasklet handler: Continue sending current skb, or send command, or299* start sending an skb from the send queue.300*/301static void gigaset_modem_fill(unsigned long data)302{303struct cardstate *cs = (struct cardstate *) data;304struct bc_state *bcs = &cs->bcs[0]; /* only one channel */305struct cmdbuf_t *cb;306int again;307308gig_dbg(DEBUG_OUTPUT, "modem_fill");309310if (cs->hw.usb->busy) {311gig_dbg(DEBUG_OUTPUT, "modem_fill: busy");312return;313}314315do {316again = 0;317if (!bcs->tx_skb) { /* no skb is being sent */318cb = cs->cmdbuf;319if (cb) { /* commands to send? */320gig_dbg(DEBUG_OUTPUT, "modem_fill: cb");321if (send_cb(cs, cb) < 0) {322gig_dbg(DEBUG_OUTPUT,323"modem_fill: send_cb failed");324again = 1; /* no callback will be325called! */326}327} else { /* skbs to send? */328bcs->tx_skb = skb_dequeue(&bcs->squeue);329if (bcs->tx_skb)330gig_dbg(DEBUG_INTR,331"Dequeued skb (Adr: %lx)!",332(unsigned long) bcs->tx_skb);333}334}335336if (bcs->tx_skb) {337gig_dbg(DEBUG_OUTPUT, "modem_fill: tx_skb");338if (write_modem(cs) < 0) {339gig_dbg(DEBUG_OUTPUT,340"modem_fill: write_modem failed");341again = 1; /* no callback will be called! */342}343}344} while (again);345}346347/*348* Interrupt Input URB completion routine349*/350static void gigaset_read_int_callback(struct urb *urb)351{352struct cardstate *cs = urb->context;353struct inbuf_t *inbuf = cs->inbuf;354int status = urb->status;355int r;356unsigned numbytes;357unsigned char *src;358unsigned long flags;359360if (!status) {361numbytes = urb->actual_length;362363if (numbytes) {364src = cs->hw.usb->rcvbuf;365if (unlikely(*src))366dev_warn(cs->dev,367"%s: There was no leading 0, but 0x%02x!\n",368__func__, (unsigned) *src);369++src; /* skip leading 0x00 */370--numbytes;371if (gigaset_fill_inbuf(inbuf, src, numbytes)) {372gig_dbg(DEBUG_INTR, "%s-->BH", __func__);373gigaset_schedule_event(inbuf->cs);374}375} else376gig_dbg(DEBUG_INTR, "Received zero block length");377} else {378/* The urb might have been killed. */379gig_dbg(DEBUG_ANY, "%s - nonzero status received: %d",380__func__, status);381if (status == -ENOENT || status == -ESHUTDOWN)382/* killed or endpoint shutdown: don't resubmit */383return;384}385386/* resubmit URB */387spin_lock_irqsave(&cs->lock, flags);388if (!cs->connected) {389spin_unlock_irqrestore(&cs->lock, flags);390pr_err("%s: disconnected\n", __func__);391return;392}393r = usb_submit_urb(urb, GFP_ATOMIC);394spin_unlock_irqrestore(&cs->lock, flags);395if (r)396dev_err(cs->dev, "error %d resubmitting URB\n", -r);397}398399400/* This callback routine is called when data was transmitted to the device. */401static void gigaset_write_bulk_callback(struct urb *urb)402{403struct cardstate *cs = urb->context;404int status = urb->status;405unsigned long flags;406407switch (status) {408case 0: /* normal completion */409break;410case -ENOENT: /* killed */411gig_dbg(DEBUG_ANY, "%s: killed", __func__);412cs->hw.usb->busy = 0;413return;414default:415dev_err(cs->dev, "bulk transfer failed (status %d)\n",416-status);417/* That's all we can do. Communication problems418are handled by timeouts or network protocols. */419}420421spin_lock_irqsave(&cs->lock, flags);422if (!cs->connected) {423pr_err("%s: disconnected\n", __func__);424} else {425cs->hw.usb->busy = 0;426tasklet_schedule(&cs->write_tasklet);427}428spin_unlock_irqrestore(&cs->lock, flags);429}430431static int send_cb(struct cardstate *cs, struct cmdbuf_t *cb)432{433struct cmdbuf_t *tcb;434unsigned long flags;435int count;436int status = -ENOENT;437struct usb_cardstate *ucs = cs->hw.usb;438439do {440if (!cb->len) {441tcb = cb;442443spin_lock_irqsave(&cs->cmdlock, flags);444cs->cmdbytes -= cs->curlen;445gig_dbg(DEBUG_OUTPUT, "send_cb: sent %u bytes, %u left",446cs->curlen, cs->cmdbytes);447cs->cmdbuf = cb = cb->next;448if (cb) {449cb->prev = NULL;450cs->curlen = cb->len;451} else {452cs->lastcmdbuf = NULL;453cs->curlen = 0;454}455spin_unlock_irqrestore(&cs->cmdlock, flags);456457if (tcb->wake_tasklet)458tasklet_schedule(tcb->wake_tasklet);459kfree(tcb);460}461if (cb) {462count = min(cb->len, ucs->bulk_out_size);463gig_dbg(DEBUG_OUTPUT, "send_cb: send %d bytes", count);464465usb_fill_bulk_urb(ucs->bulk_out_urb, ucs->udev,466usb_sndbulkpipe(ucs->udev,467ucs->bulk_out_endpointAddr & 0x0f),468cb->buf + cb->offset, count,469gigaset_write_bulk_callback, cs);470471cb->offset += count;472cb->len -= count;473ucs->busy = 1;474475spin_lock_irqsave(&cs->lock, flags);476status = cs->connected ?477usb_submit_urb(ucs->bulk_out_urb, GFP_ATOMIC) :478-ENODEV;479spin_unlock_irqrestore(&cs->lock, flags);480481if (status) {482ucs->busy = 0;483dev_err(cs->dev,484"could not submit urb (error %d)\n",485-status);486cb->len = 0; /* skip urb => remove cb+wakeup487in next loop cycle */488}489}490} while (cb && status); /* next command on error */491492return status;493}494495/* Send command to device. */496static int gigaset_write_cmd(struct cardstate *cs, struct cmdbuf_t *cb)497{498unsigned long flags;499500gigaset_dbg_buffer(cs->mstate != MS_LOCKED ?501DEBUG_TRANSCMD : DEBUG_LOCKCMD,502"CMD Transmit", cb->len, cb->buf);503504spin_lock_irqsave(&cs->cmdlock, flags);505cb->prev = cs->lastcmdbuf;506if (cs->lastcmdbuf)507cs->lastcmdbuf->next = cb;508else {509cs->cmdbuf = cb;510cs->curlen = cb->len;511}512cs->cmdbytes += cb->len;513cs->lastcmdbuf = cb;514spin_unlock_irqrestore(&cs->cmdlock, flags);515516spin_lock_irqsave(&cs->lock, flags);517if (cs->connected)518tasklet_schedule(&cs->write_tasklet);519spin_unlock_irqrestore(&cs->lock, flags);520return cb->len;521}522523static int gigaset_write_room(struct cardstate *cs)524{525unsigned bytes;526527bytes = cs->cmdbytes;528return bytes < IF_WRITEBUF ? IF_WRITEBUF - bytes : 0;529}530531static int gigaset_chars_in_buffer(struct cardstate *cs)532{533return cs->cmdbytes;534}535536/*537* set the break characters on the internal serial adapter538* using undocumented device commands reverse engineered from USB traces539* of the Siemens Windows driver540*/541static int gigaset_brkchars(struct cardstate *cs, const unsigned char buf[6])542{543struct usb_device *udev = cs->hw.usb->udev;544545gigaset_dbg_buffer(DEBUG_USBREQ, "brkchars", 6, buf);546memcpy(cs->hw.usb->bchars, buf, 6);547return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x19, 0x41,5480, 0, &buf, 6, 2000);549}550551static int gigaset_freebcshw(struct bc_state *bcs)552{553/* unused */554return 1;555}556557/* Initialize the b-channel structure */558static int gigaset_initbcshw(struct bc_state *bcs)559{560/* unused */561bcs->hw.usb = NULL;562return 1;563}564565static void gigaset_reinitbcshw(struct bc_state *bcs)566{567/* nothing to do for M10x */568}569570static void gigaset_freecshw(struct cardstate *cs)571{572tasklet_kill(&cs->write_tasklet);573kfree(cs->hw.usb);574}575576static int gigaset_initcshw(struct cardstate *cs)577{578struct usb_cardstate *ucs;579580cs->hw.usb = ucs =581kmalloc(sizeof(struct usb_cardstate), GFP_KERNEL);582if (!ucs) {583pr_err("out of memory\n");584return 0;585}586587ucs->bchars[0] = 0;588ucs->bchars[1] = 0;589ucs->bchars[2] = 0;590ucs->bchars[3] = 0;591ucs->bchars[4] = 0x11;592ucs->bchars[5] = 0x13;593ucs->bulk_out_buffer = NULL;594ucs->bulk_out_urb = NULL;595ucs->read_urb = NULL;596tasklet_init(&cs->write_tasklet,597gigaset_modem_fill, (unsigned long) cs);598599return 1;600}601602/* Send data from current skb to the device. */603static int write_modem(struct cardstate *cs)604{605int ret = 0;606int count;607struct bc_state *bcs = &cs->bcs[0]; /* only one channel */608struct usb_cardstate *ucs = cs->hw.usb;609unsigned long flags;610611gig_dbg(DEBUG_OUTPUT, "len: %d...", bcs->tx_skb->len);612613if (!bcs->tx_skb->len) {614dev_kfree_skb_any(bcs->tx_skb);615bcs->tx_skb = NULL;616return -EINVAL;617}618619/* Copy data to bulk out buffer and transmit data */620count = min(bcs->tx_skb->len, (unsigned) ucs->bulk_out_size);621skb_copy_from_linear_data(bcs->tx_skb, ucs->bulk_out_buffer, count);622skb_pull(bcs->tx_skb, count);623ucs->busy = 1;624gig_dbg(DEBUG_OUTPUT, "write_modem: send %d bytes", count);625626spin_lock_irqsave(&cs->lock, flags);627if (cs->connected) {628usb_fill_bulk_urb(ucs->bulk_out_urb, ucs->udev,629usb_sndbulkpipe(ucs->udev,630ucs->bulk_out_endpointAddr &6310x0f),632ucs->bulk_out_buffer, count,633gigaset_write_bulk_callback, cs);634ret = usb_submit_urb(ucs->bulk_out_urb, GFP_ATOMIC);635} else {636ret = -ENODEV;637}638spin_unlock_irqrestore(&cs->lock, flags);639640if (ret) {641dev_err(cs->dev, "could not submit urb (error %d)\n", -ret);642ucs->busy = 0;643}644645if (!bcs->tx_skb->len) {646/* skb sent completely */647gigaset_skb_sent(bcs, bcs->tx_skb);648649gig_dbg(DEBUG_INTR, "kfree skb (Adr: %lx)!",650(unsigned long) bcs->tx_skb);651dev_kfree_skb_any(bcs->tx_skb);652bcs->tx_skb = NULL;653}654655return ret;656}657658static int gigaset_probe(struct usb_interface *interface,659const struct usb_device_id *id)660{661int retval;662struct usb_device *udev = interface_to_usbdev(interface);663struct usb_host_interface *hostif = interface->cur_altsetting;664struct cardstate *cs = NULL;665struct usb_cardstate *ucs = NULL;666struct usb_endpoint_descriptor *endpoint;667int buffer_size;668669gig_dbg(DEBUG_ANY, "%s: Check if device matches ...", __func__);670671/* See if the device offered us matches what we can accept */672if ((le16_to_cpu(udev->descriptor.idVendor) != USB_M105_VENDOR_ID) ||673(le16_to_cpu(udev->descriptor.idProduct) != USB_M105_PRODUCT_ID)) {674gig_dbg(DEBUG_ANY, "device ID (0x%x, 0x%x) not for me - skip",675le16_to_cpu(udev->descriptor.idVendor),676le16_to_cpu(udev->descriptor.idProduct));677return -ENODEV;678}679if (hostif->desc.bInterfaceNumber != 0) {680gig_dbg(DEBUG_ANY, "interface %d not for me - skip",681hostif->desc.bInterfaceNumber);682return -ENODEV;683}684if (hostif->desc.bAlternateSetting != 0) {685dev_notice(&udev->dev, "unsupported altsetting %d - skip",686hostif->desc.bAlternateSetting);687return -ENODEV;688}689if (hostif->desc.bInterfaceClass != 255) {690dev_notice(&udev->dev, "unsupported interface class %d - skip",691hostif->desc.bInterfaceClass);692return -ENODEV;693}694695dev_info(&udev->dev, "%s: Device matched ... !\n", __func__);696697/* allocate memory for our device state and initialize it */698cs = gigaset_initcs(driver, 1, 1, 0, cidmode, GIGASET_MODULENAME);699if (!cs)700return -ENODEV;701ucs = cs->hw.usb;702703/* save off device structure ptrs for later use */704usb_get_dev(udev);705ucs->udev = udev;706ucs->interface = interface;707cs->dev = &interface->dev;708709/* save address of controller structure */710usb_set_intfdata(interface, cs);711712endpoint = &hostif->endpoint[0].desc;713714buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);715ucs->bulk_out_size = buffer_size;716ucs->bulk_out_endpointAddr = endpoint->bEndpointAddress;717ucs->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL);718if (!ucs->bulk_out_buffer) {719dev_err(cs->dev, "Couldn't allocate bulk_out_buffer\n");720retval = -ENOMEM;721goto error;722}723724ucs->bulk_out_urb = usb_alloc_urb(0, GFP_KERNEL);725if (!ucs->bulk_out_urb) {726dev_err(cs->dev, "Couldn't allocate bulk_out_urb\n");727retval = -ENOMEM;728goto error;729}730731endpoint = &hostif->endpoint[1].desc;732733ucs->busy = 0;734735ucs->read_urb = usb_alloc_urb(0, GFP_KERNEL);736if (!ucs->read_urb) {737dev_err(cs->dev, "No free urbs available\n");738retval = -ENOMEM;739goto error;740}741buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);742ucs->rcvbuf_size = buffer_size;743ucs->int_in_endpointAddr = endpoint->bEndpointAddress;744ucs->rcvbuf = kmalloc(buffer_size, GFP_KERNEL);745if (!ucs->rcvbuf) {746dev_err(cs->dev, "Couldn't allocate rcvbuf\n");747retval = -ENOMEM;748goto error;749}750/* Fill the interrupt urb and send it to the core */751usb_fill_int_urb(ucs->read_urb, udev,752usb_rcvintpipe(udev,753endpoint->bEndpointAddress & 0x0f),754ucs->rcvbuf, buffer_size,755gigaset_read_int_callback,756cs, endpoint->bInterval);757758retval = usb_submit_urb(ucs->read_urb, GFP_KERNEL);759if (retval) {760dev_err(cs->dev, "Could not submit URB (error %d)\n", -retval);761goto error;762}763764/* tell common part that the device is ready */765if (startmode == SM_LOCKED)766cs->mstate = MS_LOCKED;767768if (!gigaset_start(cs)) {769tasklet_kill(&cs->write_tasklet);770retval = -ENODEV;771goto error;772}773return 0;774775error:776usb_kill_urb(ucs->read_urb);777kfree(ucs->bulk_out_buffer);778usb_free_urb(ucs->bulk_out_urb);779kfree(ucs->rcvbuf);780usb_free_urb(ucs->read_urb);781usb_set_intfdata(interface, NULL);782ucs->read_urb = ucs->bulk_out_urb = NULL;783ucs->rcvbuf = ucs->bulk_out_buffer = NULL;784usb_put_dev(ucs->udev);785ucs->udev = NULL;786ucs->interface = NULL;787gigaset_freecs(cs);788return retval;789}790791static void gigaset_disconnect(struct usb_interface *interface)792{793struct cardstate *cs;794struct usb_cardstate *ucs;795796cs = usb_get_intfdata(interface);797ucs = cs->hw.usb;798799dev_info(cs->dev, "disconnecting Gigaset USB adapter\n");800801usb_kill_urb(ucs->read_urb);802803gigaset_stop(cs);804805usb_set_intfdata(interface, NULL);806tasklet_kill(&cs->write_tasklet);807808usb_kill_urb(ucs->bulk_out_urb);809810kfree(ucs->bulk_out_buffer);811usb_free_urb(ucs->bulk_out_urb);812kfree(ucs->rcvbuf);813usb_free_urb(ucs->read_urb);814ucs->read_urb = ucs->bulk_out_urb = NULL;815ucs->rcvbuf = ucs->bulk_out_buffer = NULL;816817usb_put_dev(ucs->udev);818ucs->interface = NULL;819ucs->udev = NULL;820cs->dev = NULL;821gigaset_freecs(cs);822}823824/* gigaset_suspend825* This function is called before the USB connection is suspended or reset.826*/827static int gigaset_suspend(struct usb_interface *intf, pm_message_t message)828{829struct cardstate *cs = usb_get_intfdata(intf);830831/* stop activity */832cs->connected = 0; /* prevent rescheduling */833usb_kill_urb(cs->hw.usb->read_urb);834tasklet_kill(&cs->write_tasklet);835usb_kill_urb(cs->hw.usb->bulk_out_urb);836837gig_dbg(DEBUG_SUSPEND, "suspend complete");838return 0;839}840841/* gigaset_resume842* This function is called after the USB connection has been resumed or reset.843*/844static int gigaset_resume(struct usb_interface *intf)845{846struct cardstate *cs = usb_get_intfdata(intf);847int rc;848849/* resubmit interrupt URB */850cs->connected = 1;851rc = usb_submit_urb(cs->hw.usb->read_urb, GFP_KERNEL);852if (rc) {853dev_err(cs->dev, "Could not submit read URB (error %d)\n", -rc);854return rc;855}856857gig_dbg(DEBUG_SUSPEND, "resume complete");858return 0;859}860861/* gigaset_pre_reset862* This function is called before the USB connection is reset.863*/864static int gigaset_pre_reset(struct usb_interface *intf)865{866/* same as suspend */867return gigaset_suspend(intf, PMSG_ON);868}869870static const struct gigaset_ops ops = {871gigaset_write_cmd,872gigaset_write_room,873gigaset_chars_in_buffer,874gigaset_brkchars,875gigaset_init_bchannel,876gigaset_close_bchannel,877gigaset_initbcshw,878gigaset_freebcshw,879gigaset_reinitbcshw,880gigaset_initcshw,881gigaset_freecshw,882gigaset_set_modem_ctrl,883gigaset_baud_rate,884gigaset_set_line_ctrl,885gigaset_m10x_send_skb,886gigaset_m10x_input,887};888889/*890* This function is called while kernel-module is loaded891*/892static int __init usb_gigaset_init(void)893{894int result;895896/* allocate memory for our driver state and initialize it */897driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS,898GIGASET_MODULENAME, GIGASET_DEVNAME,899&ops, THIS_MODULE);900if (driver == NULL)901goto error;902903/* register this driver with the USB subsystem */904result = usb_register(&gigaset_usb_driver);905if (result < 0) {906pr_err("error %d registering USB driver\n", -result);907goto error;908}909910pr_info(DRIVER_DESC "\n");911return 0;912913error:914if (driver)915gigaset_freedriver(driver);916driver = NULL;917return -1;918}919920/*921* This function is called while unloading the kernel-module922*/923static void __exit usb_gigaset_exit(void)924{925int i;926927gigaset_blockdriver(driver); /* => probe will fail928* => no gigaset_start any more929*/930931/* stop all connected devices */932for (i = 0; i < driver->minors; i++)933gigaset_shutdown(driver->cs + i);934935/* from now on, no isdn callback should be possible */936937/* deregister this driver with the USB subsystem */938usb_deregister(&gigaset_usb_driver);939/* this will call the disconnect-callback */940/* from now on, no disconnect/probe callback should be running */941942gigaset_freedriver(driver);943driver = NULL;944}945946947module_init(usb_gigaset_init);948module_exit(usb_gigaset_exit);949950MODULE_AUTHOR(DRIVER_AUTHOR);951MODULE_DESCRIPTION(DRIVER_DESC);952953MODULE_LICENSE("GPL");954955956