diff options
Diffstat (limited to 'drivers/isdn/gigaset/usb-gigaset.c')
-rw-r--r-- | drivers/isdn/gigaset/usb-gigaset.c | 455 |
1 files changed, 204 insertions, 251 deletions
diff --git a/drivers/isdn/gigaset/usb-gigaset.c b/drivers/isdn/gigaset/usb-gigaset.c index 323fc7349dec..bfb73fd5077e 100644 --- a/drivers/isdn/gigaset/usb-gigaset.c +++ b/drivers/isdn/gigaset/usb-gigaset.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * USB driver for Gigaset 307x directly or using M105 Data. | 2 | * USB driver for Gigaset 307x directly or using M105 Data. |
3 | * | 3 | * |
4 | * Copyright (c) 2001 by Stefan Eilers <Eilers.Stefan@epost.de> | 4 | * Copyright (c) 2001 by Stefan Eilers |
5 | * and Hansjoerg Lipp <hjlipp@web.de>. | 5 | * and Hansjoerg Lipp <hjlipp@web.de>. |
6 | * | 6 | * |
7 | * This driver was derived from the USB skeleton driver by | 7 | * This driver was derived from the USB skeleton driver by |
@@ -13,10 +13,6 @@ | |||
13 | * published by the Free Software Foundation; either version 2 of | 13 | * published by the Free Software Foundation; either version 2 of |
14 | * the License, or (at your option) any later version. | 14 | * the License, or (at your option) any later version. |
15 | * ===================================================================== | 15 | * ===================================================================== |
16 | * ToDo: ... | ||
17 | * ===================================================================== | ||
18 | * Version: $Id: usb-gigaset.c,v 1.85.4.18 2006/02/04 18:28:16 hjlipp Exp $ | ||
19 | * ===================================================================== | ||
20 | */ | 16 | */ |
21 | 17 | ||
22 | #include "gigaset.h" | 18 | #include "gigaset.h" |
@@ -29,7 +25,7 @@ | |||
29 | #include <linux/moduleparam.h> | 25 | #include <linux/moduleparam.h> |
30 | 26 | ||
31 | /* Version Information */ | 27 | /* Version Information */ |
32 | #define DRIVER_AUTHOR "Hansjoerg Lipp <hjlipp@web.de>, Stefan Eilers <Eilers.Stefan@epost.de>" | 28 | #define DRIVER_AUTHOR "Hansjoerg Lipp <hjlipp@web.de>, Stefan Eilers" |
33 | #define DRIVER_DESC "USB Driver for Gigaset 307x using M105" | 29 | #define DRIVER_DESC "USB Driver for Gigaset 307x using M105" |
34 | 30 | ||
35 | /* Module parameters */ | 31 | /* Module parameters */ |
@@ -62,10 +58,6 @@ static struct usb_device_id gigaset_table [] = { | |||
62 | 58 | ||
63 | MODULE_DEVICE_TABLE(usb, gigaset_table); | 59 | MODULE_DEVICE_TABLE(usb, gigaset_table); |
64 | 60 | ||
65 | /* Get a minor range for your devices from the usb maintainer */ | ||
66 | #define USB_SKEL_MINOR_BASE 200 | ||
67 | |||
68 | |||
69 | /* | 61 | /* |
70 | * Control requests (empty fields: 00) | 62 | * Control requests (empty fields: 00) |
71 | * | 63 | * |
@@ -114,7 +106,7 @@ MODULE_DEVICE_TABLE(usb, gigaset_table); | |||
114 | */ | 106 | */ |
115 | 107 | ||
116 | static int gigaset_probe(struct usb_interface *interface, | 108 | static int gigaset_probe(struct usb_interface *interface, |
117 | const struct usb_device_id *id); | 109 | const struct usb_device_id *id); |
118 | static void gigaset_disconnect(struct usb_interface *interface); | 110 | static void gigaset_disconnect(struct usb_interface *interface); |
119 | 111 | ||
120 | static struct gigaset_driver *driver = NULL; | 112 | static struct gigaset_driver *driver = NULL; |
@@ -122,29 +114,29 @@ static struct cardstate *cardstate = NULL; | |||
122 | 114 | ||
123 | /* usb specific object needed to register this driver with the usb subsystem */ | 115 | /* usb specific object needed to register this driver with the usb subsystem */ |
124 | static struct usb_driver gigaset_usb_driver = { | 116 | static struct usb_driver gigaset_usb_driver = { |
125 | .name = GIGASET_MODULENAME, | 117 | .name = GIGASET_MODULENAME, |
126 | .probe = gigaset_probe, | 118 | .probe = gigaset_probe, |
127 | .disconnect = gigaset_disconnect, | 119 | .disconnect = gigaset_disconnect, |
128 | .id_table = gigaset_table, | 120 | .id_table = gigaset_table, |
129 | }; | 121 | }; |
130 | 122 | ||
131 | struct usb_cardstate { | 123 | struct usb_cardstate { |
132 | struct usb_device *udev; /* save off the usb device pointer */ | 124 | struct usb_device *udev; /* usb device pointer */ |
133 | struct usb_interface *interface; /* the interface for this device */ | 125 | struct usb_interface *interface; /* interface for this device */ |
134 | atomic_t busy; /* bulk output in progress */ | 126 | atomic_t busy; /* bulk output in progress */ |
135 | 127 | ||
136 | /* Output buffer for commands (M105: and data)*/ | 128 | /* Output buffer */ |
137 | unsigned char *bulk_out_buffer; /* the buffer to send data */ | 129 | unsigned char *bulk_out_buffer; |
138 | int bulk_out_size; /* the size of the send buffer */ | 130 | int bulk_out_size; |
139 | __u8 bulk_out_endpointAddr; /* the address of the bulk out endpoint */ | 131 | __u8 bulk_out_endpointAddr; |
140 | struct urb *bulk_out_urb; /* the urb used to transmit data */ | 132 | struct urb *bulk_out_urb; |
141 | 133 | ||
142 | /* Input buffer for command responses (M105: and data)*/ | 134 | /* Input buffer */ |
143 | int rcvbuf_size; /* the size of the receive buffer */ | 135 | int rcvbuf_size; |
144 | struct urb *read_urb; /* the urb used to receive data */ | 136 | struct urb *read_urb; |
145 | __u8 int_in_endpointAddr; /* the address of the bulk in endpoint */ | 137 | __u8 int_in_endpointAddr; |
146 | 138 | ||
147 | char bchars[6]; /* req. 0x19 */ | 139 | char bchars[6]; /* for request 0x19 */ |
148 | }; | 140 | }; |
149 | 141 | ||
150 | struct usb_bc_state {}; | 142 | struct usb_bc_state {}; |
@@ -157,19 +149,20 @@ static inline unsigned tiocm_to_gigaset(unsigned state) | |||
157 | #ifdef CONFIG_GIGASET_UNDOCREQ | 149 | #ifdef CONFIG_GIGASET_UNDOCREQ |
158 | /* WARNING: EXPERIMENTAL! */ | 150 | /* WARNING: EXPERIMENTAL! */ |
159 | static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state, | 151 | static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state, |
160 | unsigned new_state) | 152 | unsigned new_state) |
161 | { | 153 | { |
154 | struct usb_device *udev = cs->hw.usb->udev; | ||
162 | unsigned mask, val; | 155 | unsigned mask, val; |
163 | int r; | 156 | int r; |
164 | 157 | ||
165 | mask = tiocm_to_gigaset(old_state ^ new_state); | 158 | mask = tiocm_to_gigaset(old_state ^ new_state); |
166 | val = tiocm_to_gigaset(new_state); | 159 | val = tiocm_to_gigaset(new_state); |
167 | 160 | ||
168 | dbg(DEBUG_USBREQ, "set flags 0x%02x with mask 0x%02x", val, mask); | 161 | gig_dbg(DEBUG_USBREQ, "set flags 0x%02x with mask 0x%02x", val, mask); |
169 | r = usb_control_msg(cs->hw.usb->udev, | 162 | // don't use this in an interrupt/BH |
170 | usb_sndctrlpipe(cs->hw.usb->udev, 0), 7, 0x41, | 163 | r = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 7, 0x41, |
171 | (val & 0xff) | ((mask & 0xff) << 8), 0, | 164 | (val & 0xff) | ((mask & 0xff) << 8), 0, |
172 | NULL, 0, 2000 /*timeout??*/); // don't use this in an interrupt/BH | 165 | NULL, 0, 2000 /* timeout? */); |
173 | if (r < 0) | 166 | if (r < 0) |
174 | return r; | 167 | return r; |
175 | //.. | 168 | //.. |
@@ -178,30 +171,29 @@ static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state, | |||
178 | 171 | ||
179 | static int set_value(struct cardstate *cs, u8 req, u16 val) | 172 | static int set_value(struct cardstate *cs, u8 req, u16 val) |
180 | { | 173 | { |
174 | struct usb_device *udev = cs->hw.usb->udev; | ||
181 | int r, r2; | 175 | int r, r2; |
182 | 176 | ||
183 | dbg(DEBUG_USBREQ, "request %02x (%04x)", (unsigned)req, (unsigned)val); | 177 | gig_dbg(DEBUG_USBREQ, "request %02x (%04x)", |
184 | r = usb_control_msg(cs->hw.usb->udev, | 178 | (unsigned)req, (unsigned)val); |
185 | usb_sndctrlpipe(cs->hw.usb->udev, 0), 0x12, 0x41, | 179 | r = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x12, 0x41, |
186 | 0xf /*?*/, 0, | 180 | 0xf /*?*/, 0, NULL, 0, 2000 /*?*/); |
187 | NULL, 0, 2000 /*?*/); /* no idea, what this does */ | 181 | /* no idea what this does */ |
188 | if (r < 0) { | 182 | if (r < 0) { |
189 | err("error %d on request 0x12", -r); | 183 | dev_err(&udev->dev, "error %d on request 0x12\n", -r); |
190 | return r; | 184 | return r; |
191 | } | 185 | } |
192 | 186 | ||
193 | r = usb_control_msg(cs->hw.usb->udev, | 187 | r = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), req, 0x41, |
194 | usb_sndctrlpipe(cs->hw.usb->udev, 0), req, 0x41, | 188 | val, 0, NULL, 0, 2000 /*?*/); |
195 | val, 0, | ||
196 | NULL, 0, 2000 /*?*/); | ||
197 | if (r < 0) | 189 | if (r < 0) |
198 | err("error %d on request 0x%02x", -r, (unsigned)req); | 190 | dev_err(&udev->dev, "error %d on request 0x%02x\n", |
191 | -r, (unsigned)req); | ||
199 | 192 | ||
200 | r2 = usb_control_msg(cs->hw.usb->udev, | 193 | r2 = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x19, 0x41, |
201 | usb_sndctrlpipe(cs->hw.usb->udev, 0), 0x19, 0x41, | 194 | 0, 0, cs->hw.usb->bchars, 6, 2000 /*?*/); |
202 | 0, 0, cs->hw.usb->bchars, 6, 2000 /*?*/); | ||
203 | if (r2 < 0) | 195 | if (r2 < 0) |
204 | err("error %d on request 0x19", -r2); | 196 | dev_err(&udev->dev, "error %d on request 0x19\n", -r2); |
205 | 197 | ||
206 | return r < 0 ? r : (r2 < 0 ? r2 : 0); | 198 | return r < 0 ? r : (r2 < 0 ? r2 : 0); |
207 | } | 199 | } |
@@ -229,8 +221,8 @@ static int gigaset_baud_rate(struct cardstate *cs, unsigned cflag) | |||
229 | case B115200: rate = 115200; break; | 221 | case B115200: rate = 115200; break; |
230 | default: | 222 | default: |
231 | rate = 9600; | 223 | rate = 9600; |
232 | err("unsupported baudrate request 0x%x," | 224 | dev_err(cs->dev, "unsupported baudrate request 0x%x," |
233 | " using default of B9600", cflag); | 225 | " using default of B9600\n", cflag); |
234 | } | 226 | } |
235 | 227 | ||
236 | val = 0x383fff / rate + 1; | 228 | val = 0x383fff / rate + 1; |
@@ -259,7 +251,7 @@ static int gigaset_set_line_ctrl(struct cardstate *cs, unsigned cflag) | |||
259 | case CS8: | 251 | case CS8: |
260 | val |= 8 << 8; break; | 252 | val |= 8 << 8; break; |
261 | default: | 253 | default: |
262 | err("CSIZE was not CS5-CS8, using default of 8"); | 254 | dev_err(cs->dev, "CSIZE was not CS5-CS8, using default of 8\n"); |
263 | val |= 8 << 8; | 255 | val |= 8 << 8; |
264 | break; | 256 | break; |
265 | } | 257 | } |
@@ -277,7 +269,7 @@ static int gigaset_set_line_ctrl(struct cardstate *cs, unsigned cflag) | |||
277 | 269 | ||
278 | #else | 270 | #else |
279 | static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state, | 271 | static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state, |
280 | unsigned new_state) | 272 | unsigned new_state) |
281 | { | 273 | { |
282 | return -EINVAL; | 274 | return -EINVAL; |
283 | } | 275 | } |
@@ -309,15 +301,12 @@ static int gigaset_close_bchannel(struct bc_state *bcs) | |||
309 | return 0; | 301 | return 0; |
310 | } | 302 | } |
311 | 303 | ||
312 | //void send_ack_to_LL(void *data); | ||
313 | static int write_modem(struct cardstate *cs); | 304 | static int write_modem(struct cardstate *cs); |
314 | static int send_cb(struct cardstate *cs, struct cmdbuf_t *cb); | 305 | static int send_cb(struct cardstate *cs, struct cmdbuf_t *cb); |
315 | 306 | ||
316 | 307 | ||
317 | /* Handling of send queue. If there is already a skb opened, put data to | 308 | /* Write tasklet handler: Continue sending current skb, or send command, or |
318 | * the transfer buffer by calling "write_modem". Otherwise take a new skb out of the queue. | 309 | * start sending an skb from the send queue. |
319 | * This function will be called by the ISR via "transmit_chars" (USB: B-Channel Bulk callback handler | ||
320 | * via immediate task queue) or by writebuf_from_LL if the LL wants to transmit data. | ||
321 | */ | 310 | */ |
322 | static void gigaset_modem_fill(unsigned long data) | 311 | static void gigaset_modem_fill(unsigned long data) |
323 | { | 312 | { |
@@ -327,10 +316,10 @@ static void gigaset_modem_fill(unsigned long data) | |||
327 | unsigned long flags; | 316 | unsigned long flags; |
328 | int again; | 317 | int again; |
329 | 318 | ||
330 | dbg(DEBUG_OUTPUT, "modem_fill"); | 319 | gig_dbg(DEBUG_OUTPUT, "modem_fill"); |
331 | 320 | ||
332 | if (atomic_read(&cs->hw.usb->busy)) { | 321 | if (atomic_read(&cs->hw.usb->busy)) { |
333 | dbg(DEBUG_OUTPUT, "modem_fill: busy"); | 322 | gig_dbg(DEBUG_OUTPUT, "modem_fill: busy"); |
334 | return; | 323 | return; |
335 | } | 324 | } |
336 | 325 | ||
@@ -341,26 +330,27 @@ static void gigaset_modem_fill(unsigned long data) | |||
341 | cb = cs->cmdbuf; | 330 | cb = cs->cmdbuf; |
342 | spin_unlock_irqrestore(&cs->cmdlock, flags); | 331 | spin_unlock_irqrestore(&cs->cmdlock, flags); |
343 | if (cb) { /* commands to send? */ | 332 | if (cb) { /* commands to send? */ |
344 | dbg(DEBUG_OUTPUT, "modem_fill: cb"); | 333 | gig_dbg(DEBUG_OUTPUT, "modem_fill: cb"); |
345 | if (send_cb(cs, cb) < 0) { | 334 | if (send_cb(cs, cb) < 0) { |
346 | dbg(DEBUG_OUTPUT, | 335 | gig_dbg(DEBUG_OUTPUT, |
347 | "modem_fill: send_cb failed"); | 336 | "modem_fill: send_cb failed"); |
348 | again = 1; /* no callback will be called! */ | 337 | again = 1; /* no callback will be |
338 | called! */ | ||
349 | } | 339 | } |
350 | } else { /* skbs to send? */ | 340 | } else { /* skbs to send? */ |
351 | bcs->tx_skb = skb_dequeue(&bcs->squeue); | 341 | bcs->tx_skb = skb_dequeue(&bcs->squeue); |
352 | if (bcs->tx_skb) | 342 | if (bcs->tx_skb) |
353 | dbg(DEBUG_INTR, | 343 | gig_dbg(DEBUG_INTR, |
354 | "Dequeued skb (Adr: %lx)!", | 344 | "Dequeued skb (Adr: %lx)!", |
355 | (unsigned long) bcs->tx_skb); | 345 | (unsigned long) bcs->tx_skb); |
356 | } | 346 | } |
357 | } | 347 | } |
358 | 348 | ||
359 | if (bcs->tx_skb) { | 349 | if (bcs->tx_skb) { |
360 | dbg(DEBUG_OUTPUT, "modem_fill: tx_skb"); | 350 | gig_dbg(DEBUG_OUTPUT, "modem_fill: tx_skb"); |
361 | if (write_modem(cs) < 0) { | 351 | if (write_modem(cs) < 0) { |
362 | dbg(DEBUG_OUTPUT, | 352 | gig_dbg(DEBUG_OUTPUT, |
363 | "modem_fill: write_modem failed"); | 353 | "modem_fill: write_modem failed"); |
364 | // FIXME should we tell the LL? | 354 | // FIXME should we tell the LL? |
365 | again = 1; /* no callback will be called! */ | 355 | again = 1; /* no callback will be called! */ |
366 | } | 356 | } |
@@ -371,88 +361,85 @@ static void gigaset_modem_fill(unsigned long data) | |||
371 | /** | 361 | /** |
372 | * gigaset_read_int_callback | 362 | * gigaset_read_int_callback |
373 | * | 363 | * |
374 | * It is called if the data was received from the device. This is almost similiar to | 364 | * It is called if the data was received from the device. |
375 | * the interrupt service routine in the serial device. | ||
376 | */ | 365 | */ |
377 | static void gigaset_read_int_callback(struct urb *urb, struct pt_regs *regs) | 366 | static void gigaset_read_int_callback(struct urb *urb, struct pt_regs *regs) |
378 | { | 367 | { |
368 | struct inbuf_t *inbuf = urb->context; | ||
369 | struct cardstate *cs = inbuf->cs; | ||
379 | int resubmit = 0; | 370 | int resubmit = 0; |
380 | int r; | 371 | int r; |
381 | struct cardstate *cs; | ||
382 | unsigned numbytes; | 372 | unsigned numbytes; |
383 | unsigned char *src; | 373 | unsigned char *src; |
384 | //unsigned long flags; | 374 | unsigned long flags; |
385 | struct inbuf_t *inbuf; | ||
386 | |||
387 | IFNULLRET(urb); | ||
388 | inbuf = (struct inbuf_t *) urb->context; | ||
389 | IFNULLRET(inbuf); | ||
390 | //spin_lock_irqsave(&inbuf->lock, flags); | ||
391 | cs = inbuf->cs; | ||
392 | IFNULLGOTO(cs, exit); | ||
393 | IFNULLGOTO(cardstate, exit); | ||
394 | |||
395 | if (!atomic_read(&cs->connected)) { | ||
396 | err("%s: disconnected", __func__); | ||
397 | goto exit; | ||
398 | } | ||
399 | 375 | ||
400 | if (!urb->status) { | 376 | if (!urb->status) { |
377 | if (!cs->connected) { | ||
378 | err("%s: disconnected", __func__); /* should never happen */ | ||
379 | return; | ||
380 | } | ||
381 | |||
401 | numbytes = urb->actual_length; | 382 | numbytes = urb->actual_length; |
402 | 383 | ||
403 | if (numbytes) { | 384 | if (numbytes) { |
404 | src = inbuf->rcvbuf; | 385 | src = inbuf->rcvbuf; |
405 | if (unlikely(*src)) | 386 | if (unlikely(*src)) |
406 | warn("%s: There was no leading 0, but 0x%02x!", | 387 | dev_warn(cs->dev, |
407 | __func__, (unsigned) *src); | 388 | "%s: There was no leading 0, but 0x%02x!\n", |
389 | __func__, (unsigned) *src); | ||
408 | ++src; /* skip leading 0x00 */ | 390 | ++src; /* skip leading 0x00 */ |
409 | --numbytes; | 391 | --numbytes; |
410 | if (gigaset_fill_inbuf(inbuf, src, numbytes)) { | 392 | if (gigaset_fill_inbuf(inbuf, src, numbytes)) { |
411 | dbg(DEBUG_INTR, "%s-->BH", __func__); | 393 | gig_dbg(DEBUG_INTR, "%s-->BH", __func__); |
412 | gigaset_schedule_event(inbuf->cs); | 394 | gigaset_schedule_event(inbuf->cs); |
413 | } | 395 | } |
414 | } else | 396 | } else |
415 | dbg(DEBUG_INTR, "Received zero block length"); | 397 | gig_dbg(DEBUG_INTR, "Received zero block length"); |
416 | resubmit = 1; | 398 | resubmit = 1; |
417 | } else { | 399 | } else { |
418 | /* The urb might have been killed. */ | 400 | /* The urb might have been killed. */ |
419 | dbg(DEBUG_ANY, "%s - nonzero read bulk status received: %d", | 401 | gig_dbg(DEBUG_ANY, "%s - nonzero read bulk status received: %d", |
420 | __func__, urb->status); | 402 | __func__, urb->status); |
421 | if (urb->status != -ENOENT) /* not killed */ | 403 | if (urb->status != -ENOENT) { /* not killed */ |
404 | if (!cs->connected) { | ||
405 | err("%s: disconnected", __func__); /* should never happen */ | ||
406 | return; | ||
407 | } | ||
422 | resubmit = 1; | 408 | resubmit = 1; |
409 | } | ||
423 | } | 410 | } |
424 | exit: | 411 | |
425 | //spin_unlock_irqrestore(&inbuf->lock, flags); | ||
426 | if (resubmit) { | 412 | if (resubmit) { |
427 | r = usb_submit_urb(urb, SLAB_ATOMIC); | 413 | spin_lock_irqsave(&cs->lock, flags); |
414 | r = cs->connected ? usb_submit_urb(urb, SLAB_ATOMIC) : -ENODEV; | ||
415 | spin_unlock_irqrestore(&cs->lock, flags); | ||
428 | if (r) | 416 | if (r) |
429 | err("error %d when resubmitting urb.", -r); | 417 | dev_err(cs->dev, "error %d when resubmitting urb.\n", |
418 | -r); | ||
430 | } | 419 | } |
431 | } | 420 | } |
432 | 421 | ||
433 | 422 | ||
434 | /* This callback routine is called when data was transmitted to a B-Channel. | 423 | /* This callback routine is called when data was transmitted to the device. */ |
435 | * Therefore it has to check if there is still data to transmit. This | ||
436 | * happens by calling modem_fill via task queue. | ||
437 | * | ||
438 | */ | ||
439 | static void gigaset_write_bulk_callback(struct urb *urb, struct pt_regs *regs) | 424 | static void gigaset_write_bulk_callback(struct urb *urb, struct pt_regs *regs) |
440 | { | 425 | { |
441 | struct cardstate *cs = (struct cardstate *) urb->context; | 426 | struct cardstate *cs = urb->context; |
427 | unsigned long flags; | ||
442 | 428 | ||
443 | IFNULLRET(cs); | ||
444 | #ifdef CONFIG_GIGASET_DEBUG | ||
445 | if (!atomic_read(&cs->connected)) { | ||
446 | err("%s:not connected", __func__); | ||
447 | return; | ||
448 | } | ||
449 | #endif | ||
450 | if (urb->status) | 429 | if (urb->status) |
451 | err("bulk transfer failed (status %d)", -urb->status); /* That's all we can do. Communication problems | 430 | dev_err(cs->dev, "bulk transfer failed (status %d)\n", |
452 | are handeled by timeouts or network protocols */ | 431 | -urb->status); |
432 | /* That's all we can do. Communication problems | ||
433 | are handled by timeouts or network protocols. */ | ||
453 | 434 | ||
454 | atomic_set(&cs->hw.usb->busy, 0); | 435 | spin_lock_irqsave(&cs->lock, flags); |
455 | tasklet_schedule(&cs->write_tasklet); | 436 | if (!cs->connected) { |
437 | err("%s: not connected", __func__); | ||
438 | } else { | ||
439 | atomic_set(&cs->hw.usb->busy, 0); | ||
440 | tasklet_schedule(&cs->write_tasklet); | ||
441 | } | ||
442 | spin_unlock_irqrestore(&cs->lock, flags); | ||
456 | } | 443 | } |
457 | 444 | ||
458 | static int send_cb(struct cardstate *cs, struct cmdbuf_t *cb) | 445 | static int send_cb(struct cardstate *cs, struct cmdbuf_t *cb) |
@@ -469,8 +456,8 @@ static int send_cb(struct cardstate *cs, struct cmdbuf_t *cb) | |||
469 | 456 | ||
470 | spin_lock_irqsave(&cs->cmdlock, flags); | 457 | spin_lock_irqsave(&cs->cmdlock, flags); |
471 | cs->cmdbytes -= cs->curlen; | 458 | cs->cmdbytes -= cs->curlen; |
472 | dbg(DEBUG_OUTPUT, "send_cb: sent %u bytes, %u left", | 459 | gig_dbg(DEBUG_OUTPUT, "send_cb: sent %u bytes, %u left", |
473 | cs->curlen, cs->cmdbytes); | 460 | cs->curlen, cs->cmdbytes); |
474 | cs->cmdbuf = cb = cb->next; | 461 | cs->cmdbuf = cb = cb->next; |
475 | if (cb) { | 462 | if (cb) { |
476 | cb->prev = NULL; | 463 | cb->prev = NULL; |
@@ -487,52 +474,51 @@ static int send_cb(struct cardstate *cs, struct cmdbuf_t *cb) | |||
487 | } | 474 | } |
488 | if (cb) { | 475 | if (cb) { |
489 | count = min(cb->len, ucs->bulk_out_size); | 476 | count = min(cb->len, ucs->bulk_out_size); |
477 | gig_dbg(DEBUG_OUTPUT, "send_cb: send %d bytes", count); | ||
478 | |||
490 | usb_fill_bulk_urb(ucs->bulk_out_urb, ucs->udev, | 479 | usb_fill_bulk_urb(ucs->bulk_out_urb, ucs->udev, |
491 | usb_sndbulkpipe(ucs->udev, | 480 | usb_sndbulkpipe(ucs->udev, |
492 | ucs->bulk_out_endpointAddr & 0x0f), | 481 | ucs->bulk_out_endpointAddr & 0x0f), |
493 | cb->buf + cb->offset, count, | 482 | cb->buf + cb->offset, count, |
494 | gigaset_write_bulk_callback, cs); | 483 | gigaset_write_bulk_callback, cs); |
495 | 484 | ||
496 | cb->offset += count; | 485 | cb->offset += count; |
497 | cb->len -= count; | 486 | cb->len -= count; |
498 | atomic_set(&ucs->busy, 1); | 487 | atomic_set(&ucs->busy, 1); |
499 | dbg(DEBUG_OUTPUT, "send_cb: send %d bytes", count); | ||
500 | 488 | ||
501 | status = usb_submit_urb(ucs->bulk_out_urb, SLAB_ATOMIC); | 489 | spin_lock_irqsave(&cs->lock, flags); |
490 | status = cs->connected ? usb_submit_urb(ucs->bulk_out_urb, SLAB_ATOMIC) : -ENODEV; | ||
491 | spin_unlock_irqrestore(&cs->lock, flags); | ||
492 | |||
502 | if (status) { | 493 | if (status) { |
503 | atomic_set(&ucs->busy, 0); | 494 | atomic_set(&ucs->busy, 0); |
504 | err("could not submit urb (error %d).", | 495 | err("could not submit urb (error %d)\n", |
505 | -status); | 496 | -status); |
506 | cb->len = 0; /* skip urb => remove cb+wakeup in next loop cycle */ | 497 | cb->len = 0; /* skip urb => remove cb+wakeup |
498 | in next loop cycle */ | ||
507 | } | 499 | } |
508 | } | 500 | } |
509 | } while (cb && status); /* bei Fehler naechster Befehl //FIXME: ist das OK? */ | 501 | } while (cb && status); /* next command on error */ |
510 | 502 | ||
511 | return status; | 503 | return status; |
512 | } | 504 | } |
513 | 505 | ||
514 | /* Write string into transbuf and send it to modem. | 506 | /* Send command to device. */ |
515 | */ | ||
516 | static int gigaset_write_cmd(struct cardstate *cs, const unsigned char *buf, | 507 | static int gigaset_write_cmd(struct cardstate *cs, const unsigned char *buf, |
517 | int len, struct tasklet_struct *wake_tasklet) | 508 | int len, struct tasklet_struct *wake_tasklet) |
518 | { | 509 | { |
519 | struct cmdbuf_t *cb; | 510 | struct cmdbuf_t *cb; |
520 | unsigned long flags; | 511 | unsigned long flags; |
521 | 512 | ||
522 | gigaset_dbg_buffer(atomic_read(&cs->mstate) != MS_LOCKED ? | 513 | gigaset_dbg_buffer(atomic_read(&cs->mstate) != MS_LOCKED ? |
523 | DEBUG_TRANSCMD : DEBUG_LOCKCMD, | 514 | DEBUG_TRANSCMD : DEBUG_LOCKCMD, |
524 | "CMD Transmit", len, buf, 0); | 515 | "CMD Transmit", len, buf); |
525 | |||
526 | if (!atomic_read(&cs->connected)) { | ||
527 | err("%s: not connected", __func__); | ||
528 | return -ENODEV; | ||
529 | } | ||
530 | 516 | ||
531 | if (len <= 0) | 517 | if (len <= 0) |
532 | return 0; | 518 | return 0; |
533 | 519 | ||
534 | if (!(cb = kmalloc(sizeof(struct cmdbuf_t) + len, GFP_ATOMIC))) { | 520 | if (!(cb = kmalloc(sizeof(struct cmdbuf_t) + len, GFP_ATOMIC))) { |
535 | err("%s: out of memory", __func__); | 521 | dev_err(cs->dev, "%s: out of memory\n", __func__); |
536 | return -ENOMEM; | 522 | return -ENOMEM; |
537 | } | 523 | } |
538 | 524 | ||
@@ -554,7 +540,10 @@ static int gigaset_write_cmd(struct cardstate *cs, const unsigned char *buf, | |||
554 | cs->lastcmdbuf = cb; | 540 | cs->lastcmdbuf = cb; |
555 | spin_unlock_irqrestore(&cs->cmdlock, flags); | 541 | spin_unlock_irqrestore(&cs->cmdlock, flags); |
556 | 542 | ||
557 | tasklet_schedule(&cs->write_tasklet); | 543 | spin_lock_irqsave(&cs->lock, flags); |
544 | if (cs->connected) | ||
545 | tasklet_schedule(&cs->write_tasklet); | ||
546 | spin_unlock_irqrestore(&cs->lock, flags); | ||
558 | return len; | 547 | return len; |
559 | } | 548 | } |
560 | 549 | ||
@@ -578,11 +567,12 @@ static int gigaset_chars_in_buffer(struct cardstate *cs) | |||
578 | static int gigaset_brkchars(struct cardstate *cs, const unsigned char buf[6]) | 567 | static int gigaset_brkchars(struct cardstate *cs, const unsigned char buf[6]) |
579 | { | 568 | { |
580 | #ifdef CONFIG_GIGASET_UNDOCREQ | 569 | #ifdef CONFIG_GIGASET_UNDOCREQ |
581 | gigaset_dbg_buffer(DEBUG_USBREQ, "brkchars", 6, buf, 0); | 570 | struct usb_device *udev = cs->hw.usb->udev; |
571 | |||
572 | gigaset_dbg_buffer(DEBUG_USBREQ, "brkchars", 6, buf); | ||
582 | memcpy(cs->hw.usb->bchars, buf, 6); | 573 | memcpy(cs->hw.usb->bchars, buf, 6); |
583 | return usb_control_msg(cs->hw.usb->udev, | 574 | return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x19, 0x41, |
584 | usb_sndctrlpipe(cs->hw.usb->udev, 0), 0x19, 0x41, | 575 | 0, 0, &buf, 6, 2000); |
585 | 0, 0, &buf, 6, 2000); | ||
586 | #else | 576 | #else |
587 | return -EINVAL; | 577 | return -EINVAL; |
588 | #endif | 578 | #endif |
@@ -604,7 +594,6 @@ static int gigaset_initbcshw(struct bc_state *bcs) | |||
604 | if (!bcs->hw.usb) | 594 | if (!bcs->hw.usb) |
605 | return 0; | 595 | return 0; |
606 | 596 | ||
607 | //bcs->hw.usb->trans_flg = READY_TO_TRNSMIT; /* B-Channel ready to transmit */ | ||
608 | return 1; | 597 | return 1; |
609 | } | 598 | } |
610 | 599 | ||
@@ -614,7 +603,6 @@ static void gigaset_reinitbcshw(struct bc_state *bcs) | |||
614 | 603 | ||
615 | static void gigaset_freecshw(struct cardstate *cs) | 604 | static void gigaset_freecshw(struct cardstate *cs) |
616 | { | 605 | { |
617 | //FIXME | ||
618 | tasklet_kill(&cs->write_tasklet); | 606 | tasklet_kill(&cs->write_tasklet); |
619 | kfree(cs->hw.usb); | 607 | kfree(cs->hw.usb); |
620 | } | 608 | } |
@@ -639,33 +627,21 @@ static int gigaset_initcshw(struct cardstate *cs) | |||
639 | //ucs->urb_cmd_out = NULL; | 627 | //ucs->urb_cmd_out = NULL; |
640 | ucs->read_urb = NULL; | 628 | ucs->read_urb = NULL; |
641 | tasklet_init(&cs->write_tasklet, | 629 | tasklet_init(&cs->write_tasklet, |
642 | &gigaset_modem_fill, (unsigned long) cs); | 630 | &gigaset_modem_fill, (unsigned long) cs); |
643 | 631 | ||
644 | return 1; | 632 | return 1; |
645 | } | 633 | } |
646 | 634 | ||
647 | /* Writes the data of the current open skb into the modem. | 635 | /* Send data from current skb to the device. */ |
648 | * We have to protect against multiple calls until the | ||
649 | * callback handler () is called , due to the fact that we | ||
650 | * are just allowed to send data once to an endpoint. Therefore | ||
651 | * we using "trans_flg" to synchonize ... | ||
652 | */ | ||
653 | static int write_modem(struct cardstate *cs) | 636 | static int write_modem(struct cardstate *cs) |
654 | { | 637 | { |
655 | int ret; | 638 | int ret = 0; |
656 | int count; | 639 | int count; |
657 | struct bc_state *bcs = &cs->bcs[0]; /* only one channel */ | 640 | struct bc_state *bcs = &cs->bcs[0]; /* only one channel */ |
658 | struct usb_cardstate *ucs = cs->hw.usb; | 641 | struct usb_cardstate *ucs = cs->hw.usb; |
659 | //unsigned long flags; | 642 | unsigned long flags; |
660 | |||
661 | IFNULLRETVAL(bcs->tx_skb, -EINVAL); | ||
662 | |||
663 | dbg(DEBUG_WRITE, "len: %d...", bcs->tx_skb->len); | ||
664 | 643 | ||
665 | ret = -ENODEV; | 644 | gig_dbg(DEBUG_WRITE, "len: %d...", bcs->tx_skb->len); |
666 | IFNULLGOTO(ucs->bulk_out_buffer, error); | ||
667 | IFNULLGOTO(ucs->bulk_out_urb, error); | ||
668 | ret = 0; | ||
669 | 645 | ||
670 | if (!bcs->tx_skb->len) { | 646 | if (!bcs->tx_skb->len) { |
671 | dev_kfree_skb_any(bcs->tx_skb); | 647 | dev_kfree_skb_any(bcs->tx_skb); |
@@ -679,40 +655,42 @@ static int write_modem(struct cardstate *cs) | |||
679 | count = min(bcs->tx_skb->len, (unsigned) ucs->bulk_out_size); | 655 | count = min(bcs->tx_skb->len, (unsigned) ucs->bulk_out_size); |
680 | memcpy(ucs->bulk_out_buffer, bcs->tx_skb->data, count); | 656 | memcpy(ucs->bulk_out_buffer, bcs->tx_skb->data, count); |
681 | skb_pull(bcs->tx_skb, count); | 657 | skb_pull(bcs->tx_skb, count); |
682 | |||
683 | usb_fill_bulk_urb(ucs->bulk_out_urb, ucs->udev, | ||
684 | usb_sndbulkpipe(ucs->udev, | ||
685 | ucs->bulk_out_endpointAddr & 0x0f), | ||
686 | ucs->bulk_out_buffer, count, | ||
687 | gigaset_write_bulk_callback, cs); | ||
688 | atomic_set(&ucs->busy, 1); | 658 | atomic_set(&ucs->busy, 1); |
689 | dbg(DEBUG_OUTPUT, "write_modem: send %d bytes", count); | 659 | gig_dbg(DEBUG_OUTPUT, "write_modem: send %d bytes", count); |
660 | |||
661 | spin_lock_irqsave(&cs->lock, flags); | ||
662 | if (cs->connected) { | ||
663 | usb_fill_bulk_urb(ucs->bulk_out_urb, ucs->udev, | ||
664 | usb_sndbulkpipe(ucs->udev, | ||
665 | ucs->bulk_out_endpointAddr & 0x0f), | ||
666 | ucs->bulk_out_buffer, count, | ||
667 | gigaset_write_bulk_callback, cs); | ||
668 | ret = usb_submit_urb(ucs->bulk_out_urb, SLAB_ATOMIC); | ||
669 | } else { | ||
670 | ret = -ENODEV; | ||
671 | } | ||
672 | spin_unlock_irqrestore(&cs->lock, flags); | ||
690 | 673 | ||
691 | ret = usb_submit_urb(ucs->bulk_out_urb, SLAB_ATOMIC); | ||
692 | if (ret) { | 674 | if (ret) { |
693 | err("could not submit urb (error %d).", -ret); | 675 | err("could not submit urb (error %d)\n", -ret); |
694 | atomic_set(&ucs->busy, 0); | 676 | atomic_set(&ucs->busy, 0); |
695 | } | 677 | } |
678 | |||
696 | if (!bcs->tx_skb->len) { | 679 | if (!bcs->tx_skb->len) { |
697 | /* skb sent completely */ | 680 | /* skb sent completely */ |
698 | gigaset_skb_sent(bcs, bcs->tx_skb); //FIXME also, when ret<0? | 681 | gigaset_skb_sent(bcs, bcs->tx_skb); //FIXME also, when ret<0? |
699 | 682 | ||
700 | dbg(DEBUG_INTR, | 683 | gig_dbg(DEBUG_INTR, "kfree skb (Adr: %lx)!", |
701 | "kfree skb (Adr: %lx)!", (unsigned long) bcs->tx_skb); | 684 | (unsigned long) bcs->tx_skb); |
702 | dev_kfree_skb_any(bcs->tx_skb); | 685 | dev_kfree_skb_any(bcs->tx_skb); |
703 | bcs->tx_skb = NULL; | 686 | bcs->tx_skb = NULL; |
704 | } | 687 | } |
705 | 688 | ||
706 | return ret; | 689 | return ret; |
707 | error: | ||
708 | dev_kfree_skb_any(bcs->tx_skb); | ||
709 | bcs->tx_skb = NULL; | ||
710 | return ret; | ||
711 | |||
712 | } | 690 | } |
713 | 691 | ||
714 | static int gigaset_probe(struct usb_interface *interface, | 692 | static int gigaset_probe(struct usb_interface *interface, |
715 | const struct usb_device_id *id) | 693 | const struct usb_device_id *id) |
716 | { | 694 | { |
717 | int retval; | 695 | int retval; |
718 | struct usb_device *udev = interface_to_usbdev(interface); | 696 | struct usb_device *udev = interface_to_usbdev(interface); |
@@ -720,16 +698,14 @@ static int gigaset_probe(struct usb_interface *interface, | |||
720 | struct usb_host_interface *hostif; | 698 | struct usb_host_interface *hostif; |
721 | struct cardstate *cs = NULL; | 699 | struct cardstate *cs = NULL; |
722 | struct usb_cardstate *ucs = NULL; | 700 | struct usb_cardstate *ucs = NULL; |
723 | //struct usb_interface_descriptor *iface_desc; | ||
724 | struct usb_endpoint_descriptor *endpoint; | 701 | struct usb_endpoint_descriptor *endpoint; |
725 | //isdn_ctrl command; | ||
726 | int buffer_size; | 702 | int buffer_size; |
727 | int alt; | 703 | int alt; |
728 | //unsigned long flags; | ||
729 | 704 | ||
730 | info("%s: Check if device matches .. (Vendor: 0x%x, Product: 0x%x)", | 705 | gig_dbg(DEBUG_ANY, |
731 | __func__, le16_to_cpu(udev->descriptor.idVendor), | 706 | "%s: Check if device matches .. (Vendor: 0x%x, Product: 0x%x)", |
732 | le16_to_cpu(udev->descriptor.idProduct)); | 707 | __func__, le16_to_cpu(udev->descriptor.idVendor), |
708 | le16_to_cpu(udev->descriptor.idProduct)); | ||
733 | 709 | ||
734 | retval = -ENODEV; //FIXME | 710 | retval = -ENODEV; //FIXME |
735 | 711 | ||
@@ -744,7 +720,7 @@ static int gigaset_probe(struct usb_interface *interface, | |||
744 | ifnum = hostif->desc.bInterfaceNumber; // FIXME ? | 720 | ifnum = hostif->desc.bInterfaceNumber; // FIXME ? |
745 | 721 | ||
746 | if (alt != 0 || ifnum != 0) { | 722 | if (alt != 0 || ifnum != 0) { |
747 | warn("ifnum %d, alt %d", ifnum, alt); | 723 | dev_warn(&udev->dev, "ifnum %d, alt %d\n", ifnum, alt); |
748 | return -ENODEV; | 724 | return -ENODEV; |
749 | } | 725 | } |
750 | 726 | ||
@@ -752,42 +728,29 @@ static int gigaset_probe(struct usb_interface *interface, | |||
752 | * | 728 | * |
753 | */ | 729 | */ |
754 | if (hostif->desc.bInterfaceClass != 255) { | 730 | if (hostif->desc.bInterfaceClass != 255) { |
755 | info("%s: Device matched, but iface_desc[%d]->bInterfaceClass==%d !", | 731 | dev_info(&udev->dev, |
756 | __func__, ifnum, hostif->desc.bInterfaceClass); | 732 | "%s: Device matched but iface_desc[%d]->bInterfaceClass==%d!\n", |
733 | __func__, ifnum, hostif->desc.bInterfaceClass); | ||
757 | return -ENODEV; | 734 | return -ENODEV; |
758 | } | 735 | } |
759 | 736 | ||
760 | info("%s: Device matched ... !", __func__); | 737 | dev_info(&udev->dev, "%s: Device matched ... !\n", __func__); |
761 | 738 | ||
762 | cs = gigaset_getunassignedcs(driver); | 739 | cs = gigaset_getunassignedcs(driver); |
763 | if (!cs) { | 740 | if (!cs) { |
764 | warn("No free cardstate!"); | 741 | dev_warn(&udev->dev, "no free cardstate\n"); |
765 | return -ENODEV; | 742 | return -ENODEV; |
766 | } | 743 | } |
767 | ucs = cs->hw.usb; | 744 | ucs = cs->hw.usb; |
768 | 745 | ||
769 | #if 0 | 746 | /* save off device structure ptrs for later use */ |
770 | if (usb_set_configuration(udev, udev->config[0].desc.bConfigurationValue) < 0) { | 747 | usb_get_dev(udev); |
771 | warn("set_configuration failed"); | 748 | ucs->udev = udev; |
772 | goto error; | 749 | ucs->interface = interface; |
773 | } | 750 | cs->dev = &interface->dev; |
774 | |||
775 | |||
776 | if (usb_set_interface(udev, ifnum/*==0*/, alt/*==0*/) < 0) { | ||
777 | warn("usb_set_interface failed, device %d interface %d altsetting %d", | ||
778 | udev->devnum, ifnum, alt); | ||
779 | goto error; | ||
780 | } | ||
781 | #endif | ||
782 | 751 | ||
783 | /* set up the endpoint information */ | 752 | /* save address of controller structure */ |
784 | /* check out the endpoints */ | 753 | usb_set_intfdata(interface, cs); // dev_set_drvdata(&interface->dev, cs); |
785 | /* We will get 2 endpoints: One for sending commands to the device (bulk out) and one to | ||
786 | * poll messages from the device(int in). | ||
787 | * Therefore we will have an almost similiar situation as with our serial port handler. | ||
788 | * If an connection will be established, we will have to create data in/out pipes | ||
789 | * dynamically... | ||
790 | */ | ||
791 | 754 | ||
792 | endpoint = &hostif->endpoint[0].desc; | 755 | endpoint = &hostif->endpoint[0].desc; |
793 | 756 | ||
@@ -796,14 +759,14 @@ static int gigaset_probe(struct usb_interface *interface, | |||
796 | ucs->bulk_out_endpointAddr = endpoint->bEndpointAddress; | 759 | ucs->bulk_out_endpointAddr = endpoint->bEndpointAddress; |
797 | ucs->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL); | 760 | ucs->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL); |
798 | if (!ucs->bulk_out_buffer) { | 761 | if (!ucs->bulk_out_buffer) { |
799 | err("Couldn't allocate bulk_out_buffer"); | 762 | dev_err(cs->dev, "Couldn't allocate bulk_out_buffer\n"); |
800 | retval = -ENOMEM; | 763 | retval = -ENOMEM; |
801 | goto error; | 764 | goto error; |
802 | } | 765 | } |
803 | 766 | ||
804 | ucs->bulk_out_urb = usb_alloc_urb(0, SLAB_KERNEL); | 767 | ucs->bulk_out_urb = usb_alloc_urb(0, SLAB_KERNEL); |
805 | if (!ucs->bulk_out_urb) { | 768 | if (!ucs->bulk_out_urb) { |
806 | err("Couldn't allocate bulk_out_buffer"); | 769 | dev_err(cs->dev, "Couldn't allocate bulk_out_urb\n"); |
807 | retval = -ENOMEM; | 770 | retval = -ENOMEM; |
808 | goto error; | 771 | goto error; |
809 | } | 772 | } |
@@ -811,12 +774,10 @@ static int gigaset_probe(struct usb_interface *interface, | |||
811 | endpoint = &hostif->endpoint[1].desc; | 774 | endpoint = &hostif->endpoint[1].desc; |
812 | 775 | ||
813 | atomic_set(&ucs->busy, 0); | 776 | atomic_set(&ucs->busy, 0); |
814 | ucs->udev = udev; | ||
815 | ucs->interface = interface; | ||
816 | 777 | ||
817 | ucs->read_urb = usb_alloc_urb(0, SLAB_KERNEL); | 778 | ucs->read_urb = usb_alloc_urb(0, SLAB_KERNEL); |
818 | if (!ucs->read_urb) { | 779 | if (!ucs->read_urb) { |
819 | err("No free urbs available"); | 780 | dev_err(cs->dev, "No free urbs available\n"); |
820 | retval = -ENOMEM; | 781 | retval = -ENOMEM; |
821 | goto error; | 782 | goto error; |
822 | } | 783 | } |
@@ -825,38 +786,33 @@ static int gigaset_probe(struct usb_interface *interface, | |||
825 | ucs->int_in_endpointAddr = endpoint->bEndpointAddress; | 786 | ucs->int_in_endpointAddr = endpoint->bEndpointAddress; |
826 | cs->inbuf[0].rcvbuf = kmalloc(buffer_size, GFP_KERNEL); | 787 | cs->inbuf[0].rcvbuf = kmalloc(buffer_size, GFP_KERNEL); |
827 | if (!cs->inbuf[0].rcvbuf) { | 788 | if (!cs->inbuf[0].rcvbuf) { |
828 | err("Couldn't allocate rcvbuf"); | 789 | dev_err(cs->dev, "Couldn't allocate rcvbuf\n"); |
829 | retval = -ENOMEM; | 790 | retval = -ENOMEM; |
830 | goto error; | 791 | goto error; |
831 | } | 792 | } |
832 | /* Fill the interrupt urb and send it to the core */ | 793 | /* Fill the interrupt urb and send it to the core */ |
833 | usb_fill_int_urb(ucs->read_urb, udev, | 794 | usb_fill_int_urb(ucs->read_urb, udev, |
834 | usb_rcvintpipe(udev, | 795 | usb_rcvintpipe(udev, |
835 | endpoint->bEndpointAddress & 0x0f), | 796 | endpoint->bEndpointAddress & 0x0f), |
836 | cs->inbuf[0].rcvbuf, buffer_size, | 797 | cs->inbuf[0].rcvbuf, buffer_size, |
837 | gigaset_read_int_callback, | 798 | gigaset_read_int_callback, |
838 | cs->inbuf + 0, endpoint->bInterval); | 799 | cs->inbuf + 0, endpoint->bInterval); |
839 | 800 | ||
840 | retval = usb_submit_urb(ucs->read_urb, SLAB_KERNEL); | 801 | retval = usb_submit_urb(ucs->read_urb, SLAB_KERNEL); |
841 | if (retval) { | 802 | if (retval) { |
842 | err("Could not submit URB!"); | 803 | dev_err(cs->dev, "Could not submit URB (error %d)\n", -retval); |
843 | goto error; | 804 | goto error; |
844 | } | 805 | } |
845 | 806 | ||
846 | /* tell common part that the device is ready */ | 807 | /* tell common part that the device is ready */ |
847 | if (startmode == SM_LOCKED) | 808 | if (startmode == SM_LOCKED) |
848 | atomic_set(&cs->mstate, MS_LOCKED); | 809 | atomic_set(&cs->mstate, MS_LOCKED); |
810 | |||
849 | if (!gigaset_start(cs)) { | 811 | if (!gigaset_start(cs)) { |
850 | tasklet_kill(&cs->write_tasklet); | 812 | tasklet_kill(&cs->write_tasklet); |
851 | retval = -ENODEV; //FIXME | 813 | retval = -ENODEV; //FIXME |
852 | goto error; | 814 | goto error; |
853 | } | 815 | } |
854 | |||
855 | /* save address of controller structure */ | ||
856 | usb_set_intfdata(interface, cs); | ||
857 | |||
858 | /* set up device sysfs */ | ||
859 | gigaset_init_dev_sysfs(interface); | ||
860 | return 0; | 816 | return 0; |
861 | 817 | ||
862 | error: | 818 | error: |
@@ -868,48 +824,45 @@ error: | |||
868 | kfree(cs->inbuf[0].rcvbuf); | 824 | kfree(cs->inbuf[0].rcvbuf); |
869 | if (ucs->read_urb != NULL) | 825 | if (ucs->read_urb != NULL) |
870 | usb_free_urb(ucs->read_urb); | 826 | usb_free_urb(ucs->read_urb); |
827 | usb_set_intfdata(interface, NULL); | ||
871 | ucs->read_urb = ucs->bulk_out_urb = NULL; | 828 | ucs->read_urb = ucs->bulk_out_urb = NULL; |
872 | cs->inbuf[0].rcvbuf = ucs->bulk_out_buffer = NULL; | 829 | cs->inbuf[0].rcvbuf = ucs->bulk_out_buffer = NULL; |
830 | usb_put_dev(ucs->udev); | ||
831 | ucs->udev = NULL; | ||
832 | ucs->interface = NULL; | ||
873 | gigaset_unassign(cs); | 833 | gigaset_unassign(cs); |
874 | return retval; | 834 | return retval; |
875 | } | 835 | } |
876 | 836 | ||
877 | /** | ||
878 | * skel_disconnect | ||
879 | */ | ||
880 | static void gigaset_disconnect(struct usb_interface *interface) | 837 | static void gigaset_disconnect(struct usb_interface *interface) |
881 | { | 838 | { |
882 | struct cardstate *cs; | 839 | struct cardstate *cs; |
883 | struct usb_cardstate *ucs; | 840 | struct usb_cardstate *ucs; |
884 | 841 | ||
885 | cs = usb_get_intfdata(interface); | 842 | cs = usb_get_intfdata(interface); |
886 | |||
887 | /* clear device sysfs */ | ||
888 | gigaset_free_dev_sysfs(interface); | ||
889 | |||
890 | usb_set_intfdata(interface, NULL); | ||
891 | ucs = cs->hw.usb; | 843 | ucs = cs->hw.usb; |
892 | usb_kill_urb(ucs->read_urb); | 844 | usb_kill_urb(ucs->read_urb); |
893 | //info("GigaSet USB device #%d will be disconnected", minor); | ||
894 | 845 | ||
895 | gigaset_stop(cs); | 846 | gigaset_stop(cs); |
896 | 847 | ||
848 | usb_set_intfdata(interface, NULL); | ||
897 | tasklet_kill(&cs->write_tasklet); | 849 | tasklet_kill(&cs->write_tasklet); |
898 | 850 | ||
899 | usb_kill_urb(ucs->bulk_out_urb); /* FIXME: nur, wenn noetig */ | 851 | usb_kill_urb(ucs->bulk_out_urb); /* FIXME: only if active? */ |
900 | //usb_kill_urb(ucs->urb_cmd_out); /* FIXME: nur, wenn noetig */ | ||
901 | 852 | ||
902 | kfree(ucs->bulk_out_buffer); | 853 | kfree(ucs->bulk_out_buffer); |
903 | if (ucs->bulk_out_urb != NULL) | 854 | if (ucs->bulk_out_urb != NULL) |
904 | usb_free_urb(ucs->bulk_out_urb); | 855 | usb_free_urb(ucs->bulk_out_urb); |
905 | //if(ucs->urb_cmd_out != NULL) | ||
906 | // usb_free_urb(ucs->urb_cmd_out); | ||
907 | kfree(cs->inbuf[0].rcvbuf); | 856 | kfree(cs->inbuf[0].rcvbuf); |
908 | if (ucs->read_urb != NULL) | 857 | if (ucs->read_urb != NULL) |
909 | usb_free_urb(ucs->read_urb); | 858 | usb_free_urb(ucs->read_urb); |
910 | ucs->read_urb = ucs->bulk_out_urb/*=ucs->urb_cmd_out*/=NULL; | 859 | ucs->read_urb = ucs->bulk_out_urb = NULL; |
911 | cs->inbuf[0].rcvbuf = ucs->bulk_out_buffer = NULL; | 860 | cs->inbuf[0].rcvbuf = ucs->bulk_out_buffer = NULL; |
912 | 861 | ||
862 | usb_put_dev(ucs->udev); | ||
863 | ucs->interface = NULL; | ||
864 | ucs->udev = NULL; | ||
865 | cs->dev = NULL; | ||
913 | gigaset_unassign(cs); | 866 | gigaset_unassign(cs); |
914 | } | 867 | } |
915 | 868 | ||
@@ -942,9 +895,9 @@ static int __init usb_gigaset_init(void) | |||
942 | 895 | ||
943 | /* allocate memory for our driver state and intialize it */ | 896 | /* allocate memory for our driver state and intialize it */ |
944 | if ((driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS, | 897 | if ((driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS, |
945 | GIGASET_MODULENAME, GIGASET_DEVNAME, | 898 | GIGASET_MODULENAME, GIGASET_DEVNAME, |
946 | GIGASET_DEVFSNAME, &ops, | 899 | GIGASET_DEVFSNAME, &ops, |
947 | THIS_MODULE)) == NULL) | 900 | THIS_MODULE)) == NULL) |
948 | goto error; | 901 | goto error; |
949 | 902 | ||
950 | /* allocate memory for our device state and intialize it */ | 903 | /* allocate memory for our device state and intialize it */ |
@@ -981,8 +934,8 @@ error: if (cardstate) | |||
981 | static void __exit usb_gigaset_exit(void) | 934 | static void __exit usb_gigaset_exit(void) |
982 | { | 935 | { |
983 | gigaset_blockdriver(driver); /* => probe will fail | 936 | gigaset_blockdriver(driver); /* => probe will fail |
984 | * => no gigaset_start any more | 937 | * => no gigaset_start any more |
985 | */ | 938 | */ |
986 | 939 | ||
987 | gigaset_shutdown(cardstate); | 940 | gigaset_shutdown(cardstate); |
988 | /* from now on, no isdn callback should be possible */ | 941 | /* from now on, no isdn callback should be possible */ |