1 /* 2 Option Card (PCMCIA to) USB to Serial Driver 3 4 Copyright (C) 2005 Matthias Urlichs <smurf@smurf.noris.de> 5 6 This driver is free software; you can redistribute it and/or modify 7 it under the terms of Version 2 of the GNU General Public License as 8 published by the Free Software Foundation. 9 10 Portions copied from the Keyspan driver by Hugh Blemings <hugh@blemings.org> 11 12 History: 13 14 2005-05-19 v0.1 Initial version, based on incomplete docs 15 and analysis of misbehavior with the standard driver 16 2005-05-20 v0.2 Extended the input buffer to avoid losing 17 random 64-byte chunks of data 18 2005-05-21 v0.3 implemented chars_in_buffer() 19 turned on low_latency 20 simplified the code somewhat 21 2005-05-24 v0.4 option_write() sometimes deadlocked under heavy load 22 removed some dead code 23 added sponsor notice 24 coding style clean-up 25 2005-06-20 v0.4.1 add missing braces :-/ 26 killed end-of-line whitespace 27 2005-07-15 v0.4.2 rename WLAN product to FUSION, add FUSION2 28 2005-09-10 v0.4.3 added HUAWEI E600 card and Audiovox AirCard 29 2005-09-20 v0.4.4 increased recv buffer size: the card sometimes 30 wants to send >2000 bytes. 31 32 Work sponsored by: Sigos GmbH, Germany <info@sigos.de> 33 34 */ 35 36 #define DRIVER_VERSION "v0.4" 37 #define DRIVER_AUTHOR "Matthias Urlichs <smurf@smurf.noris.de>" 38 #define DRIVER_DESC "Option Card (PC-Card to) USB to Serial Driver" 39 40 #include <linux/config.h> 41 #include <linux/kernel.h> 42 #include <linux/jiffies.h> 43 #include <linux/errno.h> 44 #include <linux/tty.h> 45 #include <linux/tty_flip.h> 46 #include <linux/module.h> 47 #include <linux/usb.h> 48 #include "usb-serial.h" 49 50 /* Function prototypes */ 51 static int option_open(struct usb_serial_port *port, struct file *filp); 52 static void option_close(struct usb_serial_port *port, struct file *filp); 53 static int option_startup(struct usb_serial *serial); 54 static void option_shutdown(struct usb_serial *serial); 55 static void option_rx_throttle(struct usb_serial_port *port); 56 static void option_rx_unthrottle(struct usb_serial_port *port); 57 static int option_write_room(struct usb_serial_port *port); 58 59 static void option_instat_callback(struct urb *urb, struct pt_regs *regs); 60 61 static int option_write(struct usb_serial_port *port, 62 const unsigned char *buf, int count); 63 64 static int option_chars_in_buffer(struct usb_serial_port *port); 65 static int option_ioctl(struct usb_serial_port *port, struct file *file, 66 unsigned int cmd, unsigned long arg); 67 static void option_set_termios(struct usb_serial_port *port, 68 struct termios *old); 69 static void option_break_ctl(struct usb_serial_port *port, int break_state); 70 static int option_tiocmget(struct usb_serial_port *port, struct file *file); 71 static int option_tiocmset(struct usb_serial_port *port, struct file *file, 72 unsigned int set, unsigned int clear); 73 static int option_send_setup(struct usb_serial_port *port); 74 75 /* Vendor and product IDs */ 76 #define OPTION_VENDOR_ID 0x0AF0 77 #define HUAWEI_VENDOR_ID 0x12D1 78 #define AUDIOVOX_VENDOR_ID 0x0F3D 79 80 #define OPTION_PRODUCT_OLD 0x5000 81 #define OPTION_PRODUCT_FUSION 0x6000 82 #define OPTION_PRODUCT_FUSION2 0x6300 83 #define HUAWEI_PRODUCT_E600 0x1001 84 #define AUDIOVOX_PRODUCT_AIRCARD 0x0112 85 86 static struct usb_device_id option_ids[] = { 87 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) }, 88 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION) }, 89 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION2) }, 90 { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) }, 91 { USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) }, 92 { } /* Terminating entry */ 93 }; 94 95 MODULE_DEVICE_TABLE(usb, option_ids); 96 97 static struct usb_driver option_driver = { 98 .owner = THIS_MODULE, 99 .name = "option", 100 .probe = usb_serial_probe, 101 .disconnect = usb_serial_disconnect, 102 .id_table = option_ids, 103 }; 104 105 /* The card has three separate interfaces, wich the serial driver 106 * recognizes separately, thus num_port=1. 107 */ 108 static struct usb_serial_driver option_3port_device = { 109 .driver = { 110 .owner = THIS_MODULE, 111 .name = "option", 112 }, 113 .description = "Option 3G data card", 114 .id_table = option_ids, 115 .num_interrupt_in = NUM_DONT_CARE, 116 .num_bulk_in = NUM_DONT_CARE, 117 .num_bulk_out = NUM_DONT_CARE, 118 .num_ports = 1, /* 3, but the card reports its ports separately */ 119 .open = option_open, 120 .close = option_close, 121 .write = option_write, 122 .write_room = option_write_room, 123 .chars_in_buffer = option_chars_in_buffer, 124 .throttle = option_rx_throttle, 125 .unthrottle = option_rx_unthrottle, 126 .ioctl = option_ioctl, 127 .set_termios = option_set_termios, 128 .break_ctl = option_break_ctl, 129 .tiocmget = option_tiocmget, 130 .tiocmset = option_tiocmset, 131 .attach = option_startup, 132 .shutdown = option_shutdown, 133 .read_int_callback = option_instat_callback, 134 }; 135 136 #ifdef CONFIG_USB_DEBUG 137 static int debug; 138 #else 139 #define debug 0 140 #endif 141 142 /* per port private data */ 143 144 #define N_IN_URB 4 145 #define N_OUT_URB 1 146 #define IN_BUFLEN 4096 147 #define OUT_BUFLEN 128 148 149 struct option_port_private { 150 /* Input endpoints and buffer for this port */ 151 struct urb *in_urbs[N_IN_URB]; 152 char in_buffer[N_IN_URB][IN_BUFLEN]; 153 /* Output endpoints and buffer for this port */ 154 struct urb *out_urbs[N_OUT_URB]; 155 char out_buffer[N_OUT_URB][OUT_BUFLEN]; 156 157 /* Settings for the port */ 158 int rts_state; /* Handshaking pins (outputs) */ 159 int dtr_state; 160 int cts_state; /* Handshaking pins (inputs) */ 161 int dsr_state; 162 int dcd_state; 163 int ri_state; 164 165 unsigned long tx_start_time[N_OUT_URB]; 166 }; 167 168 /* Functions used by new usb-serial code. */ 169 static int __init option_init(void) 170 { 171 int retval; 172 retval = usb_serial_register(&option_3port_device); 173 if (retval) 174 goto failed_3port_device_register; 175 retval = usb_register(&option_driver); 176 if (retval) 177 goto failed_driver_register; 178 179 info(DRIVER_DESC ": " DRIVER_VERSION); 180 181 return 0; 182 183 failed_driver_register: 184 usb_serial_deregister (&option_3port_device); 185 failed_3port_device_register: 186 return retval; 187 } 188 189 static void __exit option_exit(void) 190 { 191 usb_deregister (&option_driver); 192 usb_serial_deregister (&option_3port_device); 193 } 194 195 module_init(option_init); 196 module_exit(option_exit); 197 198 static void option_rx_throttle(struct usb_serial_port *port) 199 { 200 dbg("%s", __FUNCTION__); 201 } 202 203 static void option_rx_unthrottle(struct usb_serial_port *port) 204 { 205 dbg("%s", __FUNCTION__); 206 } 207 208 static void option_break_ctl(struct usb_serial_port *port, int break_state) 209 { 210 /* Unfortunately, I don't know how to send a break */ 211 dbg("%s", __FUNCTION__); 212 } 213 214 static void option_set_termios(struct usb_serial_port *port, 215 struct termios *old_termios) 216 { 217 dbg("%s", __FUNCTION__); 218 219 option_send_setup(port); 220 } 221 222 static int option_tiocmget(struct usb_serial_port *port, struct file *file) 223 { 224 unsigned int value; 225 struct option_port_private *portdata; 226 227 portdata = usb_get_serial_port_data(port); 228 229 value = ((portdata->rts_state) ? TIOCM_RTS : 0) | 230 ((portdata->dtr_state) ? TIOCM_DTR : 0) | 231 ((portdata->cts_state) ? TIOCM_CTS : 0) | 232 ((portdata->dsr_state) ? TIOCM_DSR : 0) | 233 ((portdata->dcd_state) ? TIOCM_CAR : 0) | 234 ((portdata->ri_state) ? TIOCM_RNG : 0); 235 236 return value; 237 } 238 239 static int option_tiocmset(struct usb_serial_port *port, struct file *file, 240 unsigned int set, unsigned int clear) 241 { 242 struct option_port_private *portdata; 243 244 portdata = usb_get_serial_port_data(port); 245 246 if (set & TIOCM_RTS) 247 portdata->rts_state = 1; 248 if (set & TIOCM_DTR) 249 portdata->dtr_state = 1; 250 251 if (clear & TIOCM_RTS) 252 portdata->rts_state = 0; 253 if (clear & TIOCM_DTR) 254 portdata->dtr_state = 0; 255 return option_send_setup(port); 256 } 257 258 static int option_ioctl(struct usb_serial_port *port, struct file *file, 259 unsigned int cmd, unsigned long arg) 260 { 261 return -ENOIOCTLCMD; 262 } 263 264 /* Write */ 265 static int option_write(struct usb_serial_port *port, 266 const unsigned char *buf, int count) 267 { 268 struct option_port_private *portdata; 269 int i; 270 int left, todo; 271 struct urb *this_urb = NULL; /* spurious */ 272 int err; 273 274 portdata = usb_get_serial_port_data(port); 275 276 dbg("%s: write (%d chars)", __FUNCTION__, count); 277 278 i = 0; 279 left = count; 280 for (i=0; left > 0 && i < N_OUT_URB; i++) { 281 todo = left; 282 if (todo > OUT_BUFLEN) 283 todo = OUT_BUFLEN; 284 285 this_urb = portdata->out_urbs[i]; 286 if (this_urb->status == -EINPROGRESS) { 287 if (time_before(jiffies, 288 portdata->tx_start_time[i] + 10 * HZ)) 289 continue; 290 usb_unlink_urb(this_urb); 291 continue; 292 } 293 if (this_urb->status != 0) 294 dbg("usb_write %p failed (err=%d)", 295 this_urb, this_urb->status); 296 297 dbg("%s: endpoint %d buf %d", __FUNCTION__, 298 usb_pipeendpoint(this_urb->pipe), i); 299 300 /* send the data */ 301 memcpy (this_urb->transfer_buffer, buf, todo); 302 this_urb->transfer_buffer_length = todo; 303 304 this_urb->dev = port->serial->dev; 305 err = usb_submit_urb(this_urb, GFP_ATOMIC); 306 if (err) { 307 dbg("usb_submit_urb %p (write bulk) failed " 308 "(%d, has %d)", this_urb, 309 err, this_urb->status); 310 continue; 311 } 312 portdata->tx_start_time[i] = jiffies; 313 buf += todo; 314 left -= todo; 315 } 316 317 count -= left; 318 dbg("%s: wrote (did %d)", __FUNCTION__, count); 319 return count; 320 } 321 322 static void option_indat_callback(struct urb *urb, struct pt_regs *regs) 323 { 324 int i, err; 325 int endpoint; 326 struct usb_serial_port *port; 327 struct tty_struct *tty; 328 unsigned char *data = urb->transfer_buffer; 329 330 dbg("%s: %p", __FUNCTION__, urb); 331 332 endpoint = usb_pipeendpoint(urb->pipe); 333 port = (struct usb_serial_port *) urb->context; 334 335 if (urb->status) { 336 dbg("%s: nonzero status: %d on endpoint %02x.", 337 __FUNCTION__, urb->status, endpoint); 338 } else { 339 tty = port->tty; 340 if (urb->actual_length) { 341 for (i = 0; i < urb->actual_length ; ++i) { 342 if (tty->flip.count >= TTY_FLIPBUF_SIZE) 343 tty_flip_buffer_push(tty); 344 tty_insert_flip_char(tty, data[i], 0); 345 } 346 tty_flip_buffer_push(tty); 347 } else { 348 dbg("%s: empty read urb received", __FUNCTION__); 349 } 350 351 /* Resubmit urb so we continue receiving */ 352 if (port->open_count && urb->status != -ESHUTDOWN) { 353 err = usb_submit_urb(urb, GFP_ATOMIC); 354 if (err) 355 printk(KERN_ERR "%s: resubmit read urb failed. " 356 "(%d)", __FUNCTION__, err); 357 } 358 } 359 return; 360 } 361 362 static void option_outdat_callback(struct urb *urb, struct pt_regs *regs) 363 { 364 struct usb_serial_port *port; 365 366 dbg("%s", __FUNCTION__); 367 368 port = (struct usb_serial_port *) urb->context; 369 370 if (port->open_count) 371 schedule_work(&port->work); 372 } 373 374 static void option_instat_callback(struct urb *urb, struct pt_regs *regs) 375 { 376 int err; 377 struct usb_serial_port *port = (struct usb_serial_port *) urb->context; 378 struct option_port_private *portdata = usb_get_serial_port_data(port); 379 struct usb_serial *serial = port->serial; 380 381 dbg("%s", __FUNCTION__); 382 dbg("%s: urb %p port %p has data %p", __FUNCTION__,urb,port,portdata); 383 384 if (urb->status == 0) { 385 struct usb_ctrlrequest *req_pkt = 386 (struct usb_ctrlrequest *)urb->transfer_buffer; 387 388 if (!req_pkt) { 389 dbg("%s: NULL req_pkt\n", __FUNCTION__); 390 return; 391 } 392 if ((req_pkt->bRequestType == 0xA1) && 393 (req_pkt->bRequest == 0x20)) { 394 int old_dcd_state; 395 unsigned char signals = *((unsigned char *) 396 urb->transfer_buffer + 397 sizeof(struct usb_ctrlrequest)); 398 399 dbg("%s: signal x%x", __FUNCTION__, signals); 400 401 old_dcd_state = portdata->dcd_state; 402 portdata->cts_state = 1; 403 portdata->dcd_state = ((signals & 0x01) ? 1 : 0); 404 portdata->dsr_state = ((signals & 0x02) ? 1 : 0); 405 portdata->ri_state = ((signals & 0x08) ? 1 : 0); 406 407 if (port->tty && !C_CLOCAL(port->tty) && 408 old_dcd_state && !portdata->dcd_state) 409 tty_hangup(port->tty); 410 } else { 411 dbg("%s: type %x req %x", __FUNCTION__, 412 req_pkt->bRequestType,req_pkt->bRequest); 413 } 414 } else 415 dbg("%s: error %d", __FUNCTION__, urb->status); 416 417 /* Resubmit urb so we continue receiving IRQ data */ 418 if (urb->status != -ESHUTDOWN) { 419 urb->dev = serial->dev; 420 err = usb_submit_urb(urb, GFP_ATOMIC); 421 if (err) 422 dbg("%s: resubmit intr urb failed. (%d)", 423 __FUNCTION__, err); 424 } 425 } 426 427 static int option_write_room(struct usb_serial_port *port) 428 { 429 struct option_port_private *portdata; 430 int i; 431 int data_len = 0; 432 struct urb *this_urb; 433 434 portdata = usb_get_serial_port_data(port); 435 436 for (i=0; i < N_OUT_URB; i++) { 437 this_urb = portdata->out_urbs[i]; 438 if (this_urb && this_urb->status != -EINPROGRESS) 439 data_len += OUT_BUFLEN; 440 } 441 442 dbg("%s: %d", __FUNCTION__, data_len); 443 return data_len; 444 } 445 446 static int option_chars_in_buffer(struct usb_serial_port *port) 447 { 448 struct option_port_private *portdata; 449 int i; 450 int data_len = 0; 451 struct urb *this_urb; 452 453 portdata = usb_get_serial_port_data(port); 454 455 for (i=0; i < N_OUT_URB; i++) { 456 this_urb = portdata->out_urbs[i]; 457 if (this_urb && this_urb->status == -EINPROGRESS) 458 data_len += this_urb->transfer_buffer_length; 459 } 460 dbg("%s: %d", __FUNCTION__, data_len); 461 return data_len; 462 } 463 464 static int option_open(struct usb_serial_port *port, struct file *filp) 465 { 466 struct option_port_private *portdata; 467 struct usb_serial *serial = port->serial; 468 int i, err; 469 struct urb *urb; 470 471 portdata = usb_get_serial_port_data(port); 472 473 dbg("%s", __FUNCTION__); 474 475 /* Set some sane defaults */ 476 portdata->rts_state = 1; 477 portdata->dtr_state = 1; 478 479 /* Reset low level data toggle and start reading from endpoints */ 480 for (i = 0; i < N_IN_URB; i++) { 481 urb = portdata->in_urbs[i]; 482 if (! urb) 483 continue; 484 if (urb->dev != serial->dev) { 485 dbg("%s: dev %p != %p", __FUNCTION__, 486 urb->dev, serial->dev); 487 continue; 488 } 489 490 /* 491 * make sure endpoint data toggle is synchronized with the 492 * device 493 */ 494 usb_clear_halt(urb->dev, urb->pipe); 495 496 err = usb_submit_urb(urb, GFP_KERNEL); 497 if (err) { 498 dbg("%s: submit urb %d failed (%d) %d", 499 __FUNCTION__, i, err, 500 urb->transfer_buffer_length); 501 } 502 } 503 504 /* Reset low level data toggle on out endpoints */ 505 for (i = 0; i < N_OUT_URB; i++) { 506 urb = portdata->out_urbs[i]; 507 if (! urb) 508 continue; 509 urb->dev = serial->dev; 510 /* usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), 511 usb_pipeout(urb->pipe), 0); */ 512 } 513 514 port->tty->low_latency = 1; 515 516 option_send_setup(port); 517 518 return (0); 519 } 520 521 static inline void stop_urb(struct urb *urb) 522 { 523 if (urb && urb->status == -EINPROGRESS) 524 usb_kill_urb(urb); 525 } 526 527 static void option_close(struct usb_serial_port *port, struct file *filp) 528 { 529 int i; 530 struct usb_serial *serial = port->serial; 531 struct option_port_private *portdata; 532 533 dbg("%s", __FUNCTION__); 534 portdata = usb_get_serial_port_data(port); 535 536 portdata->rts_state = 0; 537 portdata->dtr_state = 0; 538 539 if (serial->dev) { 540 option_send_setup(port); 541 542 /* Stop reading/writing urbs */ 543 for (i = 0; i < N_IN_URB; i++) 544 stop_urb(portdata->in_urbs[i]); 545 for (i = 0; i < N_OUT_URB; i++) 546 stop_urb(portdata->out_urbs[i]); 547 } 548 port->tty = NULL; 549 } 550 551 /* Helper functions used by option_setup_urbs */ 552 static struct urb *option_setup_urb(struct usb_serial *serial, int endpoint, 553 int dir, void *ctx, char *buf, int len, 554 void (*callback)(struct urb *, struct pt_regs *regs)) 555 { 556 struct urb *urb; 557 558 if (endpoint == -1) 559 return NULL; /* endpoint not needed */ 560 561 urb = usb_alloc_urb(0, GFP_KERNEL); /* No ISO */ 562 if (urb == NULL) { 563 dbg("%s: alloc for endpoint %d failed.", __FUNCTION__, endpoint); 564 return NULL; 565 } 566 567 /* Fill URB using supplied data. */ 568 usb_fill_bulk_urb(urb, serial->dev, 569 usb_sndbulkpipe(serial->dev, endpoint) | dir, 570 buf, len, callback, ctx); 571 572 return urb; 573 } 574 575 /* Setup urbs */ 576 static void option_setup_urbs(struct usb_serial *serial) 577 { 578 int j; 579 struct usb_serial_port *port; 580 struct option_port_private *portdata; 581 582 dbg("%s", __FUNCTION__); 583 584 port = serial->port[0]; 585 portdata = usb_get_serial_port_data(port); 586 587 /* Do indat endpoints first */ 588 for (j = 0; j <= N_IN_URB; ++j) { 589 portdata->in_urbs[j] = option_setup_urb (serial, 590 port->bulk_in_endpointAddress, USB_DIR_IN, port, 591 portdata->in_buffer[j], IN_BUFLEN, option_indat_callback); 592 } 593 594 /* outdat endpoints */ 595 for (j = 0; j <= N_OUT_URB; ++j) { 596 portdata->out_urbs[j] = option_setup_urb (serial, 597 port->bulk_out_endpointAddress, USB_DIR_OUT, port, 598 portdata->out_buffer[j], OUT_BUFLEN, option_outdat_callback); 599 } 600 } 601 602 static int option_send_setup(struct usb_serial_port *port) 603 { 604 struct usb_serial *serial = port->serial; 605 struct option_port_private *portdata; 606 607 dbg("%s", __FUNCTION__); 608 609 portdata = usb_get_serial_port_data(port); 610 611 if (port->tty) { 612 int val = 0; 613 if (portdata->dtr_state) 614 val |= 0x01; 615 if (portdata->rts_state) 616 val |= 0x02; 617 618 return usb_control_msg(serial->dev, 619 usb_rcvctrlpipe(serial->dev, 0), 620 0x22,0x21,val,0,NULL,0,USB_CTRL_SET_TIMEOUT); 621 } 622 623 return 0; 624 } 625 626 static int option_startup(struct usb_serial *serial) 627 { 628 int i, err; 629 struct usb_serial_port *port; 630 struct option_port_private *portdata; 631 632 dbg("%s", __FUNCTION__); 633 634 /* Now setup per port private data */ 635 for (i = 0; i < serial->num_ports; i++) { 636 port = serial->port[i]; 637 portdata = kmalloc(sizeof(*portdata), GFP_KERNEL); 638 if (!portdata) { 639 dbg("%s: kmalloc for option_port_private (%d) failed!.", 640 __FUNCTION__, i); 641 return (1); 642 } 643 memset(portdata, 0, sizeof(struct option_port_private)); 644 645 usb_set_serial_port_data(port, portdata); 646 647 if (! port->interrupt_in_urb) 648 continue; 649 err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); 650 if (err) 651 dbg("%s: submit irq_in urb failed %d", 652 __FUNCTION__, err); 653 } 654 655 option_setup_urbs(serial); 656 657 return (0); 658 } 659 660 static void option_shutdown(struct usb_serial *serial) 661 { 662 int i, j; 663 struct usb_serial_port *port; 664 struct option_port_private *portdata; 665 666 dbg("%s", __FUNCTION__); 667 668 /* Stop reading/writing urbs */ 669 for (i = 0; i < serial->num_ports; ++i) { 670 port = serial->port[i]; 671 portdata = usb_get_serial_port_data(port); 672 for (j = 0; j < N_IN_URB; j++) 673 stop_urb(portdata->in_urbs[j]); 674 for (j = 0; j < N_OUT_URB; j++) 675 stop_urb(portdata->out_urbs[j]); 676 } 677 678 /* Now free them */ 679 for (i = 0; i < serial->num_ports; ++i) { 680 port = serial->port[i]; 681 portdata = usb_get_serial_port_data(port); 682 683 for (j = 0; j < N_IN_URB; j++) { 684 if (portdata->in_urbs[j]) { 685 usb_free_urb(portdata->in_urbs[j]); 686 portdata->in_urbs[j] = NULL; 687 } 688 } 689 for (j = 0; j < N_OUT_URB; j++) { 690 if (portdata->out_urbs[j]) { 691 usb_free_urb(portdata->out_urbs[j]); 692 portdata->out_urbs[j] = NULL; 693 } 694 } 695 } 696 697 /* Now free per port private data */ 698 for (i = 0; i < serial->num_ports; i++) { 699 port = serial->port[i]; 700 kfree(usb_get_serial_port_data(port)); 701 } 702 } 703 704 MODULE_AUTHOR(DRIVER_AUTHOR); 705 MODULE_DESCRIPTION(DRIVER_DESC); 706 MODULE_VERSION(DRIVER_VERSION); 707 MODULE_LICENSE("GPL"); 708 709 #ifdef CONFIG_USB_DEBUG 710 module_param(debug, bool, S_IRUGO | S_IWUSR); 711 MODULE_PARM_DESC(debug, "Debug messages"); 712 #endif 713 714