diff options
| author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-04 19:25:44 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-04 19:25:44 -0500 |
| commit | c6c88bbde4d8b2ffe9886b7130b2e23781d424e5 (patch) | |
| tree | 47c2b61983acc6fbc42d89813729b87bbaf2aed9 | |
| parent | 0356dbb7fe87ba59558902e536d9f960e87353c1 (diff) | |
| parent | c8dd7709c534ab0d713aa698c99132b6c812b57c (diff) | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
198 files changed, 6554 insertions, 2028 deletions
diff --git a/Documentation/DocBook/usb.tmpl b/Documentation/DocBook/usb.tmpl index 15ce0f21e5e0..320af25de3a2 100644 --- a/Documentation/DocBook/usb.tmpl +++ b/Documentation/DocBook/usb.tmpl | |||
| @@ -253,6 +253,7 @@ | |||
| 253 | !Edrivers/usb/core/urb.c | 253 | !Edrivers/usb/core/urb.c |
| 254 | !Edrivers/usb/core/message.c | 254 | !Edrivers/usb/core/message.c |
| 255 | !Edrivers/usb/core/file.c | 255 | !Edrivers/usb/core/file.c |
| 256 | !Edrivers/usb/core/driver.c | ||
| 256 | !Edrivers/usb/core/usb.c | 257 | !Edrivers/usb/core/usb.c |
| 257 | !Edrivers/usb/core/hub.c | 258 | !Edrivers/usb/core/hub.c |
| 258 | </chapter> | 259 | </chapter> |
diff --git a/MAINTAINERS b/MAINTAINERS index 6af683025ae0..3fd7687a6ad9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -2640,6 +2640,12 @@ L: linux-usb-users@lists.sourceforge.net | |||
| 2640 | L: linux-usb-devel@lists.sourceforge.net | 2640 | L: linux-usb-devel@lists.sourceforge.net |
| 2641 | S: Maintained | 2641 | S: Maintained |
| 2642 | 2642 | ||
| 2643 | USB ISP116X DRIVER | ||
| 2644 | P: Olav Kongas | ||
| 2645 | M: ok@artecdesign.ee | ||
| 2646 | L: linux-usb-devel@lists.sourceforge.net | ||
| 2647 | S: Maintained | ||
| 2648 | |||
| 2643 | USB KAWASAKI LSI DRIVER | 2649 | USB KAWASAKI LSI DRIVER |
| 2644 | P: Oliver Neukum | 2650 | P: Oliver Neukum |
| 2645 | M: oliver@neukum.name | 2651 | M: oliver@neukum.name |
| @@ -2651,7 +2657,7 @@ USB MASS STORAGE DRIVER | |||
| 2651 | P: Matthew Dharm | 2657 | P: Matthew Dharm |
| 2652 | M: mdharm-usb@one-eyed-alien.net | 2658 | M: mdharm-usb@one-eyed-alien.net |
| 2653 | L: linux-usb-users@lists.sourceforge.net | 2659 | L: linux-usb-users@lists.sourceforge.net |
| 2654 | L: linux-usb-devel@lists.sourceforge.net | 2660 | L: usb-storage@lists.one-eyed-alien.net |
| 2655 | S: Maintained | 2661 | S: Maintained |
| 2656 | W: http://www.one-eyed-alien.net/~mdharm/linux-usb/ | 2662 | W: http://www.one-eyed-alien.net/~mdharm/linux-usb/ |
| 2657 | 2663 | ||
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index 07892f4012d8..277498ae5b6c 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c | |||
| @@ -43,6 +43,7 @@ | |||
| 43 | #include <asm/arch/pxafb.h> | 43 | #include <asm/arch/pxafb.h> |
| 44 | #include <asm/arch/mmc.h> | 44 | #include <asm/arch/mmc.h> |
| 45 | #include <asm/arch/irda.h> | 45 | #include <asm/arch/irda.h> |
| 46 | #include <asm/arch/ohci.h> | ||
| 46 | 47 | ||
| 47 | #include "generic.h" | 48 | #include "generic.h" |
| 48 | 49 | ||
| @@ -393,6 +394,25 @@ static struct platform_device *platform_devices[] __initdata = { | |||
| 393 | &mst_flash_device[1], | 394 | &mst_flash_device[1], |
| 394 | }; | 395 | }; |
| 395 | 396 | ||
| 397 | static int mainstone_ohci_init(struct device *dev) | ||
| 398 | { | ||
| 399 | /* setup Port1 GPIO pin. */ | ||
| 400 | pxa_gpio_mode( 88 | GPIO_ALT_FN_1_IN); /* USBHPWR1 */ | ||
| 401 | pxa_gpio_mode( 89 | GPIO_ALT_FN_2_OUT); /* USBHPEN1 */ | ||
| 402 | |||
| 403 | /* Set the Power Control Polarity Low and Power Sense | ||
| 404 | Polarity Low to active low. */ | ||
| 405 | UHCHR = (UHCHR | UHCHR_PCPL | UHCHR_PSPL) & | ||
| 406 | ~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE); | ||
| 407 | |||
| 408 | return 0; | ||
| 409 | } | ||
| 410 | |||
| 411 | static struct pxaohci_platform_data mainstone_ohci_platform_data = { | ||
| 412 | .port_mode = PMM_PERPORT_MODE, | ||
| 413 | .init = mainstone_ohci_init, | ||
| 414 | }; | ||
| 415 | |||
| 396 | static void __init mainstone_init(void) | 416 | static void __init mainstone_init(void) |
| 397 | { | 417 | { |
| 398 | int SW7 = 0; /* FIXME: get from SCR (Mst doc section 3.2.1.1) */ | 418 | int SW7 = 0; /* FIXME: get from SCR (Mst doc section 3.2.1.1) */ |
| @@ -424,6 +444,7 @@ static void __init mainstone_init(void) | |||
| 424 | 444 | ||
| 425 | pxa_set_mci_info(&mainstone_mci_platform_data); | 445 | pxa_set_mci_info(&mainstone_mci_platform_data); |
| 426 | pxa_set_ficp_info(&mainstone_ficp_platform_data); | 446 | pxa_set_ficp_info(&mainstone_ficp_platform_data); |
| 447 | pxa_set_ohci_info(&mainstone_ohci_platform_data); | ||
| 427 | } | 448 | } |
| 428 | 449 | ||
| 429 | 450 | ||
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index c722a9a91fcc..b41b1efaa2cf 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <asm/hardware.h> | 21 | #include <asm/hardware.h> |
| 22 | #include <asm/irq.h> | 22 | #include <asm/irq.h> |
| 23 | #include <asm/arch/pxa-regs.h> | 23 | #include <asm/arch/pxa-regs.h> |
| 24 | #include <asm/arch/ohci.h> | ||
| 24 | 25 | ||
| 25 | #include "generic.h" | 26 | #include "generic.h" |
| 26 | 27 | ||
| @@ -194,6 +195,11 @@ static struct platform_device ohci_device = { | |||
| 194 | .resource = pxa27x_ohci_resources, | 195 | .resource = pxa27x_ohci_resources, |
| 195 | }; | 196 | }; |
| 196 | 197 | ||
| 198 | void __init pxa_set_ohci_info(struct pxaohci_platform_data *info) | ||
| 199 | { | ||
| 200 | ohci_device.dev.platform_data = info; | ||
| 201 | } | ||
| 202 | |||
| 197 | static struct platform_device *devices[] __initdata = { | 203 | static struct platform_device *devices[] __initdata = { |
| 198 | &ohci_device, | 204 | &ohci_device, |
| 199 | }; | 205 | }; |
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index 7b1cd93892be..c4b9d2adfc08 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig | |||
| @@ -358,7 +358,8 @@ config BLK_DEV_UB | |||
| 358 | This driver supports certain USB attached storage devices | 358 | This driver supports certain USB attached storage devices |
| 359 | such as flash keys. | 359 | such as flash keys. |
| 360 | 360 | ||
| 361 | Warning: Enabling this cripples the usb-storage driver. | 361 | If you enable this driver, it is recommended to avoid conflicts |
| 362 | with usb-storage by enabling USB_LIBUSUAL. | ||
| 362 | 363 | ||
| 363 | If unsure, say N. | 364 | If unsure, say N. |
| 364 | 365 | ||
diff --git a/drivers/block/ub.c b/drivers/block/ub.c index bfb23d543ff7..10740a065088 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c | |||
| @@ -9,7 +9,6 @@ | |||
| 9 | * | 9 | * |
| 10 | * TODO (sorted by decreasing priority) | 10 | * TODO (sorted by decreasing priority) |
| 11 | * -- Kill first_open (Al Viro fixed the block layer now) | 11 | * -- Kill first_open (Al Viro fixed the block layer now) |
| 12 | * -- Do resets with usb_device_reset (needs a thread context, use khubd) | ||
| 13 | * -- set readonly flag for CDs, set removable flag for CF readers | 12 | * -- set readonly flag for CDs, set removable flag for CF readers |
| 14 | * -- do inquiry and verify we got a disk and not a tape (for LUN mismatch) | 13 | * -- do inquiry and verify we got a disk and not a tape (for LUN mismatch) |
| 15 | * -- special case some senses, e.g. 3a/0 -> no media present, reduce retries | 14 | * -- special case some senses, e.g. 3a/0 -> no media present, reduce retries |
| @@ -29,6 +28,7 @@ | |||
| 29 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
| 30 | #include <linux/module.h> | 29 | #include <linux/module.h> |
| 31 | #include <linux/usb.h> | 30 | #include <linux/usb.h> |
| 31 | #include <linux/usb_usual.h> | ||
| 32 | #include <linux/blkdev.h> | 32 | #include <linux/blkdev.h> |
| 33 | #include <linux/devfs_fs_kernel.h> | 33 | #include <linux/devfs_fs_kernel.h> |
| 34 | #include <linux/timer.h> | 34 | #include <linux/timer.h> |
| @@ -107,16 +107,6 @@ | |||
| 107 | */ | 107 | */ |
| 108 | 108 | ||
| 109 | /* | 109 | /* |
| 110 | * Definitions which have to be scattered once we understand the layout better. | ||
| 111 | */ | ||
| 112 | |||
| 113 | /* Transport (despite PR in the name) */ | ||
| 114 | #define US_PR_BULK 0x50 /* bulk only */ | ||
| 115 | |||
| 116 | /* Protocol */ | ||
| 117 | #define US_SC_SCSI 0x06 /* Transparent */ | ||
| 118 | |||
| 119 | /* | ||
| 120 | * This many LUNs per USB device. | 110 | * This many LUNs per USB device. |
| 121 | * Every one of them takes a host, see UB_MAX_HOSTS. | 111 | * Every one of them takes a host, see UB_MAX_HOSTS. |
| 122 | */ | 112 | */ |
| @@ -125,7 +115,7 @@ | |||
| 125 | /* | 115 | /* |
| 126 | */ | 116 | */ |
| 127 | 117 | ||
| 128 | #define UB_MINORS_PER_MAJOR 8 | 118 | #define UB_PARTS_PER_LUN 8 |
| 129 | 119 | ||
| 130 | #define UB_MAX_CDB_SIZE 16 /* Corresponds to Bulk */ | 120 | #define UB_MAX_CDB_SIZE 16 /* Corresponds to Bulk */ |
| 131 | 121 | ||
| @@ -245,6 +235,13 @@ struct ub_scsi_cmd { | |||
| 245 | void *back; | 235 | void *back; |
| 246 | }; | 236 | }; |
| 247 | 237 | ||
| 238 | struct ub_request { | ||
| 239 | struct request *rq; | ||
| 240 | unsigned int current_try; | ||
| 241 | unsigned int nsg; /* sgv[nsg] */ | ||
| 242 | struct scatterlist sgv[UB_MAX_REQ_SG]; | ||
| 243 | }; | ||
| 244 | |||
| 248 | /* | 245 | /* |
| 249 | */ | 246 | */ |
| 250 | struct ub_capacity { | 247 | struct ub_capacity { |
| @@ -340,6 +337,8 @@ struct ub_lun { | |||
| 340 | int readonly; | 337 | int readonly; |
| 341 | int first_open; /* Kludge. See ub_bd_open. */ | 338 | int first_open; /* Kludge. See ub_bd_open. */ |
| 342 | 339 | ||
| 340 | struct ub_request urq; | ||
| 341 | |||
| 343 | /* Use Ingo's mempool if or when we have more than one command. */ | 342 | /* Use Ingo's mempool if or when we have more than one command. */ |
| 344 | /* | 343 | /* |
| 345 | * Currently we never need more than one command for the whole device. | 344 | * Currently we never need more than one command for the whole device. |
| @@ -360,6 +359,7 @@ struct ub_dev { | |||
| 360 | atomic_t poison; /* The USB device is disconnected */ | 359 | atomic_t poison; /* The USB device is disconnected */ |
| 361 | int openc; /* protected by ub_lock! */ | 360 | int openc; /* protected by ub_lock! */ |
| 362 | /* kref is too implicit for our taste */ | 361 | /* kref is too implicit for our taste */ |
| 362 | int reset; /* Reset is running */ | ||
| 363 | unsigned int tagcnt; | 363 | unsigned int tagcnt; |
| 364 | char name[12]; | 364 | char name[12]; |
| 365 | struct usb_device *dev; | 365 | struct usb_device *dev; |
| @@ -387,6 +387,9 @@ struct ub_dev { | |||
| 387 | struct bulk_cs_wrap work_bcs; | 387 | struct bulk_cs_wrap work_bcs; |
| 388 | struct usb_ctrlrequest work_cr; | 388 | struct usb_ctrlrequest work_cr; |
| 389 | 389 | ||
| 390 | struct work_struct reset_work; | ||
| 391 | wait_queue_head_t reset_wait; | ||
| 392 | |||
| 390 | int sg_stat[6]; | 393 | int sg_stat[6]; |
| 391 | struct ub_scsi_trace tr; | 394 | struct ub_scsi_trace tr; |
| 392 | }; | 395 | }; |
| @@ -395,12 +398,14 @@ struct ub_dev { | |||
| 395 | */ | 398 | */ |
| 396 | static void ub_cleanup(struct ub_dev *sc); | 399 | static void ub_cleanup(struct ub_dev *sc); |
| 397 | static int ub_request_fn_1(struct ub_lun *lun, struct request *rq); | 400 | static int ub_request_fn_1(struct ub_lun *lun, struct request *rq); |
| 398 | static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun, | 401 | static void ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun, |
| 399 | struct ub_scsi_cmd *cmd, struct request *rq); | 402 | struct ub_scsi_cmd *cmd, struct ub_request *urq); |
| 400 | static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun, | 403 | static void ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun, |
| 401 | struct ub_scsi_cmd *cmd, struct request *rq); | 404 | struct ub_scsi_cmd *cmd, struct ub_request *urq); |
| 402 | static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd); | 405 | static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd); |
| 403 | static void ub_end_rq(struct request *rq, int uptodate); | 406 | static void ub_end_rq(struct request *rq, int uptodate); |
| 407 | static int ub_rw_cmd_retry(struct ub_dev *sc, struct ub_lun *lun, | ||
| 408 | struct ub_request *urq, struct ub_scsi_cmd *cmd); | ||
| 404 | static int ub_submit_scsi(struct ub_dev *sc, struct ub_scsi_cmd *cmd); | 409 | static int ub_submit_scsi(struct ub_dev *sc, struct ub_scsi_cmd *cmd); |
| 405 | static void ub_urb_complete(struct urb *urb, struct pt_regs *pt); | 410 | static void ub_urb_complete(struct urb *urb, struct pt_regs *pt); |
| 406 | static void ub_scsi_action(unsigned long _dev); | 411 | static void ub_scsi_action(unsigned long _dev); |
| @@ -415,6 +420,8 @@ static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd); | |||
| 415 | static int ub_submit_clear_stall(struct ub_dev *sc, struct ub_scsi_cmd *cmd, | 420 | static int ub_submit_clear_stall(struct ub_dev *sc, struct ub_scsi_cmd *cmd, |
| 416 | int stalled_pipe); | 421 | int stalled_pipe); |
| 417 | static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd); | 422 | static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd); |
| 423 | static void ub_reset_enter(struct ub_dev *sc); | ||
| 424 | static void ub_reset_task(void *arg); | ||
| 418 | static int ub_sync_tur(struct ub_dev *sc, struct ub_lun *lun); | 425 | static int ub_sync_tur(struct ub_dev *sc, struct ub_lun *lun); |
| 419 | static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun, | 426 | static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun, |
| 420 | struct ub_capacity *ret); | 427 | struct ub_capacity *ret); |
| @@ -422,13 +429,18 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum); | |||
| 422 | 429 | ||
| 423 | /* | 430 | /* |
| 424 | */ | 431 | */ |
| 432 | #ifdef CONFIG_USB_LIBUSUAL | ||
| 433 | |||
| 434 | #define ub_usb_ids storage_usb_ids | ||
| 435 | #else | ||
| 436 | |||
| 425 | static struct usb_device_id ub_usb_ids[] = { | 437 | static struct usb_device_id ub_usb_ids[] = { |
| 426 | // { USB_DEVICE_VER(0x0781, 0x0002, 0x0009, 0x0009) }, /* SDDR-31 */ | ||
| 427 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_BULK) }, | 438 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_BULK) }, |
| 428 | { } | 439 | { } |
| 429 | }; | 440 | }; |
| 430 | 441 | ||
| 431 | MODULE_DEVICE_TABLE(usb, ub_usb_ids); | 442 | MODULE_DEVICE_TABLE(usb, ub_usb_ids); |
| 443 | #endif /* CONFIG_USB_LIBUSUAL */ | ||
| 432 | 444 | ||
| 433 | /* | 445 | /* |
| 434 | * Find me a way to identify "next free minor" for add_disk(), | 446 | * Find me a way to identify "next free minor" for add_disk(), |
| @@ -522,6 +534,9 @@ static ssize_t ub_diag_show(struct device *dev, struct device_attribute *attr, | |||
| 522 | spin_lock_irqsave(&sc->lock, flags); | 534 | spin_lock_irqsave(&sc->lock, flags); |
| 523 | 535 | ||
| 524 | cnt += sprintf(page + cnt, | 536 | cnt += sprintf(page + cnt, |
| 537 | "poison %d reset %d\n", | ||
| 538 | atomic_read(&sc->poison), sc->reset); | ||
| 539 | cnt += sprintf(page + cnt, | ||
| 525 | "qlen %d qmax %d\n", | 540 | "qlen %d qmax %d\n", |
| 526 | sc->cmd_queue.qlen, sc->cmd_queue.qmax); | 541 | sc->cmd_queue.qlen, sc->cmd_queue.qmax); |
| 527 | cnt += sprintf(page + cnt, | 542 | cnt += sprintf(page + cnt, |
| @@ -770,7 +785,8 @@ static int ub_request_fn_1(struct ub_lun *lun, struct request *rq) | |||
| 770 | { | 785 | { |
| 771 | struct ub_dev *sc = lun->udev; | 786 | struct ub_dev *sc = lun->udev; |
| 772 | struct ub_scsi_cmd *cmd; | 787 | struct ub_scsi_cmd *cmd; |
| 773 | int rc; | 788 | struct ub_request *urq; |
| 789 | int n_elem; | ||
| 774 | 790 | ||
| 775 | if (atomic_read(&sc->poison) || lun->changed) { | 791 | if (atomic_read(&sc->poison) || lun->changed) { |
| 776 | blkdev_dequeue_request(rq); | 792 | blkdev_dequeue_request(rq); |
| @@ -778,65 +794,70 @@ static int ub_request_fn_1(struct ub_lun *lun, struct request *rq) | |||
| 778 | return 0; | 794 | return 0; |
| 779 | } | 795 | } |
| 780 | 796 | ||
| 797 | if (lun->urq.rq != NULL) | ||
| 798 | return -1; | ||
| 781 | if ((cmd = ub_get_cmd(lun)) == NULL) | 799 | if ((cmd = ub_get_cmd(lun)) == NULL) |
| 782 | return -1; | 800 | return -1; |
| 783 | memset(cmd, 0, sizeof(struct ub_scsi_cmd)); | 801 | memset(cmd, 0, sizeof(struct ub_scsi_cmd)); |
| 784 | 802 | ||
| 785 | blkdev_dequeue_request(rq); | 803 | blkdev_dequeue_request(rq); |
| 804 | |||
| 805 | urq = &lun->urq; | ||
| 806 | memset(urq, 0, sizeof(struct ub_request)); | ||
| 807 | urq->rq = rq; | ||
| 808 | |||
| 809 | /* | ||
| 810 | * get scatterlist from block layer | ||
| 811 | */ | ||
| 812 | n_elem = blk_rq_map_sg(lun->disk->queue, rq, &urq->sgv[0]); | ||
| 813 | if (n_elem < 0) { | ||
| 814 | printk(KERN_INFO "%s: failed request map (%d)\n", | ||
| 815 | lun->name, n_elem); /* P3 */ | ||
| 816 | goto drop; | ||
| 817 | } | ||
| 818 | if (n_elem > UB_MAX_REQ_SG) { /* Paranoia */ | ||
| 819 | printk(KERN_WARNING "%s: request with %d segments\n", | ||
| 820 | lun->name, n_elem); | ||
| 821 | goto drop; | ||
| 822 | } | ||
| 823 | urq->nsg = n_elem; | ||
| 824 | sc->sg_stat[n_elem < 5 ? n_elem : 5]++; | ||
| 825 | |||
| 786 | if (blk_pc_request(rq)) { | 826 | if (blk_pc_request(rq)) { |
| 787 | rc = ub_cmd_build_packet(sc, lun, cmd, rq); | 827 | ub_cmd_build_packet(sc, lun, cmd, urq); |
| 788 | } else { | 828 | } else { |
| 789 | rc = ub_cmd_build_block(sc, lun, cmd, rq); | 829 | ub_cmd_build_block(sc, lun, cmd, urq); |
| 790 | } | ||
| 791 | if (rc != 0) { | ||
| 792 | ub_put_cmd(lun, cmd); | ||
| 793 | ub_end_rq(rq, 0); | ||
| 794 | return 0; | ||
| 795 | } | 830 | } |
| 796 | cmd->state = UB_CMDST_INIT; | 831 | cmd->state = UB_CMDST_INIT; |
| 797 | cmd->lun = lun; | 832 | cmd->lun = lun; |
| 798 | cmd->done = ub_rw_cmd_done; | 833 | cmd->done = ub_rw_cmd_done; |
| 799 | cmd->back = rq; | 834 | cmd->back = urq; |
| 800 | 835 | ||
| 801 | cmd->tag = sc->tagcnt++; | 836 | cmd->tag = sc->tagcnt++; |
| 802 | if (ub_submit_scsi(sc, cmd) != 0) { | 837 | if (ub_submit_scsi(sc, cmd) != 0) |
| 803 | ub_put_cmd(lun, cmd); | 838 | goto drop; |
| 804 | ub_end_rq(rq, 0); | ||
| 805 | return 0; | ||
| 806 | } | ||
| 807 | 839 | ||
| 808 | return 0; | 840 | return 0; |
| 841 | |||
| 842 | drop: | ||
| 843 | ub_put_cmd(lun, cmd); | ||
| 844 | ub_end_rq(rq, 0); | ||
| 845 | return 0; | ||
| 809 | } | 846 | } |
| 810 | 847 | ||
| 811 | static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun, | 848 | static void ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun, |
| 812 | struct ub_scsi_cmd *cmd, struct request *rq) | 849 | struct ub_scsi_cmd *cmd, struct ub_request *urq) |
| 813 | { | 850 | { |
| 814 | int ub_dir; | 851 | struct request *rq = urq->rq; |
| 815 | int n_elem; | ||
| 816 | unsigned int block, nblks; | 852 | unsigned int block, nblks; |
| 817 | 853 | ||
| 818 | if (rq_data_dir(rq) == WRITE) | 854 | if (rq_data_dir(rq) == WRITE) |
| 819 | ub_dir = UB_DIR_WRITE; | 855 | cmd->dir = UB_DIR_WRITE; |
| 820 | else | 856 | else |
| 821 | ub_dir = UB_DIR_READ; | 857 | cmd->dir = UB_DIR_READ; |
| 822 | cmd->dir = ub_dir; | ||
| 823 | 858 | ||
| 824 | /* | 859 | cmd->nsg = urq->nsg; |
| 825 | * get scatterlist from block layer | 860 | memcpy(cmd->sgv, urq->sgv, sizeof(struct scatterlist) * cmd->nsg); |
| 826 | */ | ||
| 827 | n_elem = blk_rq_map_sg(lun->disk->queue, rq, &cmd->sgv[0]); | ||
| 828 | if (n_elem <= 0) { | ||
| 829 | printk(KERN_INFO "%s: failed request map (%d)\n", | ||
| 830 | sc->name, n_elem); /* P3 */ | ||
| 831 | return -1; /* request with no s/g entries? */ | ||
| 832 | } | ||
| 833 | if (n_elem > UB_MAX_REQ_SG) { /* Paranoia */ | ||
| 834 | printk(KERN_WARNING "%s: request with %d segments\n", | ||
| 835 | sc->name, n_elem); | ||
| 836 | return -1; | ||
| 837 | } | ||
| 838 | cmd->nsg = n_elem; | ||
| 839 | sc->sg_stat[n_elem < 5 ? n_elem : 5]++; | ||
| 840 | 861 | ||
| 841 | /* | 862 | /* |
| 842 | * build the command | 863 | * build the command |
| @@ -847,7 +868,7 @@ static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun, | |||
| 847 | block = rq->sector >> lun->capacity.bshift; | 868 | block = rq->sector >> lun->capacity.bshift; |
| 848 | nblks = rq->nr_sectors >> lun->capacity.bshift; | 869 | nblks = rq->nr_sectors >> lun->capacity.bshift; |
| 849 | 870 | ||
| 850 | cmd->cdb[0] = (ub_dir == UB_DIR_READ)? READ_10: WRITE_10; | 871 | cmd->cdb[0] = (cmd->dir == UB_DIR_READ)? READ_10: WRITE_10; |
| 851 | /* 10-byte uses 4 bytes of LBA: 2147483648KB, 2097152MB, 2048GB */ | 872 | /* 10-byte uses 4 bytes of LBA: 2147483648KB, 2097152MB, 2048GB */ |
| 852 | cmd->cdb[2] = block >> 24; | 873 | cmd->cdb[2] = block >> 24; |
| 853 | cmd->cdb[3] = block >> 16; | 874 | cmd->cdb[3] = block >> 16; |
| @@ -858,14 +879,12 @@ static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun, | |||
| 858 | cmd->cdb_len = 10; | 879 | cmd->cdb_len = 10; |
| 859 | 880 | ||
| 860 | cmd->len = rq->nr_sectors * 512; | 881 | cmd->len = rq->nr_sectors * 512; |
| 861 | |||
| 862 | return 0; | ||
| 863 | } | 882 | } |
| 864 | 883 | ||
| 865 | static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun, | 884 | static void ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun, |
| 866 | struct ub_scsi_cmd *cmd, struct request *rq) | 885 | struct ub_scsi_cmd *cmd, struct ub_request *urq) |
| 867 | { | 886 | { |
| 868 | int n_elem; | 887 | struct request *rq = urq->rq; |
| 869 | 888 | ||
| 870 | if (rq->data_len == 0) { | 889 | if (rq->data_len == 0) { |
| 871 | cmd->dir = UB_DIR_NONE; | 890 | cmd->dir = UB_DIR_NONE; |
| @@ -874,40 +893,26 @@ static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun, | |||
| 874 | cmd->dir = UB_DIR_WRITE; | 893 | cmd->dir = UB_DIR_WRITE; |
| 875 | else | 894 | else |
| 876 | cmd->dir = UB_DIR_READ; | 895 | cmd->dir = UB_DIR_READ; |
| 877 | |||
| 878 | } | 896 | } |
| 879 | 897 | ||
| 880 | /* | 898 | cmd->nsg = urq->nsg; |
| 881 | * get scatterlist from block layer | 899 | memcpy(cmd->sgv, urq->sgv, sizeof(struct scatterlist) * cmd->nsg); |
| 882 | */ | ||
| 883 | n_elem = blk_rq_map_sg(lun->disk->queue, rq, &cmd->sgv[0]); | ||
| 884 | if (n_elem < 0) { | ||
| 885 | printk(KERN_INFO "%s: failed request map (%d)\n", | ||
| 886 | sc->name, n_elem); /* P3 */ | ||
| 887 | return -1; | ||
| 888 | } | ||
| 889 | if (n_elem > UB_MAX_REQ_SG) { /* Paranoia */ | ||
| 890 | printk(KERN_WARNING "%s: request with %d segments\n", | ||
| 891 | sc->name, n_elem); | ||
| 892 | return -1; | ||
| 893 | } | ||
| 894 | cmd->nsg = n_elem; | ||
| 895 | sc->sg_stat[n_elem < 5 ? n_elem : 5]++; | ||
| 896 | 900 | ||
| 897 | memcpy(&cmd->cdb, rq->cmd, rq->cmd_len); | 901 | memcpy(&cmd->cdb, rq->cmd, rq->cmd_len); |
| 898 | cmd->cdb_len = rq->cmd_len; | 902 | cmd->cdb_len = rq->cmd_len; |
| 899 | 903 | ||
| 900 | cmd->len = rq->data_len; | 904 | cmd->len = rq->data_len; |
| 901 | |||
| 902 | return 0; | ||
| 903 | } | 905 | } |
| 904 | 906 | ||
| 905 | static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | 907 | static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd) |
| 906 | { | 908 | { |
| 907 | struct request *rq = cmd->back; | ||
| 908 | struct ub_lun *lun = cmd->lun; | 909 | struct ub_lun *lun = cmd->lun; |
| 910 | struct ub_request *urq = cmd->back; | ||
| 911 | struct request *rq; | ||
| 909 | int uptodate; | 912 | int uptodate; |
| 910 | 913 | ||
| 914 | rq = urq->rq; | ||
| 915 | |||
| 911 | if (cmd->error == 0) { | 916 | if (cmd->error == 0) { |
| 912 | uptodate = 1; | 917 | uptodate = 1; |
| 913 | 918 | ||
| @@ -928,9 +933,16 @@ static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
| 928 | rq->errors = SAM_STAT_CHECK_CONDITION; | 933 | rq->errors = SAM_STAT_CHECK_CONDITION; |
| 929 | else | 934 | else |
| 930 | rq->errors = DID_ERROR << 16; | 935 | rq->errors = DID_ERROR << 16; |
| 936 | } else { | ||
| 937 | if (cmd->error == -EIO) { | ||
| 938 | if (ub_rw_cmd_retry(sc, lun, urq, cmd) == 0) | ||
| 939 | return; | ||
| 940 | } | ||
| 931 | } | 941 | } |
| 932 | } | 942 | } |
| 933 | 943 | ||
| 944 | urq->rq = NULL; | ||
| 945 | |||
| 934 | ub_put_cmd(lun, cmd); | 946 | ub_put_cmd(lun, cmd); |
| 935 | ub_end_rq(rq, uptodate); | 947 | ub_end_rq(rq, uptodate); |
| 936 | blk_start_queue(lun->disk->queue); | 948 | blk_start_queue(lun->disk->queue); |
| @@ -938,13 +950,45 @@ static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
| 938 | 950 | ||
| 939 | static void ub_end_rq(struct request *rq, int uptodate) | 951 | static void ub_end_rq(struct request *rq, int uptodate) |
| 940 | { | 952 | { |
| 941 | int rc; | 953 | end_that_request_first(rq, uptodate, rq->hard_nr_sectors); |
| 942 | |||
| 943 | rc = end_that_request_first(rq, uptodate, rq->hard_nr_sectors); | ||
| 944 | // assert(rc == 0); | ||
| 945 | end_that_request_last(rq); | 954 | end_that_request_last(rq); |
| 946 | } | 955 | } |
| 947 | 956 | ||
| 957 | static int ub_rw_cmd_retry(struct ub_dev *sc, struct ub_lun *lun, | ||
| 958 | struct ub_request *urq, struct ub_scsi_cmd *cmd) | ||
| 959 | { | ||
| 960 | |||
| 961 | if (atomic_read(&sc->poison)) | ||
| 962 | return -ENXIO; | ||
| 963 | |||
| 964 | ub_reset_enter(sc); | ||
| 965 | |||
| 966 | if (urq->current_try >= 3) | ||
| 967 | return -EIO; | ||
| 968 | urq->current_try++; | ||
| 969 | /* P3 */ printk("%s: dir %c len/act %d/%d " | ||
| 970 | "[sense %x %02x %02x] retry %d\n", | ||
| 971 | sc->name, UB_DIR_CHAR(cmd->dir), cmd->len, cmd->act_len, | ||
| 972 | cmd->key, cmd->asc, cmd->ascq, urq->current_try); | ||
| 973 | |||
| 974 | memset(cmd, 0, sizeof(struct ub_scsi_cmd)); | ||
| 975 | ub_cmd_build_block(sc, lun, cmd, urq); | ||
| 976 | |||
| 977 | cmd->state = UB_CMDST_INIT; | ||
| 978 | cmd->lun = lun; | ||
| 979 | cmd->done = ub_rw_cmd_done; | ||
| 980 | cmd->back = urq; | ||
| 981 | |||
| 982 | cmd->tag = sc->tagcnt++; | ||
| 983 | |||
| 984 | #if 0 /* Wasteful */ | ||
| 985 | return ub_submit_scsi(sc, cmd); | ||
| 986 | #else | ||
| 987 | ub_cmdq_add(sc, cmd); | ||
| 988 | return 0; | ||
| 989 | #endif | ||
| 990 | } | ||
| 991 | |||
| 948 | /* | 992 | /* |
| 949 | * Submit a regular SCSI operation (not an auto-sense). | 993 | * Submit a regular SCSI operation (not an auto-sense). |
| 950 | * | 994 | * |
| @@ -1075,7 +1119,7 @@ static void ub_scsi_dispatch(struct ub_dev *sc) | |||
| 1075 | struct ub_scsi_cmd *cmd; | 1119 | struct ub_scsi_cmd *cmd; |
| 1076 | int rc; | 1120 | int rc; |
| 1077 | 1121 | ||
| 1078 | while ((cmd = ub_cmdq_peek(sc)) != NULL) { | 1122 | while (!sc->reset && (cmd = ub_cmdq_peek(sc)) != NULL) { |
| 1079 | if (cmd->state == UB_CMDST_DONE) { | 1123 | if (cmd->state == UB_CMDST_DONE) { |
| 1080 | ub_cmdq_pop(sc); | 1124 | ub_cmdq_pop(sc); |
| 1081 | (*cmd->done)(sc, cmd); | 1125 | (*cmd->done)(sc, cmd); |
| @@ -1098,11 +1142,12 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
| 1098 | { | 1142 | { |
| 1099 | struct urb *urb = &sc->work_urb; | 1143 | struct urb *urb = &sc->work_urb; |
| 1100 | struct bulk_cs_wrap *bcs; | 1144 | struct bulk_cs_wrap *bcs; |
| 1145 | int len; | ||
| 1101 | int rc; | 1146 | int rc; |
| 1102 | 1147 | ||
| 1103 | if (atomic_read(&sc->poison)) { | 1148 | if (atomic_read(&sc->poison)) { |
| 1104 | /* A little too simplistic, I feel... */ | 1149 | ub_state_done(sc, cmd, -ENODEV); |
| 1105 | goto Bad_End; | 1150 | return; |
| 1106 | } | 1151 | } |
| 1107 | 1152 | ||
| 1108 | if (cmd->state == UB_CMDST_CLEAR) { | 1153 | if (cmd->state == UB_CMDST_CLEAR) { |
| @@ -1110,7 +1155,6 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
| 1110 | /* | 1155 | /* |
| 1111 | * STALL while clearning STALL. | 1156 | * STALL while clearning STALL. |
| 1112 | * The control pipe clears itself - nothing to do. | 1157 | * The control pipe clears itself - nothing to do. |
| 1113 | * XXX Might try to reset the device here and retry. | ||
| 1114 | */ | 1158 | */ |
| 1115 | printk(KERN_NOTICE "%s: stall on control pipe\n", | 1159 | printk(KERN_NOTICE "%s: stall on control pipe\n", |
| 1116 | sc->name); | 1160 | sc->name); |
| @@ -1129,11 +1173,6 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
| 1129 | 1173 | ||
| 1130 | } else if (cmd->state == UB_CMDST_CLR2STS) { | 1174 | } else if (cmd->state == UB_CMDST_CLR2STS) { |
| 1131 | if (urb->status == -EPIPE) { | 1175 | if (urb->status == -EPIPE) { |
| 1132 | /* | ||
| 1133 | * STALL while clearning STALL. | ||
| 1134 | * The control pipe clears itself - nothing to do. | ||
| 1135 | * XXX Might try to reset the device here and retry. | ||
| 1136 | */ | ||
| 1137 | printk(KERN_NOTICE "%s: stall on control pipe\n", | 1176 | printk(KERN_NOTICE "%s: stall on control pipe\n", |
| 1138 | sc->name); | 1177 | sc->name); |
| 1139 | goto Bad_End; | 1178 | goto Bad_End; |
| @@ -1151,11 +1190,6 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
| 1151 | 1190 | ||
| 1152 | } else if (cmd->state == UB_CMDST_CLRRS) { | 1191 | } else if (cmd->state == UB_CMDST_CLRRS) { |
| 1153 | if (urb->status == -EPIPE) { | 1192 | if (urb->status == -EPIPE) { |
| 1154 | /* | ||
| 1155 | * STALL while clearning STALL. | ||
| 1156 | * The control pipe clears itself - nothing to do. | ||
| 1157 | * XXX Might try to reset the device here and retry. | ||
| 1158 | */ | ||
| 1159 | printk(KERN_NOTICE "%s: stall on control pipe\n", | 1193 | printk(KERN_NOTICE "%s: stall on control pipe\n", |
| 1160 | sc->name); | 1194 | sc->name); |
| 1161 | goto Bad_End; | 1195 | goto Bad_End; |
| @@ -1172,7 +1206,12 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
| 1172 | ub_state_stat_counted(sc, cmd); | 1206 | ub_state_stat_counted(sc, cmd); |
| 1173 | 1207 | ||
| 1174 | } else if (cmd->state == UB_CMDST_CMD) { | 1208 | } else if (cmd->state == UB_CMDST_CMD) { |
| 1175 | if (urb->status == -EPIPE) { | 1209 | switch (urb->status) { |
| 1210 | case 0: | ||
| 1211 | break; | ||
| 1212 | case -EOVERFLOW: | ||
| 1213 | goto Bad_End; | ||
| 1214 | case -EPIPE: | ||
| 1176 | rc = ub_submit_clear_stall(sc, cmd, sc->last_pipe); | 1215 | rc = ub_submit_clear_stall(sc, cmd, sc->last_pipe); |
| 1177 | if (rc != 0) { | 1216 | if (rc != 0) { |
| 1178 | printk(KERN_NOTICE "%s: " | 1217 | printk(KERN_NOTICE "%s: " |
| @@ -1182,17 +1221,20 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
| 1182 | * This is typically ENOMEM or some other such shit. | 1221 | * This is typically ENOMEM or some other such shit. |
| 1183 | * Retrying is pointless. Just do Bad End on it... | 1222 | * Retrying is pointless. Just do Bad End on it... |
| 1184 | */ | 1223 | */ |
| 1185 | goto Bad_End; | 1224 | ub_state_done(sc, cmd, rc); |
| 1225 | return; | ||
| 1186 | } | 1226 | } |
| 1187 | cmd->state = UB_CMDST_CLEAR; | 1227 | cmd->state = UB_CMDST_CLEAR; |
| 1188 | ub_cmdtr_state(sc, cmd); | 1228 | ub_cmdtr_state(sc, cmd); |
| 1189 | return; | 1229 | return; |
| 1190 | } | 1230 | case -ESHUTDOWN: /* unplug */ |
| 1191 | if (urb->status != 0) { | 1231 | case -EILSEQ: /* unplug timeout on uhci */ |
| 1232 | ub_state_done(sc, cmd, -ENODEV); | ||
| 1233 | return; | ||
| 1234 | default: | ||
| 1192 | goto Bad_End; | 1235 | goto Bad_End; |
| 1193 | } | 1236 | } |
| 1194 | if (urb->actual_length != US_BULK_CB_WRAP_LEN) { | 1237 | if (urb->actual_length != US_BULK_CB_WRAP_LEN) { |
| 1195 | /* XXX Must do reset here to unconfuse the device */ | ||
| 1196 | goto Bad_End; | 1238 | goto Bad_End; |
| 1197 | } | 1239 | } |
| 1198 | 1240 | ||
| @@ -1211,11 +1253,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
| 1211 | printk(KERN_NOTICE "%s: " | 1253 | printk(KERN_NOTICE "%s: " |
| 1212 | "unable to submit clear (%d)\n", | 1254 | "unable to submit clear (%d)\n", |
| 1213 | sc->name, rc); | 1255 | sc->name, rc); |
| 1214 | /* | 1256 | ub_state_done(sc, cmd, rc); |
| 1215 | * This is typically ENOMEM or some other such shit. | 1257 | return; |
| 1216 | * Retrying is pointless. Just do Bad End on it... | ||
| 1217 | */ | ||
| 1218 | goto Bad_End; | ||
| 1219 | } | 1258 | } |
| 1220 | cmd->state = UB_CMDST_CLR2STS; | 1259 | cmd->state = UB_CMDST_CLR2STS; |
| 1221 | ub_cmdtr_state(sc, cmd); | 1260 | ub_cmdtr_state(sc, cmd); |
| @@ -1224,14 +1263,50 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
| 1224 | if (urb->status == -EOVERFLOW) { | 1263 | if (urb->status == -EOVERFLOW) { |
| 1225 | /* | 1264 | /* |
| 1226 | * A babble? Failure, but we must transfer CSW now. | 1265 | * A babble? Failure, but we must transfer CSW now. |
| 1227 | * XXX This is going to end in perpetual babble. Reset. | ||
| 1228 | */ | 1266 | */ |
| 1229 | cmd->error = -EOVERFLOW; /* A cheap trick... */ | 1267 | cmd->error = -EOVERFLOW; /* A cheap trick... */ |
| 1230 | ub_state_stat(sc, cmd); | 1268 | ub_state_stat(sc, cmd); |
| 1231 | return; | 1269 | return; |
| 1232 | } | 1270 | } |
| 1233 | if (urb->status != 0) | 1271 | |
| 1234 | goto Bad_End; | 1272 | if (cmd->dir == UB_DIR_WRITE) { |
| 1273 | /* | ||
| 1274 | * Do not continue writes in case of a failure. | ||
| 1275 | * Doing so would cause sectors to be mixed up, | ||
| 1276 | * which is worse than sectors lost. | ||
| 1277 | * | ||
| 1278 | * We must try to read the CSW, or many devices | ||
| 1279 | * get confused. | ||
| 1280 | */ | ||
| 1281 | len = urb->actual_length; | ||
| 1282 | if (urb->status != 0 || | ||
| 1283 | len != cmd->sgv[cmd->current_sg].length) { | ||
| 1284 | cmd->act_len += len; | ||
| 1285 | ub_cmdtr_act_len(sc, cmd); | ||
| 1286 | |||
| 1287 | cmd->error = -EIO; | ||
| 1288 | ub_state_stat(sc, cmd); | ||
| 1289 | return; | ||
| 1290 | } | ||
| 1291 | |||
| 1292 | } else { | ||
| 1293 | /* | ||
| 1294 | * If an error occurs on read, we record it, and | ||
| 1295 | * continue to fetch data in order to avoid bubble. | ||
| 1296 | * | ||
| 1297 | * As a small shortcut, we stop if we detect that | ||
| 1298 | * a CSW mixed into data. | ||
| 1299 | */ | ||
| 1300 | if (urb->status != 0) | ||
| 1301 | cmd->error = -EIO; | ||
| 1302 | |||
| 1303 | len = urb->actual_length; | ||
| 1304 | if (urb->status != 0 || | ||
| 1305 | len != cmd->sgv[cmd->current_sg].length) { | ||
| 1306 | if ((len & 0x1FF) == US_BULK_CS_WRAP_LEN) | ||
| 1307 | goto Bad_End; | ||
| 1308 | } | ||
| 1309 | } | ||
| 1235 | 1310 | ||
| 1236 | cmd->act_len += urb->actual_length; | 1311 | cmd->act_len += urb->actual_length; |
| 1237 | ub_cmdtr_act_len(sc, cmd); | 1312 | ub_cmdtr_act_len(sc, cmd); |
| @@ -1249,11 +1324,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
| 1249 | printk(KERN_NOTICE "%s: " | 1324 | printk(KERN_NOTICE "%s: " |
| 1250 | "unable to submit clear (%d)\n", | 1325 | "unable to submit clear (%d)\n", |
| 1251 | sc->name, rc); | 1326 | sc->name, rc); |
| 1252 | /* | 1327 | ub_state_done(sc, cmd, rc); |
| 1253 | * This is typically ENOMEM or some other such shit. | 1328 | return; |
| 1254 | * Retrying is pointless. Just do Bad End on it... | ||
| 1255 | */ | ||
| 1256 | goto Bad_End; | ||
| 1257 | } | 1329 | } |
| 1258 | 1330 | ||
| 1259 | /* | 1331 | /* |
| @@ -1266,14 +1338,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
| 1266 | ub_cmdtr_state(sc, cmd); | 1338 | ub_cmdtr_state(sc, cmd); |
| 1267 | return; | 1339 | return; |
| 1268 | } | 1340 | } |
| 1269 | if (urb->status == -EOVERFLOW) { | 1341 | |
| 1270 | /* | 1342 | /* Catch everything, including -EOVERFLOW and other nasties. */ |
| 1271 | * XXX We are screwed here. Retrying is pointless, | ||
| 1272 | * because the pipelined data will not get in until | ||
| 1273 | * we read with a big enough buffer. We must reset XXX. | ||
| 1274 | */ | ||
| 1275 | goto Bad_End; | ||
| 1276 | } | ||
| 1277 | if (urb->status != 0) | 1343 | if (urb->status != 0) |
| 1278 | goto Bad_End; | 1344 | goto Bad_End; |
| 1279 | 1345 | ||
| @@ -1319,15 +1385,15 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
| 1319 | return; | 1385 | return; |
| 1320 | } | 1386 | } |
| 1321 | 1387 | ||
| 1322 | rc = le32_to_cpu(bcs->Residue); | 1388 | len = le32_to_cpu(bcs->Residue); |
| 1323 | if (rc != cmd->len - cmd->act_len) { | 1389 | if (len != cmd->len - cmd->act_len) { |
| 1324 | /* | 1390 | /* |
| 1325 | * It is all right to transfer less, the caller has | 1391 | * It is all right to transfer less, the caller has |
| 1326 | * to check. But it's not all right if the device | 1392 | * to check. But it's not all right if the device |
| 1327 | * counts disagree with our counts. | 1393 | * counts disagree with our counts. |
| 1328 | */ | 1394 | */ |
| 1329 | /* P3 */ printk("%s: resid %d len %d act %d\n", | 1395 | /* P3 */ printk("%s: resid %d len %d act %d\n", |
| 1330 | sc->name, rc, cmd->len, cmd->act_len); | 1396 | sc->name, len, cmd->len, cmd->act_len); |
| 1331 | goto Bad_End; | 1397 | goto Bad_End; |
| 1332 | } | 1398 | } |
| 1333 | 1399 | ||
| @@ -1338,13 +1404,13 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
| 1338 | ub_state_sense(sc, cmd); | 1404 | ub_state_sense(sc, cmd); |
| 1339 | return; | 1405 | return; |
| 1340 | case US_BULK_STAT_PHASE: | 1406 | case US_BULK_STAT_PHASE: |
| 1341 | /* XXX We must reset the transport here */ | ||
| 1342 | /* P3 */ printk("%s: status PHASE\n", sc->name); | 1407 | /* P3 */ printk("%s: status PHASE\n", sc->name); |
| 1343 | goto Bad_End; | 1408 | goto Bad_End; |
| 1344 | default: | 1409 | default: |
| 1345 | printk(KERN_INFO "%s: unknown CSW status 0x%x\n", | 1410 | printk(KERN_INFO "%s: unknown CSW status 0x%x\n", |
| 1346 | sc->name, bcs->Status); | 1411 | sc->name, bcs->Status); |
| 1347 | goto Bad_End; | 1412 | ub_state_done(sc, cmd, -EINVAL); |
| 1413 | return; | ||
| 1348 | } | 1414 | } |
| 1349 | 1415 | ||
| 1350 | /* Not zeroing error to preserve a babble indicator */ | 1416 | /* Not zeroing error to preserve a babble indicator */ |
| @@ -1364,7 +1430,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
| 1364 | printk(KERN_WARNING "%s: " | 1430 | printk(KERN_WARNING "%s: " |
| 1365 | "wrong command state %d\n", | 1431 | "wrong command state %d\n", |
| 1366 | sc->name, cmd->state); | 1432 | sc->name, cmd->state); |
| 1367 | goto Bad_End; | 1433 | ub_state_done(sc, cmd, -EINVAL); |
| 1434 | return; | ||
| 1368 | } | 1435 | } |
| 1369 | return; | 1436 | return; |
| 1370 | 1437 | ||
| @@ -1612,6 +1679,93 @@ static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd) | |||
| 1612 | } | 1679 | } |
| 1613 | 1680 | ||
| 1614 | /* | 1681 | /* |
| 1682 | * Reset management | ||
| 1683 | */ | ||
| 1684 | |||
| 1685 | static void ub_reset_enter(struct ub_dev *sc) | ||
| 1686 | { | ||
| 1687 | |||
| 1688 | if (sc->reset) { | ||
| 1689 | /* This happens often on multi-LUN devices. */ | ||
| 1690 | return; | ||
| 1691 | } | ||
| 1692 | sc->reset = 1; | ||
| 1693 | |||
| 1694 | #if 0 /* Not needed because the disconnect waits for us. */ | ||
| 1695 | unsigned long flags; | ||
| 1696 | spin_lock_irqsave(&ub_lock, flags); | ||
| 1697 | sc->openc++; | ||
| 1698 | spin_unlock_irqrestore(&ub_lock, flags); | ||
| 1699 | #endif | ||
| 1700 | |||
| 1701 | #if 0 /* We let them stop themselves. */ | ||
| 1702 | struct list_head *p; | ||
| 1703 | struct ub_lun *lun; | ||
| 1704 | list_for_each(p, &sc->luns) { | ||
| 1705 | lun = list_entry(p, struct ub_lun, link); | ||
| 1706 | blk_stop_queue(lun->disk->queue); | ||
| 1707 | } | ||
| 1708 | #endif | ||
| 1709 | |||
| 1710 | schedule_work(&sc->reset_work); | ||
| 1711 | } | ||
| 1712 | |||
| 1713 | static void ub_reset_task(void *arg) | ||
| 1714 | { | ||
| 1715 | struct ub_dev *sc = arg; | ||
| 1716 | unsigned long flags; | ||
| 1717 | struct list_head *p; | ||
| 1718 | struct ub_lun *lun; | ||
| 1719 | int lkr, rc; | ||
| 1720 | |||
| 1721 | if (!sc->reset) { | ||
| 1722 | printk(KERN_WARNING "%s: Running reset unrequested\n", | ||
| 1723 | sc->name); | ||
| 1724 | return; | ||
| 1725 | } | ||
| 1726 | |||
| 1727 | if (atomic_read(&sc->poison)) { | ||
| 1728 | printk(KERN_NOTICE "%s: Not resetting disconnected device\n", | ||
| 1729 | sc->name); /* P3 This floods. Remove soon. XXX */ | ||
| 1730 | } else if (sc->dev->actconfig->desc.bNumInterfaces != 1) { | ||
| 1731 | printk(KERN_NOTICE "%s: Not resetting multi-interface device\n", | ||
| 1732 | sc->name); /* P3 This floods. Remove soon. XXX */ | ||
| 1733 | } else { | ||
| 1734 | if ((lkr = usb_lock_device_for_reset(sc->dev, sc->intf)) < 0) { | ||
| 1735 | printk(KERN_NOTICE | ||
| 1736 | "%s: usb_lock_device_for_reset failed (%d)\n", | ||
| 1737 | sc->name, lkr); | ||
| 1738 | } else { | ||
| 1739 | rc = usb_reset_device(sc->dev); | ||
| 1740 | if (rc < 0) { | ||
| 1741 | printk(KERN_NOTICE "%s: " | ||
| 1742 | "usb_lock_device_for_reset failed (%d)\n", | ||
| 1743 | sc->name, rc); | ||
| 1744 | } | ||
| 1745 | |||
| 1746 | if (lkr) | ||
| 1747 | usb_unlock_device(sc->dev); | ||
| 1748 | } | ||
| 1749 | } | ||
| 1750 | |||
| 1751 | /* | ||
| 1752 | * In theory, no commands can be running while reset is active, | ||
| 1753 | * so nobody can ask for another reset, and so we do not need any | ||
| 1754 | * queues of resets or anything. We do need a spinlock though, | ||
| 1755 | * to interact with block layer. | ||
| 1756 | */ | ||
| 1757 | spin_lock_irqsave(&sc->lock, flags); | ||
| 1758 | sc->reset = 0; | ||
| 1759 | tasklet_schedule(&sc->tasklet); | ||
| 1760 | list_for_each(p, &sc->luns) { | ||
| 1761 | lun = list_entry(p, struct ub_lun, link); | ||
| 1762 | blk_start_queue(lun->disk->queue); | ||
| 1763 | } | ||
| 1764 | wake_up(&sc->reset_wait); | ||
| 1765 | spin_unlock_irqrestore(&sc->lock, flags); | ||
| 1766 | } | ||
| 1767 | |||
| 1768 | /* | ||
| 1615 | * This is called from a process context. | 1769 | * This is called from a process context. |
| 1616 | */ | 1770 | */ |
| 1617 | static void ub_revalidate(struct ub_dev *sc, struct ub_lun *lun) | 1771 | static void ub_revalidate(struct ub_dev *sc, struct ub_lun *lun) |
| @@ -2146,7 +2300,7 @@ static int ub_get_pipes(struct ub_dev *sc, struct usb_device *dev, | |||
| 2146 | if (ep_in == NULL || ep_out == NULL) { | 2300 | if (ep_in == NULL || ep_out == NULL) { |
| 2147 | printk(KERN_NOTICE "%s: failed endpoint check\n", | 2301 | printk(KERN_NOTICE "%s: failed endpoint check\n", |
| 2148 | sc->name); | 2302 | sc->name); |
| 2149 | return -EIO; | 2303 | return -ENODEV; |
| 2150 | } | 2304 | } |
| 2151 | 2305 | ||
| 2152 | /* Calculate and store the pipe values */ | 2306 | /* Calculate and store the pipe values */ |
| @@ -2172,6 +2326,9 @@ static int ub_probe(struct usb_interface *intf, | |||
| 2172 | int rc; | 2326 | int rc; |
| 2173 | int i; | 2327 | int i; |
| 2174 | 2328 | ||
| 2329 | if (usb_usual_check_type(dev_id, USB_US_TYPE_UB)) | ||
| 2330 | return -ENXIO; | ||
| 2331 | |||
| 2175 | rc = -ENOMEM; | 2332 | rc = -ENOMEM; |
| 2176 | if ((sc = kmalloc(sizeof(struct ub_dev), GFP_KERNEL)) == NULL) | 2333 | if ((sc = kmalloc(sizeof(struct ub_dev), GFP_KERNEL)) == NULL) |
| 2177 | goto err_core; | 2334 | goto err_core; |
| @@ -2181,6 +2338,8 @@ static int ub_probe(struct usb_interface *intf, | |||
| 2181 | usb_init_urb(&sc->work_urb); | 2338 | usb_init_urb(&sc->work_urb); |
| 2182 | tasklet_init(&sc->tasklet, ub_scsi_action, (unsigned long)sc); | 2339 | tasklet_init(&sc->tasklet, ub_scsi_action, (unsigned long)sc); |
| 2183 | atomic_set(&sc->poison, 0); | 2340 | atomic_set(&sc->poison, 0); |
| 2341 | INIT_WORK(&sc->reset_work, ub_reset_task, sc); | ||
| 2342 | init_waitqueue_head(&sc->reset_wait); | ||
| 2184 | 2343 | ||
| 2185 | init_timer(&sc->work_timer); | 2344 | init_timer(&sc->work_timer); |
| 2186 | sc->work_timer.data = (unsigned long) sc; | 2345 | sc->work_timer.data = (unsigned long) sc; |
| @@ -2201,7 +2360,8 @@ static int ub_probe(struct usb_interface *intf, | |||
| 2201 | 2360 | ||
| 2202 | /* XXX Verify that we can handle the device (from descriptors) */ | 2361 | /* XXX Verify that we can handle the device (from descriptors) */ |
| 2203 | 2362 | ||
| 2204 | ub_get_pipes(sc, sc->dev, intf); | 2363 | if (ub_get_pipes(sc, sc->dev, intf) != 0) |
| 2364 | goto err_dev_desc; | ||
| 2205 | 2365 | ||
| 2206 | if (device_create_file(&sc->intf->dev, &dev_attr_diag) != 0) | 2366 | if (device_create_file(&sc->intf->dev, &dev_attr_diag) != 0) |
| 2207 | goto err_diag; | 2367 | goto err_diag; |
| @@ -2272,6 +2432,7 @@ static int ub_probe(struct usb_interface *intf, | |||
| 2272 | 2432 | ||
| 2273 | /* device_remove_file(&sc->intf->dev, &dev_attr_diag); */ | 2433 | /* device_remove_file(&sc->intf->dev, &dev_attr_diag); */ |
| 2274 | err_diag: | 2434 | err_diag: |
| 2435 | err_dev_desc: | ||
| 2275 | usb_set_intfdata(intf, NULL); | 2436 | usb_set_intfdata(intf, NULL); |
| 2276 | // usb_put_intf(sc->intf); | 2437 | // usb_put_intf(sc->intf); |
| 2277 | usb_put_dev(sc->dev); | 2438 | usb_put_dev(sc->dev); |
| @@ -2309,14 +2470,14 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum) | |||
| 2309 | ub_revalidate(sc, lun); | 2470 | ub_revalidate(sc, lun); |
| 2310 | 2471 | ||
| 2311 | rc = -ENOMEM; | 2472 | rc = -ENOMEM; |
| 2312 | if ((disk = alloc_disk(UB_MINORS_PER_MAJOR)) == NULL) | 2473 | if ((disk = alloc_disk(UB_PARTS_PER_LUN)) == NULL) |
| 2313 | goto err_diskalloc; | 2474 | goto err_diskalloc; |
| 2314 | 2475 | ||
| 2315 | lun->disk = disk; | 2476 | lun->disk = disk; |
| 2316 | sprintf(disk->disk_name, DRV_NAME "%c", lun->id + 'a'); | 2477 | sprintf(disk->disk_name, DRV_NAME "%c", lun->id + 'a'); |
| 2317 | sprintf(disk->devfs_name, DEVFS_NAME "/%c", lun->id + 'a'); | 2478 | sprintf(disk->devfs_name, DEVFS_NAME "/%c", lun->id + 'a'); |
| 2318 | disk->major = UB_MAJOR; | 2479 | disk->major = UB_MAJOR; |
| 2319 | disk->first_minor = lun->id * UB_MINORS_PER_MAJOR; | 2480 | disk->first_minor = lun->id * UB_PARTS_PER_LUN; |
| 2320 | disk->fops = &ub_bd_fops; | 2481 | disk->fops = &ub_bd_fops; |
| 2321 | disk->private_data = lun; | 2482 | disk->private_data = lun; |
| 2322 | disk->driverfs_dev = &sc->intf->dev; | 2483 | disk->driverfs_dev = &sc->intf->dev; |
| @@ -2380,6 +2541,11 @@ static void ub_disconnect(struct usb_interface *intf) | |||
| 2380 | atomic_set(&sc->poison, 1); | 2541 | atomic_set(&sc->poison, 1); |
| 2381 | 2542 | ||
| 2382 | /* | 2543 | /* |
| 2544 | * Wait for reset to end, if any. | ||
| 2545 | */ | ||
| 2546 | wait_event(sc->reset_wait, !sc->reset); | ||
| 2547 | |||
| 2548 | /* | ||
| 2383 | * Blow away queued commands. | 2549 | * Blow away queued commands. |
| 2384 | * | 2550 | * |
| 2385 | * Actually, this never works, because before we get here | 2551 | * Actually, this never works, because before we get here |
| @@ -2392,7 +2558,7 @@ static void ub_disconnect(struct usb_interface *intf) | |||
| 2392 | { | 2558 | { |
| 2393 | struct ub_scsi_cmd *cmd; | 2559 | struct ub_scsi_cmd *cmd; |
| 2394 | int cnt = 0; | 2560 | int cnt = 0; |
| 2395 | while ((cmd = ub_cmdq_pop(sc)) != NULL) { | 2561 | while ((cmd = ub_cmdq_peek(sc)) != NULL) { |
| 2396 | cmd->error = -ENOTCONN; | 2562 | cmd->error = -ENOTCONN; |
| 2397 | cmd->state = UB_CMDST_DONE; | 2563 | cmd->state = UB_CMDST_DONE; |
| 2398 | ub_cmdtr_state(sc, cmd); | 2564 | ub_cmdtr_state(sc, cmd); |
| @@ -2461,7 +2627,6 @@ static void ub_disconnect(struct usb_interface *intf) | |||
| 2461 | } | 2627 | } |
| 2462 | 2628 | ||
| 2463 | static struct usb_driver ub_driver = { | 2629 | static struct usb_driver ub_driver = { |
| 2464 | .owner = THIS_MODULE, | ||
| 2465 | .name = "ub", | 2630 | .name = "ub", |
| 2466 | .probe = ub_probe, | 2631 | .probe = ub_probe, |
| 2467 | .disconnect = ub_disconnect, | 2632 | .disconnect = ub_disconnect, |
| @@ -2479,6 +2644,7 @@ static int __init ub_init(void) | |||
| 2479 | if ((rc = usb_register(&ub_driver)) != 0) | 2644 | if ((rc = usb_register(&ub_driver)) != 0) |
| 2480 | goto err_register; | 2645 | goto err_register; |
| 2481 | 2646 | ||
| 2647 | usb_usual_set_present(USB_US_TYPE_UB); | ||
| 2482 | return 0; | 2648 | return 0; |
| 2483 | 2649 | ||
| 2484 | err_register: | 2650 | err_register: |
| @@ -2494,6 +2660,7 @@ static void __exit ub_exit(void) | |||
| 2494 | 2660 | ||
| 2495 | devfs_remove(DEVFS_NAME); | 2661 | devfs_remove(DEVFS_NAME); |
| 2496 | unregister_blkdev(UB_MAJOR, DRV_NAME); | 2662 | unregister_blkdev(UB_MAJOR, DRV_NAME); |
| 2663 | usb_usual_clear_present(USB_US_TYPE_UB); | ||
| 2497 | } | 2664 | } |
| 2498 | 2665 | ||
| 2499 | module_init(ub_init); | 2666 | module_init(ub_init); |
diff --git a/drivers/bluetooth/bcm203x.c b/drivers/bluetooth/bcm203x.c index 8e7fb3551775..3e7a067cc087 100644 --- a/drivers/bluetooth/bcm203x.c +++ b/drivers/bluetooth/bcm203x.c | |||
| @@ -275,7 +275,6 @@ static void bcm203x_disconnect(struct usb_interface *intf) | |||
| 275 | } | 275 | } |
| 276 | 276 | ||
| 277 | static struct usb_driver bcm203x_driver = { | 277 | static struct usb_driver bcm203x_driver = { |
| 278 | .owner = THIS_MODULE, | ||
| 279 | .name = "bcm203x", | 278 | .name = "bcm203x", |
| 280 | .probe = bcm203x_probe, | 279 | .probe = bcm203x_probe, |
| 281 | .disconnect = bcm203x_disconnect, | 280 | .disconnect = bcm203x_disconnect, |
diff --git a/drivers/bluetooth/bfusb.c b/drivers/bluetooth/bfusb.c index 067e27893e4a..8947c8837dac 100644 --- a/drivers/bluetooth/bfusb.c +++ b/drivers/bluetooth/bfusb.c | |||
| @@ -768,7 +768,6 @@ static void bfusb_disconnect(struct usb_interface *intf) | |||
| 768 | } | 768 | } |
| 769 | 769 | ||
| 770 | static struct usb_driver bfusb_driver = { | 770 | static struct usb_driver bfusb_driver = { |
| 771 | .owner = THIS_MODULE, | ||
| 772 | .name = "bfusb", | 771 | .name = "bfusb", |
| 773 | .probe = bfusb_probe, | 772 | .probe = bfusb_probe, |
| 774 | .disconnect = bfusb_disconnect, | 773 | .disconnect = bfusb_disconnect, |
diff --git a/drivers/bluetooth/bpa10x.c b/drivers/bluetooth/bpa10x.c index 394796315adc..9446960ac742 100644 --- a/drivers/bluetooth/bpa10x.c +++ b/drivers/bluetooth/bpa10x.c | |||
| @@ -619,7 +619,6 @@ static void bpa10x_disconnect(struct usb_interface *intf) | |||
| 619 | } | 619 | } |
| 620 | 620 | ||
| 621 | static struct usb_driver bpa10x_driver = { | 621 | static struct usb_driver bpa10x_driver = { |
| 622 | .owner = THIS_MODULE, | ||
| 623 | .name = "bpa10x", | 622 | .name = "bpa10x", |
| 624 | .probe = bpa10x_probe, | 623 | .probe = bpa10x_probe, |
| 625 | .disconnect = bpa10x_disconnect, | 624 | .disconnect = bpa10x_disconnect, |
diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c index 057cb2b6e6d1..92382e823285 100644 --- a/drivers/bluetooth/hci_usb.c +++ b/drivers/bluetooth/hci_usb.c | |||
| @@ -1044,7 +1044,6 @@ static void hci_usb_disconnect(struct usb_interface *intf) | |||
| 1044 | } | 1044 | } |
| 1045 | 1045 | ||
| 1046 | static struct usb_driver hci_usb_driver = { | 1046 | static struct usb_driver hci_usb_driver = { |
| 1047 | .owner = THIS_MODULE, | ||
| 1048 | .name = "hci_usb", | 1047 | .name = "hci_usb", |
| 1049 | .probe = hci_usb_probe, | 1048 | .probe = hci_usb_probe, |
| 1050 | .disconnect = hci_usb_disconnect, | 1049 | .disconnect = hci_usb_disconnect, |
diff --git a/drivers/char/watchdog/pcwd_usb.c b/drivers/char/watchdog/pcwd_usb.c index 092e9b133750..1533f56baa42 100644 --- a/drivers/char/watchdog/pcwd_usb.c +++ b/drivers/char/watchdog/pcwd_usb.c | |||
| @@ -151,7 +151,6 @@ static void usb_pcwd_disconnect (struct usb_interface *interface); | |||
| 151 | 151 | ||
| 152 | /* usb specific object needed to register this driver with the usb subsystem */ | 152 | /* usb specific object needed to register this driver with the usb subsystem */ |
| 153 | static struct usb_driver usb_pcwd_driver = { | 153 | static struct usb_driver usb_pcwd_driver = { |
| 154 | .owner = THIS_MODULE, | ||
| 155 | .name = DRIVER_NAME, | 154 | .name = DRIVER_NAME, |
| 156 | .probe = usb_pcwd_probe, | 155 | .probe = usb_pcwd_probe, |
| 157 | .disconnect = usb_pcwd_disconnect, | 156 | .disconnect = usb_pcwd_disconnect, |
diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c index 64b4a3080985..bc2fce60f9f8 100644 --- a/drivers/input/joystick/iforce/iforce-usb.c +++ b/drivers/input/joystick/iforce/iforce-usb.c | |||
| @@ -235,7 +235,6 @@ static struct usb_device_id iforce_usb_ids [] = { | |||
| 235 | MODULE_DEVICE_TABLE (usb, iforce_usb_ids); | 235 | MODULE_DEVICE_TABLE (usb, iforce_usb_ids); |
| 236 | 236 | ||
| 237 | struct usb_driver iforce_usb_driver = { | 237 | struct usb_driver iforce_usb_driver = { |
| 238 | .owner = THIS_MODULE, | ||
| 239 | .name = "iforce", | 238 | .name = "iforce", |
| 240 | .probe = iforce_usb_probe, | 239 | .probe = iforce_usb_probe, |
| 241 | .disconnect = iforce_usb_disconnect, | 240 | .disconnect = iforce_usb_disconnect, |
diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c index f8457ef48826..ca5b4a3b683e 100644 --- a/drivers/isdn/hisax/hfc_usb.c +++ b/drivers/isdn/hisax/hfc_usb.c | |||
| @@ -1715,7 +1715,6 @@ hfc_usb_disconnect(struct usb_interface | |||
| 1715 | /* our driver information structure */ | 1715 | /* our driver information structure */ |
| 1716 | /************************************/ | 1716 | /************************************/ |
| 1717 | static struct usb_driver hfc_drv = { | 1717 | static struct usb_driver hfc_drv = { |
| 1718 | .owner = THIS_MODULE, | ||
| 1719 | .name = "hfc_usb", | 1718 | .name = "hfc_usb", |
| 1720 | .id_table = hfcusb_idtab, | 1719 | .id_table = hfcusb_idtab, |
| 1721 | .probe = hfc_usb_probe, | 1720 | .probe = hfc_usb_probe, |
diff --git a/drivers/isdn/hisax/st5481_init.c b/drivers/isdn/hisax/st5481_init.c index 8e192a3a3490..99cb0f3d59a1 100644 --- a/drivers/isdn/hisax/st5481_init.c +++ b/drivers/isdn/hisax/st5481_init.c | |||
| @@ -180,7 +180,6 @@ static struct usb_device_id st5481_ids[] = { | |||
| 180 | MODULE_DEVICE_TABLE (usb, st5481_ids); | 180 | MODULE_DEVICE_TABLE (usb, st5481_ids); |
| 181 | 181 | ||
| 182 | static struct usb_driver st5481_usb_driver = { | 182 | static struct usb_driver st5481_usb_driver = { |
| 183 | .owner = THIS_MODULE, | ||
| 184 | .name = "st5481_usb", | 183 | .name = "st5481_usb", |
| 185 | .probe = probe_st5481, | 184 | .probe = probe_st5481, |
| 186 | .disconnect = disconnect_st5481, | 185 | .disconnect = disconnect_st5481, |
diff --git a/drivers/media/dvb/b2c2/flexcop-usb.c b/drivers/media/dvb/b2c2/flexcop-usb.c index 0a78ba3737a5..a6c91db40ad6 100644 --- a/drivers/media/dvb/b2c2/flexcop-usb.c +++ b/drivers/media/dvb/b2c2/flexcop-usb.c | |||
| @@ -544,7 +544,6 @@ static struct usb_device_id flexcop_usb_table [] = { | |||
| 544 | 544 | ||
| 545 | /* usb specific object needed to register this driver with the usb subsystem */ | 545 | /* usb specific object needed to register this driver with the usb subsystem */ |
| 546 | static struct usb_driver flexcop_usb_driver = { | 546 | static struct usb_driver flexcop_usb_driver = { |
| 547 | .owner = THIS_MODULE, | ||
| 548 | .name = "b2c2_flexcop_usb", | 547 | .name = "b2c2_flexcop_usb", |
| 549 | .probe = flexcop_usb_probe, | 548 | .probe = flexcop_usb_probe, |
| 550 | .disconnect = flexcop_usb_disconnect, | 549 | .disconnect = flexcop_usb_disconnect, |
diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c index 336fc284fa52..b996fb59b7e4 100644 --- a/drivers/media/dvb/cinergyT2/cinergyT2.c +++ b/drivers/media/dvb/cinergyT2/cinergyT2.c | |||
| @@ -986,7 +986,6 @@ static const struct usb_device_id cinergyt2_table [] __devinitdata = { | |||
| 986 | MODULE_DEVICE_TABLE(usb, cinergyt2_table); | 986 | MODULE_DEVICE_TABLE(usb, cinergyt2_table); |
| 987 | 987 | ||
| 988 | static struct usb_driver cinergyt2_driver = { | 988 | static struct usb_driver cinergyt2_driver = { |
| 989 | .owner = THIS_MODULE, | ||
| 990 | .name = "cinergyT2", | 989 | .name = "cinergyT2", |
| 991 | .probe = cinergyt2_probe, | 990 | .probe = cinergyt2_probe, |
| 992 | .disconnect = cinergyt2_disconnect, | 991 | .disconnect = cinergyt2_disconnect, |
diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/dvb/dvb-usb/a800.c index 8c7beffb045f..ce44aa6bbb83 100644 --- a/drivers/media/dvb/dvb-usb/a800.c +++ b/drivers/media/dvb/dvb-usb/a800.c | |||
| @@ -144,7 +144,6 @@ static struct dvb_usb_properties a800_properties = { | |||
| 144 | }; | 144 | }; |
| 145 | 145 | ||
| 146 | static struct usb_driver a800_driver = { | 146 | static struct usb_driver a800_driver = { |
| 147 | .owner = THIS_MODULE, | ||
| 148 | .name = "dvb_usb_a800", | 147 | .name = "dvb_usb_a800", |
| 149 | .probe = a800_probe, | 148 | .probe = a800_probe, |
| 150 | .disconnect = dvb_usb_device_exit, | 149 | .disconnect = dvb_usb_device_exit, |
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c index 3fe383f4bb4c..d05fab01cccd 100644 --- a/drivers/media/dvb/dvb-usb/cxusb.c +++ b/drivers/media/dvb/dvb-usb/cxusb.c | |||
| @@ -241,7 +241,6 @@ static struct dvb_usb_properties cxusb_properties = { | |||
| 241 | }; | 241 | }; |
| 242 | 242 | ||
| 243 | static struct usb_driver cxusb_driver = { | 243 | static struct usb_driver cxusb_driver = { |
| 244 | .owner = THIS_MODULE, | ||
| 245 | .name = "dvb_usb_cxusb", | 244 | .name = "dvb_usb_cxusb", |
| 246 | .probe = cxusb_probe, | 245 | .probe = cxusb_probe, |
| 247 | .disconnect = dvb_usb_device_exit, | 246 | .disconnect = dvb_usb_device_exit, |
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c index aa271a2496d5..52ac3e5adf5d 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-mb.c +++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c | |||
| @@ -373,7 +373,6 @@ static struct dvb_usb_properties artec_t1_usb2_properties = { | |||
| 373 | }; | 373 | }; |
| 374 | 374 | ||
| 375 | static struct usb_driver dibusb_driver = { | 375 | static struct usb_driver dibusb_driver = { |
| 376 | .owner = THIS_MODULE, | ||
| 377 | .name = "dvb_usb_dibusb_mb", | 376 | .name = "dvb_usb_dibusb_mb", |
| 378 | .probe = dibusb_probe, | 377 | .probe = dibusb_probe, |
| 379 | .disconnect = dvb_usb_device_exit, | 378 | .disconnect = dvb_usb_device_exit, |
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mc.c b/drivers/media/dvb/dvb-usb/dibusb-mc.c index 6a0912eab396..55802fba3c29 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-mc.c +++ b/drivers/media/dvb/dvb-usb/dibusb-mc.c | |||
| @@ -82,7 +82,6 @@ static struct dvb_usb_properties dibusb_mc_properties = { | |||
| 82 | }; | 82 | }; |
| 83 | 83 | ||
| 84 | static struct usb_driver dibusb_mc_driver = { | 84 | static struct usb_driver dibusb_mc_driver = { |
| 85 | .owner = THIS_MODULE, | ||
| 86 | .name = "dvb_usb_dibusb_mc", | 85 | .name = "dvb_usb_dibusb_mc", |
| 87 | .probe = dibusb_mc_probe, | 86 | .probe = dibusb_mc_probe, |
| 88 | .disconnect = dvb_usb_device_exit, | 87 | .disconnect = dvb_usb_device_exit, |
diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c index f98e306a5759..450417a9e64b 100644 --- a/drivers/media/dvb/dvb-usb/digitv.c +++ b/drivers/media/dvb/dvb-usb/digitv.c | |||
| @@ -233,7 +233,6 @@ static struct dvb_usb_properties digitv_properties = { | |||
| 233 | }; | 233 | }; |
| 234 | 234 | ||
| 235 | static struct usb_driver digitv_driver = { | 235 | static struct usb_driver digitv_driver = { |
| 236 | .owner = THIS_MODULE, | ||
| 237 | .name = "dvb_usb_digitv", | 236 | .name = "dvb_usb_digitv", |
| 238 | .probe = digitv_probe, | 237 | .probe = digitv_probe, |
| 239 | .disconnect = dvb_usb_device_exit, | 238 | .disconnect = dvb_usb_device_exit, |
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c index b595476332cd..6e2bac873445 100644 --- a/drivers/media/dvb/dvb-usb/dtt200u.c +++ b/drivers/media/dvb/dvb-usb/dtt200u.c | |||
| @@ -198,7 +198,6 @@ static struct dvb_usb_properties wt220u_properties = { | |||
| 198 | 198 | ||
| 199 | /* usb specific object needed to register this driver with the usb subsystem */ | 199 | /* usb specific object needed to register this driver with the usb subsystem */ |
| 200 | static struct usb_driver dtt200u_usb_driver = { | 200 | static struct usb_driver dtt200u_usb_driver = { |
| 201 | .owner = THIS_MODULE, | ||
| 202 | .name = "dvb_usb_dtt200u", | 201 | .name = "dvb_usb_dtt200u", |
| 203 | .probe = dtt200u_usb_probe, | 202 | .probe = dtt200u_usb_probe, |
| 204 | .disconnect = dvb_usb_device_exit, | 203 | .disconnect = dvb_usb_device_exit, |
diff --git a/drivers/media/dvb/dvb-usb/nova-t-usb2.c b/drivers/media/dvb/dvb-usb/nova-t-usb2.c index 1841a66427bf..fac48fc7a4ac 100644 --- a/drivers/media/dvb/dvb-usb/nova-t-usb2.c +++ b/drivers/media/dvb/dvb-usb/nova-t-usb2.c | |||
| @@ -202,7 +202,6 @@ static struct dvb_usb_properties nova_t_properties = { | |||
| 202 | }; | 202 | }; |
| 203 | 203 | ||
| 204 | static struct usb_driver nova_t_driver = { | 204 | static struct usb_driver nova_t_driver = { |
| 205 | .owner = THIS_MODULE, | ||
| 206 | .name = "dvb_usb_nova_t_usb2", | 205 | .name = "dvb_usb_nova_t_usb2", |
| 207 | .probe = nova_t_probe, | 206 | .probe = nova_t_probe, |
| 208 | .disconnect = dvb_usb_device_exit, | 207 | .disconnect = dvb_usb_device_exit, |
diff --git a/drivers/media/dvb/dvb-usb/umt-010.c b/drivers/media/dvb/dvb-usb/umt-010.c index 6fd67657c269..14f1911c79bb 100644 --- a/drivers/media/dvb/dvb-usb/umt-010.c +++ b/drivers/media/dvb/dvb-usb/umt-010.c | |||
| @@ -128,7 +128,6 @@ static struct dvb_usb_properties umt_properties = { | |||
| 128 | }; | 128 | }; |
| 129 | 129 | ||
| 130 | static struct usb_driver umt_driver = { | 130 | static struct usb_driver umt_driver = { |
| 131 | .owner = THIS_MODULE, | ||
| 132 | .name = "dvb_usb_umt_010", | 131 | .name = "dvb_usb_umt_010", |
| 133 | .probe = umt_probe, | 132 | .probe = umt_probe, |
| 134 | .disconnect = dvb_usb_device_exit, | 133 | .disconnect = dvb_usb_device_exit, |
diff --git a/drivers/media/dvb/dvb-usb/vp702x.c b/drivers/media/dvb/dvb-usb/vp702x.c index de13c04e8e64..afa00fdb5ec0 100644 --- a/drivers/media/dvb/dvb-usb/vp702x.c +++ b/drivers/media/dvb/dvb-usb/vp702x.c | |||
| @@ -256,7 +256,6 @@ static struct dvb_usb_properties vp702x_properties = { | |||
| 256 | 256 | ||
| 257 | /* usb specific object needed to register this driver with the usb subsystem */ | 257 | /* usb specific object needed to register this driver with the usb subsystem */ |
| 258 | static struct usb_driver vp702x_usb_driver = { | 258 | static struct usb_driver vp702x_usb_driver = { |
| 259 | .owner = THIS_MODULE, | ||
| 260 | .name = "dvb-usb-vp702x", | 259 | .name = "dvb-usb-vp702x", |
| 261 | .probe = vp702x_usb_probe, | 260 | .probe = vp702x_usb_probe, |
| 262 | .disconnect = dvb_usb_device_exit, | 261 | .disconnect = dvb_usb_device_exit, |
diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c index 75765e3a569c..3835235b68df 100644 --- a/drivers/media/dvb/dvb-usb/vp7045.c +++ b/drivers/media/dvb/dvb-usb/vp7045.c | |||
| @@ -253,7 +253,6 @@ static struct dvb_usb_properties vp7045_properties = { | |||
| 253 | 253 | ||
| 254 | /* usb specific object needed to register this driver with the usb subsystem */ | 254 | /* usb specific object needed to register this driver with the usb subsystem */ |
| 255 | static struct usb_driver vp7045_usb_driver = { | 255 | static struct usb_driver vp7045_usb_driver = { |
| 256 | .owner = THIS_MODULE, | ||
| 257 | .name = "dvb_usb_vp7045", | 256 | .name = "dvb_usb_vp7045", |
| 258 | .probe = vp7045_usb_probe, | 257 | .probe = vp7045_usb_probe, |
| 259 | .disconnect = dvb_usb_device_exit, | 258 | .disconnect = dvb_usb_device_exit, |
diff --git a/drivers/media/video/cpia_usb.c b/drivers/media/video/cpia_usb.c index 9774e94d1e7d..1439cb752874 100644 --- a/drivers/media/video/cpia_usb.c +++ b/drivers/media/video/cpia_usb.c | |||
| @@ -582,7 +582,6 @@ MODULE_LICENSE("GPL"); | |||
| 582 | 582 | ||
| 583 | 583 | ||
| 584 | static struct usb_driver cpia_driver = { | 584 | static struct usb_driver cpia_driver = { |
| 585 | .owner = THIS_MODULE, | ||
| 586 | .name = "cpia", | 585 | .name = "cpia", |
| 587 | .probe = cpia_probe, | 586 | .probe = cpia_probe, |
| 588 | .disconnect = cpia_disconnect, | 587 | .disconnect = cpia_disconnect, |
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 06d76879bde2..3a56120397ae 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c | |||
| @@ -1884,7 +1884,6 @@ static void em28xx_usb_disconnect(struct usb_interface *interface) | |||
| 1884 | } | 1884 | } |
| 1885 | 1885 | ||
| 1886 | static struct usb_driver em28xx_usb_driver = { | 1886 | static struct usb_driver em28xx_usb_driver = { |
| 1887 | .owner = THIS_MODULE, | ||
| 1888 | .name = "em28xx", | 1887 | .name = "em28xx", |
| 1889 | .probe = em28xx_usb_probe, | 1888 | .probe = em28xx_usb_probe, |
| 1890 | .disconnect = em28xx_usb_disconnect, | 1889 | .disconnect = em28xx_usb_disconnect, |
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c index c22c0517883c..fa176ffb4ad5 100644 --- a/drivers/net/irda/irda-usb.c +++ b/drivers/net/irda/irda-usb.c | |||
| @@ -1539,7 +1539,6 @@ static void irda_usb_disconnect(struct usb_interface *intf) | |||
| 1539 | * USB device callbacks | 1539 | * USB device callbacks |
| 1540 | */ | 1540 | */ |
| 1541 | static struct usb_driver irda_driver = { | 1541 | static struct usb_driver irda_driver = { |
| 1542 | .owner = THIS_MODULE, | ||
| 1543 | .name = "irda-usb", | 1542 | .name = "irda-usb", |
| 1544 | .probe = irda_usb_probe, | 1543 | .probe = irda_usb_probe, |
| 1545 | .disconnect = irda_usb_disconnect, | 1544 | .disconnect = irda_usb_disconnect, |
diff --git a/drivers/net/irda/stir4200.c b/drivers/net/irda/stir4200.c index 3961a754e920..31867e4b891b 100644 --- a/drivers/net/irda/stir4200.c +++ b/drivers/net/irda/stir4200.c | |||
| @@ -1152,7 +1152,6 @@ static int stir_resume(struct usb_interface *intf) | |||
| 1152 | * USB device callbacks | 1152 | * USB device callbacks |
| 1153 | */ | 1153 | */ |
| 1154 | static struct usb_driver irda_driver = { | 1154 | static struct usb_driver irda_driver = { |
| 1155 | .owner = THIS_MODULE, | ||
| 1156 | .name = "stir4200", | 1155 | .name = "stir4200", |
| 1157 | .probe = stir_probe, | 1156 | .probe = stir_probe, |
| 1158 | .disconnect = stir_disconnect, | 1157 | .disconnect = stir_disconnect, |
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index a50c2bc506f2..3639c3f8d357 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile | |||
| @@ -22,6 +22,7 @@ obj-$(CONFIG_USB_MIDI) += class/ | |||
| 22 | obj-$(CONFIG_USB_PRINTER) += class/ | 22 | obj-$(CONFIG_USB_PRINTER) += class/ |
| 23 | 23 | ||
| 24 | obj-$(CONFIG_USB_STORAGE) += storage/ | 24 | obj-$(CONFIG_USB_STORAGE) += storage/ |
| 25 | obj-$(CONFIG_USB) += storage/ | ||
| 25 | 26 | ||
| 26 | obj-$(CONFIG_USB_AIPTEK) += input/ | 27 | obj-$(CONFIG_USB_AIPTEK) += input/ |
| 27 | obj-$(CONFIG_USB_ATI_REMOTE) += input/ | 28 | obj-$(CONFIG_USB_ATI_REMOTE) += input/ |
diff --git a/drivers/usb/atm/Kconfig b/drivers/usb/atm/Kconfig index f429862e0974..550ddfa71a43 100644 --- a/drivers/usb/atm/Kconfig +++ b/drivers/usb/atm/Kconfig | |||
| @@ -44,6 +44,19 @@ config USB_CXACRU | |||
| 44 | To compile this driver as a module, choose M here: the | 44 | To compile this driver as a module, choose M here: the |
| 45 | module will be called cxacru. | 45 | module will be called cxacru. |
| 46 | 46 | ||
| 47 | config USB_UEAGLEATM | ||
| 48 | tristate "ADI 930 and eagle USB DSL modem" | ||
| 49 | depends on USB_ATM | ||
| 50 | select FW_LOADER | ||
| 51 | help | ||
| 52 | Say Y here if you have an ADSL USB modem based on the ADI 930 | ||
| 53 | or eagle chipset. In order to use your modem you will need to | ||
| 54 | install firmwares and CMV (Command Management Variables); see | ||
| 55 | <https://gna.org/projects/ueagleatm/> for details. | ||
| 56 | |||
| 57 | To compile this driver as a module, choose M here: the | ||
| 58 | module will be called ueagle-atm. | ||
| 59 | |||
| 47 | config USB_XUSBATM | 60 | config USB_XUSBATM |
| 48 | tristate "Other USB DSL modem support" | 61 | tristate "Other USB DSL modem support" |
| 49 | depends on USB_ATM | 62 | depends on USB_ATM |
diff --git a/drivers/usb/atm/Makefile b/drivers/usb/atm/Makefile index 85099718c683..4c4a776ab1cd 100644 --- a/drivers/usb/atm/Makefile +++ b/drivers/usb/atm/Makefile | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | obj-$(CONFIG_USB_CXACRU) += cxacru.o | 5 | obj-$(CONFIG_USB_CXACRU) += cxacru.o |
| 6 | obj-$(CONFIG_USB_SPEEDTOUCH) += speedtch.o | 6 | obj-$(CONFIG_USB_SPEEDTOUCH) += speedtch.o |
| 7 | obj-$(CONFIG_USB_UEAGLEATM) += ueagle-atm.o | ||
| 7 | obj-$(CONFIG_USB_ATM) += usbatm.o | 8 | obj-$(CONFIG_USB_ATM) += usbatm.o |
| 8 | obj-$(CONFIG_USB_XUSBATM) += xusbatm.o | 9 | obj-$(CONFIG_USB_XUSBATM) += xusbatm.o |
| 9 | 10 | ||
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c index 9d59dc62e6d2..af0a41e7870e 100644 --- a/drivers/usb/atm/cxacru.c +++ b/drivers/usb/atm/cxacru.c | |||
| @@ -853,7 +853,6 @@ static int cxacru_usb_probe(struct usb_interface *intf, const struct usb_device_ | |||
| 853 | } | 853 | } |
| 854 | 854 | ||
| 855 | static struct usb_driver cxacru_usb_driver = { | 855 | static struct usb_driver cxacru_usb_driver = { |
| 856 | .owner = THIS_MODULE, | ||
| 857 | .name = cxacru_driver_name, | 856 | .name = cxacru_driver_name, |
| 858 | .probe = cxacru_usb_probe, | 857 | .probe = cxacru_usb_probe, |
| 859 | .disconnect = usbatm_usb_disconnect, | 858 | .disconnect = usbatm_usb_disconnect, |
diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c index d0cbbb7f0385..b28336148658 100644 --- a/drivers/usb/atm/speedtch.c +++ b/drivers/usb/atm/speedtch.c | |||
| @@ -659,7 +659,6 @@ MODULE_DEVICE_TABLE(usb, speedtch_usb_ids); | |||
| 659 | static int speedtch_usb_probe(struct usb_interface *, const struct usb_device_id *); | 659 | static int speedtch_usb_probe(struct usb_interface *, const struct usb_device_id *); |
| 660 | 660 | ||
| 661 | static struct usb_driver speedtch_usb_driver = { | 661 | static struct usb_driver speedtch_usb_driver = { |
| 662 | .owner = THIS_MODULE, | ||
| 663 | .name = speedtch_driver_name, | 662 | .name = speedtch_driver_name, |
| 664 | .probe = speedtch_usb_probe, | 663 | .probe = speedtch_usb_probe, |
| 665 | .disconnect = usbatm_usb_disconnect, | 664 | .disconnect = usbatm_usb_disconnect, |
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c new file mode 100644 index 000000000000..7d2a679989ed --- /dev/null +++ b/drivers/usb/atm/ueagle-atm.c | |||
| @@ -0,0 +1,1820 @@ | |||
| 1 | /*- | ||
| 2 | * Copyright (c) 2003, 2004 | ||
| 3 | * Damien Bergamini <damien.bergamini@free.fr>. All rights reserved. | ||
| 4 | * | ||
| 5 | * Copyright (c) 2005 Matthieu Castet <castet.matthieu@free.fr> | ||
| 6 | * | ||
| 7 | * This software is available to you under a choice of one of two | ||
| 8 | * licenses. You may choose to be licensed under the terms of the GNU | ||
| 9 | * General Public License (GPL) Version 2, available from the file | ||
| 10 | * COPYING in the main directory of this source tree, or the | ||
| 11 | * BSD license below: | ||
| 12 | * | ||
| 13 | * Redistribution and use in source and binary forms, with or without | ||
| 14 | * modification, are permitted provided that the following conditions | ||
| 15 | * are met: | ||
| 16 | * 1. Redistributions of source code must retain the above copyright | ||
| 17 | * notice unmodified, this list of conditions, and the following | ||
| 18 | * disclaimer. | ||
| 19 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 20 | * notice, this list of conditions and the following disclaimer in the | ||
| 21 | * documentation and/or other materials provided with the distribution. | ||
| 22 | * | ||
| 23 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | ||
| 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
| 27 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 29 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 30 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 31 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 32 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 33 | * SUCH DAMAGE. | ||
| 34 | * | ||
| 35 | * GPL license : | ||
| 36 | * This program is free software; you can redistribute it and/or | ||
| 37 | * modify it under the terms of the GNU General Public License | ||
| 38 | * as published by the Free Software Foundation; either version 2 | ||
| 39 | * of the License, or (at your option) any later version. | ||
| 40 | * | ||
| 41 | * This program is distributed in the hope that it will be useful, | ||
| 42 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 43 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 44 | * GNU General Public License for more details. | ||
| 45 | * | ||
| 46 | * You should have received a copy of the GNU General Public License | ||
| 47 | * along with this program; if not, write to the Free Software | ||
| 48 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 49 | * | ||
| 50 | * | ||
| 51 | * HISTORY : some part of the code was base on ueagle 1.3 BSD driver, | ||
| 52 | * Damien Bergamini agree to put his code under a DUAL GPL/BSD license. | ||
| 53 | * | ||
| 54 | * The rest of the code was was rewritten from scratch. | ||
| 55 | */ | ||
| 56 | |||
| 57 | #include <linux/module.h> | ||
| 58 | #include <linux/moduleparam.h> | ||
| 59 | #include <linux/init.h> | ||
| 60 | #include <linux/crc32.h> | ||
| 61 | #include <linux/usb.h> | ||
| 62 | #include <linux/firmware.h> | ||
| 63 | #include <linux/ctype.h> | ||
| 64 | #include <linux/kthread.h> | ||
| 65 | #include <linux/version.h> | ||
| 66 | #include <asm/unaligned.h> | ||
| 67 | |||
| 68 | #include "usbatm.h" | ||
| 69 | |||
| 70 | #define EAGLEUSBVERSION "ueagle 1.1" | ||
| 71 | |||
| 72 | |||
| 73 | /* | ||
| 74 | * Debug macros | ||
| 75 | */ | ||
| 76 | #define uea_dbg(usb_dev, format, args...) \ | ||
| 77 | do { \ | ||
| 78 | if (debug >= 1) \ | ||
| 79 | dev_dbg(&(usb_dev)->dev, \ | ||
| 80 | "[ueagle-atm dbg] %s: " format, \ | ||
| 81 | __FUNCTION__, ##args); \ | ||
| 82 | } while (0) | ||
| 83 | |||
| 84 | #define uea_vdbg(usb_dev, format, args...) \ | ||
| 85 | do { \ | ||
| 86 | if (debug >= 2) \ | ||
| 87 | dev_dbg(&(usb_dev)->dev, \ | ||
| 88 | "[ueagle-atm vdbg] " format, ##args); \ | ||
| 89 | } while (0) | ||
| 90 | |||
| 91 | #define uea_enters(usb_dev) \ | ||
| 92 | uea_vdbg(usb_dev, "entering %s\n", __FUNCTION__) | ||
| 93 | |||
| 94 | #define uea_leaves(usb_dev) \ | ||
| 95 | uea_vdbg(usb_dev, "leaving %s\n", __FUNCTION__) | ||
| 96 | |||
| 97 | #define uea_err(usb_dev, format,args...) \ | ||
| 98 | dev_err(&(usb_dev)->dev ,"[UEAGLE-ATM] " format , ##args) | ||
| 99 | |||
| 100 | #define uea_warn(usb_dev, format,args...) \ | ||
| 101 | dev_warn(&(usb_dev)->dev ,"[Ueagle-atm] " format, ##args) | ||
| 102 | |||
| 103 | #define uea_info(usb_dev, format,args...) \ | ||
| 104 | dev_info(&(usb_dev)->dev ,"[ueagle-atm] " format, ##args) | ||
| 105 | |||
| 106 | struct uea_cmvs { | ||
| 107 | u32 address; | ||
| 108 | u16 offset; | ||
| 109 | u32 data; | ||
| 110 | } __attribute__ ((packed)); | ||
| 111 | |||
| 112 | struct uea_softc { | ||
| 113 | struct usb_device *usb_dev; | ||
| 114 | struct usbatm_data *usbatm; | ||
| 115 | |||
| 116 | int modem_index; | ||
| 117 | unsigned int driver_info; | ||
| 118 | |||
| 119 | int booting; | ||
| 120 | int reset; | ||
| 121 | |||
| 122 | wait_queue_head_t sync_q; | ||
| 123 | |||
| 124 | struct task_struct *kthread; | ||
| 125 | u32 data; | ||
| 126 | wait_queue_head_t cmv_ack_wait; | ||
| 127 | int cmv_ack; | ||
| 128 | |||
| 129 | struct work_struct task; | ||
| 130 | u16 pageno; | ||
| 131 | u16 ovl; | ||
| 132 | |||
| 133 | const struct firmware *dsp_firm; | ||
| 134 | struct urb *urb_int; | ||
| 135 | |||
| 136 | u8 cmv_function; | ||
| 137 | u16 cmv_idx; | ||
| 138 | u32 cmv_address; | ||
| 139 | u16 cmv_offset; | ||
| 140 | |||
| 141 | /* keep in sync with eaglectl */ | ||
| 142 | struct uea_stats { | ||
| 143 | struct { | ||
| 144 | u32 state; | ||
| 145 | u32 flags; | ||
| 146 | u32 mflags; | ||
| 147 | u32 vidcpe; | ||
| 148 | u32 vidco; | ||
| 149 | u32 dsrate; | ||
| 150 | u32 usrate; | ||
| 151 | u32 dsunc; | ||
| 152 | u32 usunc; | ||
| 153 | u32 dscorr; | ||
| 154 | u32 uscorr; | ||
| 155 | u32 txflow; | ||
| 156 | u32 rxflow; | ||
| 157 | u32 usattenuation; | ||
| 158 | u32 dsattenuation; | ||
| 159 | u32 dsmargin; | ||
| 160 | u32 usmargin; | ||
| 161 | u32 firmid; | ||
| 162 | } phy; | ||
| 163 | } stats; | ||
| 164 | }; | ||
| 165 | |||
| 166 | /* | ||
| 167 | * Elsa IDs | ||
| 168 | */ | ||
| 169 | #define ELSA_VID 0x05CC | ||
| 170 | #define ELSA_PID_PSTFIRM 0x3350 | ||
| 171 | #define ELSA_PID_PREFIRM 0x3351 | ||
| 172 | |||
| 173 | /* | ||
| 174 | * Sagem USB IDs | ||
| 175 | */ | ||
| 176 | #define EAGLE_VID 0x1110 | ||
| 177 | #define EAGLE_I_PID_PREFIRM 0x9010 /* Eagle I */ | ||
| 178 | #define EAGLE_I_PID_PSTFIRM 0x900F /* Eagle I */ | ||
| 179 | |||
| 180 | #define EAGLE_IIC_PID_PREFIRM 0x9024 /* Eagle IIC */ | ||
| 181 | #define EAGLE_IIC_PID_PSTFIRM 0x9023 /* Eagle IIC */ | ||
| 182 | |||
| 183 | #define EAGLE_II_PID_PREFIRM 0x9022 /* Eagle II */ | ||
| 184 | #define EAGLE_II_PID_PSTFIRM 0x9021 /* Eagle II */ | ||
| 185 | |||
| 186 | /* | ||
| 187 | * Eagle III Pid | ||
| 188 | */ | ||
| 189 | #define EAGLE_III_PID_PREFIRM 0x9032 /* Eagle III */ | ||
| 190 | #define EAGLE_III_PID_PSTFIRM 0x9031 /* Eagle III */ | ||
| 191 | |||
| 192 | /* | ||
| 193 | * USR USB IDs | ||
| 194 | */ | ||
| 195 | #define USR_VID 0x0BAF | ||
| 196 | #define MILLER_A_PID_PREFIRM 0x00F2 | ||
| 197 | #define MILLER_A_PID_PSTFIRM 0x00F1 | ||
| 198 | #define MILLER_B_PID_PREFIRM 0x00FA | ||
| 199 | #define MILLER_B_PID_PSTFIRM 0x00F9 | ||
| 200 | #define HEINEKEN_A_PID_PREFIRM 0x00F6 | ||
| 201 | #define HEINEKEN_A_PID_PSTFIRM 0x00F5 | ||
| 202 | #define HEINEKEN_B_PID_PREFIRM 0x00F8 | ||
| 203 | #define HEINEKEN_B_PID_PSTFIRM 0x00F7 | ||
| 204 | |||
| 205 | #define PREFIRM 0 | ||
| 206 | #define PSTFIRM (1<<7) | ||
| 207 | enum { | ||
| 208 | ADI930 = 0, | ||
| 209 | EAGLE_I, | ||
| 210 | EAGLE_II, | ||
| 211 | EAGLE_III | ||
| 212 | }; | ||
| 213 | |||
| 214 | /* macros for both struct usb_device_id and struct uea_softc */ | ||
| 215 | #define UEA_IS_PREFIRM(x) \ | ||
| 216 | (!((x)->driver_info & PSTFIRM)) | ||
| 217 | #define UEA_CHIP_VERSION(x) \ | ||
| 218 | ((x)->driver_info & 0xf) | ||
| 219 | |||
| 220 | #define IS_ISDN(sc) \ | ||
| 221 | (le16_to_cpu(sc->usb_dev->descriptor.bcdDevice) & 0x80) | ||
| 222 | |||
| 223 | #define INS_TO_USBDEV(ins) ins->usb_dev | ||
| 224 | |||
| 225 | #define GET_STATUS(data) \ | ||
| 226 | ((data >> 8) & 0xf) | ||
| 227 | #define IS_OPERATIONAL(sc) \ | ||
| 228 | (GET_STATUS(sc->stats.phy.state) == 2) | ||
| 229 | |||
| 230 | /* | ||
| 231 | * Set of macros to handle unaligned data in the firmware blob. | ||
| 232 | * The FW_GET_BYTE() macro is provided only for consistency. | ||
| 233 | */ | ||
| 234 | |||
| 235 | #define FW_GET_BYTE(p) *((__u8 *) (p)) | ||
| 236 | #define FW_GET_WORD(p) le16_to_cpu(get_unaligned((__le16 *) (p))) | ||
| 237 | #define FW_GET_LONG(p) le32_to_cpu(get_unaligned((__le32 *) (p))) | ||
| 238 | |||
| 239 | #define FW_DIR "ueagle-atm/" | ||
| 240 | #define NB_MODEM 4 | ||
| 241 | |||
| 242 | #define BULK_TIMEOUT 300 | ||
| 243 | #define CTRL_TIMEOUT 1000 | ||
| 244 | |||
| 245 | #define ACK_TIMEOUT msecs_to_jiffies(1500) | ||
| 246 | |||
| 247 | #define UEA_INTR_IFACE_NO 0 | ||
| 248 | #define UEA_US_IFACE_NO 1 | ||
| 249 | #define UEA_DS_IFACE_NO 2 | ||
| 250 | |||
| 251 | #define FASTEST_ISO_INTF 8 | ||
| 252 | |||
| 253 | #define UEA_BULK_DATA_PIPE 0x02 | ||
| 254 | #define UEA_IDMA_PIPE 0x04 | ||
| 255 | #define UEA_INTR_PIPE 0x04 | ||
| 256 | #define UEA_ISO_DATA_PIPE 0x08 | ||
| 257 | |||
| 258 | #define UEA_SET_BLOCK 0x0001 | ||
| 259 | #define UEA_SET_MODE 0x0003 | ||
| 260 | #define UEA_SET_2183_DATA 0x0004 | ||
| 261 | #define UEA_SET_TIMEOUT 0x0011 | ||
| 262 | |||
| 263 | #define UEA_LOOPBACK_OFF 0x0002 | ||
| 264 | #define UEA_LOOPBACK_ON 0x0003 | ||
| 265 | #define UEA_BOOT_IDMA 0x0006 | ||
| 266 | #define UEA_START_RESET 0x0007 | ||
| 267 | #define UEA_END_RESET 0x0008 | ||
| 268 | |||
| 269 | #define UEA_SWAP_MAILBOX (0x3fcd | 0x4000) | ||
| 270 | #define UEA_MPTX_START (0x3fce | 0x4000) | ||
| 271 | #define UEA_MPTX_MAILBOX (0x3fd6 | 0x4000) | ||
| 272 | #define UEA_MPRX_MAILBOX (0x3fdf | 0x4000) | ||
| 273 | |||
| 274 | /* structure describing a block within a DSP page */ | ||
| 275 | struct block_info { | ||
| 276 | __le16 wHdr; | ||
| 277 | #define UEA_BIHDR 0xabcd | ||
| 278 | __le16 wAddress; | ||
| 279 | __le16 wSize; | ||
| 280 | __le16 wOvlOffset; | ||
| 281 | __le16 wOvl; /* overlay */ | ||
| 282 | __le16 wLast; | ||
| 283 | } __attribute__ ((packed)); | ||
| 284 | #define BLOCK_INFO_SIZE 12 | ||
| 285 | |||
| 286 | /* structure representing a CMV (Configuration and Management Variable) */ | ||
| 287 | struct cmv { | ||
| 288 | __le16 wPreamble; | ||
| 289 | #define PREAMBLE 0x535c | ||
| 290 | __u8 bDirection; | ||
| 291 | #define MODEMTOHOST 0x01 | ||
| 292 | #define HOSTTOMODEM 0x10 | ||
| 293 | __u8 bFunction; | ||
| 294 | #define FUNCTION_TYPE(f) ((f) >> 4) | ||
| 295 | #define MEMACCESS 0x1 | ||
| 296 | #define ADSLDIRECTIVE 0x7 | ||
| 297 | |||
| 298 | #define FUNCTION_SUBTYPE(f) ((f) & 0x0f) | ||
| 299 | /* for MEMACCESS */ | ||
| 300 | #define REQUESTREAD 0x0 | ||
| 301 | #define REQUESTWRITE 0x1 | ||
| 302 | #define REPLYREAD 0x2 | ||
| 303 | #define REPLYWRITE 0x3 | ||
| 304 | /* for ADSLDIRECTIVE */ | ||
| 305 | #define KERNELREADY 0x0 | ||
| 306 | #define MODEMREADY 0x1 | ||
| 307 | |||
| 308 | #define MAKEFUNCTION(t, s) (((t) & 0xf) << 4 | ((s) & 0xf)) | ||
| 309 | __le16 wIndex; | ||
| 310 | __le32 dwSymbolicAddress; | ||
| 311 | #define MAKESA(a, b, c, d) \ | ||
| 312 | (((c) & 0xff) << 24 | \ | ||
| 313 | ((d) & 0xff) << 16 | \ | ||
| 314 | ((a) & 0xff) << 8 | \ | ||
| 315 | ((b) & 0xff)) | ||
| 316 | |||
| 317 | #define SA_CNTL MAKESA('C', 'N', 'T', 'L') | ||
| 318 | #define SA_DIAG MAKESA('D', 'I', 'A', 'G') | ||
| 319 | #define SA_INFO MAKESA('I', 'N', 'F', 'O') | ||
| 320 | #define SA_OPTN MAKESA('O', 'P', 'T', 'N') | ||
| 321 | #define SA_RATE MAKESA('R', 'A', 'T', 'E') | ||
| 322 | #define SA_STAT MAKESA('S', 'T', 'A', 'T') | ||
| 323 | __le16 wOffsetAddress; | ||
| 324 | __le32 dwData; | ||
| 325 | } __attribute__ ((packed)); | ||
| 326 | #define CMV_SIZE 16 | ||
| 327 | |||
| 328 | /* structure representing swap information */ | ||
| 329 | struct swap_info { | ||
| 330 | __u8 bSwapPageNo; | ||
| 331 | __u8 bOvl; /* overlay */ | ||
| 332 | } __attribute__ ((packed)); | ||
| 333 | |||
| 334 | /* structure representing interrupt data */ | ||
| 335 | struct intr_pkt { | ||
| 336 | __u8 bType; | ||
| 337 | __u8 bNotification; | ||
| 338 | __le16 wValue; | ||
| 339 | __le16 wIndex; | ||
| 340 | __le16 wLength; | ||
| 341 | __le16 wInterrupt; | ||
| 342 | #define INT_LOADSWAPPAGE 0x0001 | ||
| 343 | #define INT_INCOMINGCMV 0x0002 | ||
| 344 | union { | ||
| 345 | struct { | ||
| 346 | struct swap_info swapinfo; | ||
| 347 | __le16 wDataSize; | ||
| 348 | } __attribute__ ((packed)) s1; | ||
| 349 | |||
| 350 | struct { | ||
| 351 | struct cmv cmv; | ||
| 352 | __le16 wDataSize; | ||
| 353 | } __attribute__ ((packed)) s2; | ||
| 354 | } __attribute__ ((packed)) u; | ||
| 355 | #define bSwapPageNo u.s1.swapinfo.bSwapPageNo | ||
| 356 | #define bOvl u.s1.swapinfo.bOvl | ||
| 357 | } __attribute__ ((packed)); | ||
| 358 | #define INTR_PKT_SIZE 28 | ||
| 359 | |||
| 360 | static struct usb_driver uea_driver; | ||
| 361 | static DECLARE_MUTEX(uea_semaphore); | ||
| 362 | static const char *chip_name[] = {"ADI930", "Eagle I", "Eagle II", "Eagle III"}; | ||
| 363 | |||
| 364 | static int modem_index; | ||
| 365 | static unsigned int debug; | ||
| 366 | static int sync_wait[NB_MODEM]; | ||
| 367 | static char *cmv_file[NB_MODEM]; | ||
| 368 | |||
| 369 | module_param(debug, uint, 0644); | ||
| 370 | MODULE_PARM_DESC(debug, "module debug level (0=off,1=on,2=verbose)"); | ||
| 371 | module_param_array(sync_wait, bool, NULL, 0644); | ||
| 372 | MODULE_PARM_DESC(sync_wait, "wait the synchronisation before starting ATM"); | ||
| 373 | module_param_array(cmv_file, charp, NULL, 0644); | ||
| 374 | MODULE_PARM_DESC(cmv_file, | ||
| 375 | "file name with configuration and management variables"); | ||
| 376 | |||
| 377 | #define UPDATE_ATM_STAT(type, val) \ | ||
| 378 | do { \ | ||
| 379 | if (sc->usbatm->atm_dev) \ | ||
| 380 | sc->usbatm->atm_dev->type = val; \ | ||
| 381 | } while (0) | ||
| 382 | |||
| 383 | /* Firmware loading */ | ||
| 384 | #define LOAD_INTERNAL 0xA0 | ||
| 385 | #define F8051_USBCS 0x7f92 | ||
| 386 | |||
| 387 | /** | ||
| 388 | * uea_send_modem_cmd - Send a command for pre-firmware devices. | ||
| 389 | */ | ||
| 390 | static int uea_send_modem_cmd(struct usb_device *usb, | ||
| 391 | u16 addr, u16 size, u8 * buff) | ||
| 392 | { | ||
| 393 | int ret = -ENOMEM; | ||
| 394 | u8 *xfer_buff; | ||
| 395 | |||
| 396 | xfer_buff = kmalloc(size, GFP_KERNEL); | ||
| 397 | if (xfer_buff) { | ||
| 398 | memcpy(xfer_buff, buff, size); | ||
| 399 | ret = usb_control_msg(usb, | ||
| 400 | usb_sndctrlpipe(usb, 0), | ||
| 401 | LOAD_INTERNAL, | ||
| 402 | USB_DIR_OUT | USB_TYPE_VENDOR | | ||
| 403 | USB_RECIP_DEVICE, addr, 0, xfer_buff, | ||
| 404 | size, CTRL_TIMEOUT); | ||
| 405 | kfree(xfer_buff); | ||
| 406 | } | ||
| 407 | |||
| 408 | if (ret < 0) | ||
| 409 | return ret; | ||
| 410 | |||
| 411 | return (ret == size) ? 0 : -EIO; | ||
| 412 | } | ||
| 413 | |||
| 414 | static void uea_upload_pre_firmware(const struct firmware *fw_entry, void *context) | ||
| 415 | { | ||
| 416 | struct usb_device *usb = context; | ||
| 417 | u8 *pfw, value; | ||
| 418 | u32 crc = 0; | ||
| 419 | int ret, size; | ||
| 420 | |||
| 421 | uea_enters(usb); | ||
| 422 | if (!fw_entry) { | ||
| 423 | uea_err(usb, "firmware is not available\n"); | ||
| 424 | goto err; | ||
| 425 | } | ||
| 426 | |||
| 427 | pfw = fw_entry->data; | ||
| 428 | size = fw_entry->size; | ||
| 429 | if (size < 4) | ||
| 430 | goto err_fw_corrupted; | ||
| 431 | |||
| 432 | crc = FW_GET_LONG(pfw); | ||
| 433 | pfw += 4; | ||
| 434 | size -= 4; | ||
| 435 | if (crc32_be(0, pfw, size) != crc) | ||
| 436 | goto err_fw_corrupted; | ||
| 437 | |||
| 438 | /* | ||
| 439 | * Start to upload formware : send reset | ||
| 440 | */ | ||
| 441 | value = 1; | ||
| 442 | ret = uea_send_modem_cmd(usb, F8051_USBCS, sizeof(value), &value); | ||
| 443 | |||
| 444 | if (ret < 0) { | ||
| 445 | uea_err(usb, "modem reset failed with error %d\n", ret); | ||
| 446 | goto err; | ||
| 447 | } | ||
| 448 | |||
| 449 | while (size > 3) { | ||
| 450 | u8 len = FW_GET_BYTE(pfw); | ||
| 451 | u16 add = FW_GET_WORD(pfw + 1); | ||
| 452 | |||
| 453 | size -= len + 3; | ||
| 454 | if (size < 0) | ||
| 455 | goto err_fw_corrupted; | ||
| 456 | |||
| 457 | ret = uea_send_modem_cmd(usb, add, len, pfw + 3); | ||
| 458 | if (ret < 0) { | ||
| 459 | uea_err(usb, "uploading firmware data failed " | ||
| 460 | "with error %d\n", ret); | ||
| 461 | goto err; | ||
| 462 | } | ||
| 463 | pfw += len + 3; | ||
| 464 | } | ||
| 465 | |||
| 466 | if (size != 0) | ||
| 467 | goto err_fw_corrupted; | ||
| 468 | |||
| 469 | /* | ||
| 470 | * Tell the modem we finish : de-assert reset | ||
| 471 | */ | ||
| 472 | value = 0; | ||
| 473 | ret = uea_send_modem_cmd(usb, F8051_USBCS, 1, &value); | ||
| 474 | if (ret < 0) | ||
| 475 | uea_err(usb, "modem de-assert failed with error %d\n", ret); | ||
| 476 | else | ||
| 477 | uea_info(usb, "firmware uploaded\n"); | ||
| 478 | |||
| 479 | uea_leaves(usb); | ||
| 480 | return; | ||
| 481 | |||
| 482 | err_fw_corrupted: | ||
| 483 | uea_err(usb, "firmware is corrupted\n"); | ||
| 484 | err: | ||
| 485 | uea_leaves(usb); | ||
| 486 | } | ||
| 487 | |||
| 488 | /** | ||
| 489 | * uea_load_firmware - Load usb firmware for pre-firmware devices. | ||
| 490 | */ | ||
| 491 | static int uea_load_firmware(struct usb_device *usb, unsigned int ver) | ||
| 492 | { | ||
| 493 | int ret; | ||
| 494 | char *fw_name = FW_DIR "eagle.fw"; | ||
| 495 | |||
| 496 | uea_enters(usb); | ||
| 497 | uea_info(usb, "pre-firmware device, uploading firmware\n"); | ||
| 498 | |||
| 499 | switch (ver) { | ||
| 500 | case ADI930: | ||
| 501 | fw_name = FW_DIR "adi930.fw"; | ||
| 502 | break; | ||
| 503 | case EAGLE_I: | ||
| 504 | fw_name = FW_DIR "eagleI.fw"; | ||
| 505 | break; | ||
| 506 | case EAGLE_II: | ||
| 507 | fw_name = FW_DIR "eagleII.fw"; | ||
| 508 | break; | ||
| 509 | case EAGLE_III: | ||
| 510 | fw_name = FW_DIR "eagleIII.fw"; | ||
| 511 | break; | ||
| 512 | } | ||
| 513 | |||
| 514 | ret = request_firmware_nowait(THIS_MODULE, 1, fw_name, &usb->dev, usb, uea_upload_pre_firmware); | ||
| 515 | if (ret) | ||
| 516 | uea_err(usb, "firmware %s is not available\n", fw_name); | ||
| 517 | else | ||
| 518 | uea_info(usb, "loading firmware %s\n", fw_name); | ||
| 519 | |||
| 520 | uea_leaves(usb); | ||
| 521 | return ret; | ||
| 522 | } | ||
| 523 | |||
| 524 | /* modem management : dsp firmware, send/read CMV, monitoring statistic | ||
| 525 | */ | ||
| 526 | |||
| 527 | /* | ||
| 528 | * Make sure that the DSP code provided is safe to use. | ||
| 529 | */ | ||
| 530 | static int check_dsp(u8 *dsp, unsigned int len) | ||
| 531 | { | ||
| 532 | u8 pagecount, blockcount; | ||
| 533 | u16 blocksize; | ||
| 534 | u32 pageoffset; | ||
| 535 | unsigned int i, j, p, pp; | ||
| 536 | |||
| 537 | pagecount = FW_GET_BYTE(dsp); | ||
| 538 | p = 1; | ||
| 539 | |||
| 540 | /* enough space for page offsets? */ | ||
| 541 | if (p + 4 * pagecount > len) | ||
| 542 | return 1; | ||
| 543 | |||
| 544 | for (i = 0; i < pagecount; i++) { | ||
| 545 | |||
| 546 | pageoffset = FW_GET_LONG(dsp + p); | ||
| 547 | p += 4; | ||
| 548 | |||
| 549 | if (pageoffset == 0) | ||
| 550 | continue; | ||
| 551 | |||
| 552 | /* enough space for blockcount? */ | ||
| 553 | if (pageoffset >= len) | ||
| 554 | return 1; | ||
| 555 | |||
| 556 | pp = pageoffset; | ||
| 557 | blockcount = FW_GET_BYTE(dsp + pp); | ||
| 558 | pp += 1; | ||
| 559 | |||
| 560 | for (j = 0; j < blockcount; j++) { | ||
| 561 | |||
| 562 | /* enough space for block header? */ | ||
| 563 | if (pp + 4 > len) | ||
| 564 | return 1; | ||
| 565 | |||
| 566 | pp += 2; /* skip blockaddr */ | ||
| 567 | blocksize = FW_GET_WORD(dsp + pp); | ||
| 568 | pp += 2; | ||
| 569 | |||
| 570 | /* enough space for block data? */ | ||
| 571 | if (pp + blocksize > len) | ||
| 572 | return 1; | ||
| 573 | |||
| 574 | pp += blocksize; | ||
| 575 | } | ||
| 576 | } | ||
| 577 | |||
| 578 | return 0; | ||
| 579 | } | ||
| 580 | |||
| 581 | /* | ||
| 582 | * send data to the idma pipe | ||
| 583 | * */ | ||
| 584 | static int uea_idma_write(struct uea_softc *sc, void *data, u32 size) | ||
| 585 | { | ||
| 586 | int ret = -ENOMEM; | ||
| 587 | u8 *xfer_buff; | ||
| 588 | int bytes_read; | ||
| 589 | |||
| 590 | xfer_buff = kmalloc(size, GFP_KERNEL); | ||
| 591 | if (!xfer_buff) { | ||
| 592 | uea_err(INS_TO_USBDEV(sc), "can't allocate xfer_buff\n"); | ||
| 593 | return ret; | ||
| 594 | } | ||
| 595 | |||
| 596 | memcpy(xfer_buff, data, size); | ||
| 597 | |||
| 598 | ret = usb_bulk_msg(sc->usb_dev, | ||
| 599 | usb_sndbulkpipe(sc->usb_dev, UEA_IDMA_PIPE), | ||
| 600 | xfer_buff, size, &bytes_read, BULK_TIMEOUT); | ||
| 601 | |||
| 602 | kfree(xfer_buff); | ||
| 603 | if (ret < 0) | ||
| 604 | return ret; | ||
| 605 | if (size != bytes_read) { | ||
| 606 | uea_err(INS_TO_USBDEV(sc), "size != bytes_read %d %d\n", size, | ||
| 607 | bytes_read); | ||
| 608 | return -EIO; | ||
| 609 | } | ||
| 610 | |||
| 611 | return 0; | ||
| 612 | } | ||
| 613 | |||
| 614 | static int request_dsp(struct uea_softc *sc) | ||
| 615 | { | ||
| 616 | int ret; | ||
| 617 | char *dsp_name; | ||
| 618 | |||
| 619 | if (UEA_CHIP_VERSION(sc) == ADI930) { | ||
| 620 | if (IS_ISDN(sc)) | ||
| 621 | dsp_name = FW_DIR "DSP9i.bin"; | ||
| 622 | else | ||
| 623 | dsp_name = FW_DIR "DSP9p.bin"; | ||
| 624 | } else { | ||
| 625 | if (IS_ISDN(sc)) | ||
| 626 | dsp_name = FW_DIR "DSPei.bin"; | ||
| 627 | else | ||
| 628 | dsp_name = FW_DIR "DSPep.bin"; | ||
| 629 | } | ||
| 630 | |||
| 631 | ret = request_firmware(&sc->dsp_firm, | ||
| 632 | dsp_name, &sc->usb_dev->dev); | ||
| 633 | if (ret < 0) { | ||
| 634 | uea_err(INS_TO_USBDEV(sc), | ||
| 635 | "requesting firmware %s failed with error %d\n", | ||
| 636 | dsp_name, ret); | ||
| 637 | return ret; | ||
| 638 | } | ||
| 639 | |||
| 640 | if (check_dsp(sc->dsp_firm->data, sc->dsp_firm->size)) { | ||
| 641 | uea_err(INS_TO_USBDEV(sc), "firmware %s is corrupted\n", | ||
| 642 | dsp_name); | ||
| 643 | release_firmware(sc->dsp_firm); | ||
| 644 | sc->dsp_firm = NULL; | ||
| 645 | return -EILSEQ; | ||
| 646 | } | ||
| 647 | |||
| 648 | return 0; | ||
| 649 | } | ||
| 650 | |||
| 651 | /* | ||
| 652 | * The uea_load_page() function must be called within a process context | ||
| 653 | */ | ||
| 654 | static void uea_load_page(void *xsc) | ||
| 655 | { | ||
| 656 | struct uea_softc *sc = xsc; | ||
| 657 | u16 pageno = sc->pageno; | ||
| 658 | u16 ovl = sc->ovl; | ||
| 659 | struct block_info bi; | ||
| 660 | |||
| 661 | u8 *p; | ||
| 662 | u8 pagecount, blockcount; | ||
| 663 | u16 blockaddr, blocksize; | ||
| 664 | u32 pageoffset; | ||
| 665 | int i; | ||
| 666 | |||
| 667 | /* reload firmware when reboot start and it's loaded already */ | ||
| 668 | if (ovl == 0 && pageno == 0 && sc->dsp_firm) { | ||
| 669 | release_firmware(sc->dsp_firm); | ||
| 670 | sc->dsp_firm = NULL; | ||
| 671 | } | ||
| 672 | |||
| 673 | if (sc->dsp_firm == NULL && request_dsp(sc) < 0) | ||
| 674 | return; | ||
| 675 | |||
| 676 | p = sc->dsp_firm->data; | ||
| 677 | pagecount = FW_GET_BYTE(p); | ||
| 678 | p += 1; | ||
| 679 | |||
| 680 | if (pageno >= pagecount) | ||
| 681 | goto bad1; | ||
| 682 | |||
| 683 | p += 4 * pageno; | ||
| 684 | pageoffset = FW_GET_LONG(p); | ||
| 685 | |||
| 686 | if (pageoffset == 0) | ||
| 687 | goto bad1; | ||
| 688 | |||
| 689 | p = sc->dsp_firm->data + pageoffset; | ||
| 690 | blockcount = FW_GET_BYTE(p); | ||
| 691 | p += 1; | ||
| 692 | |||
| 693 | uea_dbg(INS_TO_USBDEV(sc), | ||
| 694 | "sending %u blocks for DSP page %u\n", blockcount, pageno); | ||
| 695 | |||
| 696 | bi.wHdr = cpu_to_le16(UEA_BIHDR); | ||
| 697 | bi.wOvl = cpu_to_le16(ovl); | ||
| 698 | bi.wOvlOffset = cpu_to_le16(ovl | 0x8000); | ||
| 699 | |||
| 700 | for (i = 0; i < blockcount; i++) { | ||
| 701 | blockaddr = FW_GET_WORD(p); | ||
| 702 | p += 2; | ||
| 703 | |||
| 704 | blocksize = FW_GET_WORD(p); | ||
| 705 | p += 2; | ||
| 706 | |||
| 707 | bi.wSize = cpu_to_le16(blocksize); | ||
| 708 | bi.wAddress = cpu_to_le16(blockaddr); | ||
| 709 | bi.wLast = cpu_to_le16((i == blockcount - 1) ? 1 : 0); | ||
| 710 | |||
| 711 | /* send block info through the IDMA pipe */ | ||
| 712 | if (uea_idma_write(sc, &bi, BLOCK_INFO_SIZE)) | ||
| 713 | goto bad2; | ||
| 714 | |||
| 715 | /* send block data through the IDMA pipe */ | ||
| 716 | if (uea_idma_write(sc, p, blocksize)) | ||
| 717 | goto bad2; | ||
| 718 | |||
| 719 | p += blocksize; | ||
| 720 | } | ||
| 721 | |||
| 722 | return; | ||
| 723 | |||
| 724 | bad2: | ||
| 725 | uea_err(INS_TO_USBDEV(sc), "sending DSP block %u failed\n", i); | ||
| 726 | return; | ||
| 727 | bad1: | ||
| 728 | uea_err(INS_TO_USBDEV(sc), "invalid DSP page %u requested\n",pageno); | ||
| 729 | } | ||
| 730 | |||
| 731 | static inline void wake_up_cmv_ack(struct uea_softc *sc) | ||
| 732 | { | ||
| 733 | sc->cmv_ack = 1; | ||
| 734 | wake_up(&sc->cmv_ack_wait); | ||
| 735 | } | ||
| 736 | |||
| 737 | static inline int wait_cmv_ack(struct uea_softc *sc) | ||
| 738 | { | ||
| 739 | int ret = wait_event_timeout(sc->cmv_ack_wait, | ||
| 740 | sc->cmv_ack, ACK_TIMEOUT); | ||
| 741 | sc->cmv_ack = 0; | ||
| 742 | |||
| 743 | if (ret < 0) | ||
| 744 | return ret; | ||
| 745 | |||
| 746 | return (ret == 0) ? -ETIMEDOUT : 0; | ||
| 747 | |||
| 748 | } | ||
| 749 | |||
| 750 | #define UCDC_SEND_ENCAPSULATED_COMMAND 0x00 | ||
| 751 | |||
| 752 | static int uea_request(struct uea_softc *sc, | ||
| 753 | u16 value, u16 index, u16 size, void *data) | ||
| 754 | { | ||
| 755 | u8 *xfer_buff; | ||
| 756 | int ret = -ENOMEM; | ||
| 757 | |||
| 758 | xfer_buff = kmalloc(size, GFP_KERNEL); | ||
| 759 | if (!xfer_buff) { | ||
| 760 | uea_err(INS_TO_USBDEV(sc), "can't allocate xfer_buff\n"); | ||
| 761 | return ret; | ||
| 762 | } | ||
| 763 | memcpy(xfer_buff, data, size); | ||
| 764 | |||
| 765 | ret = usb_control_msg(sc->usb_dev, usb_sndctrlpipe(sc->usb_dev, 0), | ||
| 766 | UCDC_SEND_ENCAPSULATED_COMMAND, | ||
| 767 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
| 768 | value, index, xfer_buff, size, CTRL_TIMEOUT); | ||
| 769 | |||
| 770 | kfree(xfer_buff); | ||
| 771 | if (ret < 0) { | ||
| 772 | uea_err(INS_TO_USBDEV(sc), "usb_control_msg error %d\n", ret); | ||
| 773 | return ret; | ||
| 774 | } | ||
| 775 | |||
| 776 | if (ret != size) { | ||
| 777 | uea_err(INS_TO_USBDEV(sc), | ||
| 778 | "usb_control_msg send only %d bytes (instead of %d)\n", | ||
| 779 | ret, size); | ||
| 780 | return -EIO; | ||
| 781 | } | ||
| 782 | |||
| 783 | return 0; | ||
| 784 | } | ||
| 785 | |||
| 786 | static int uea_cmv(struct uea_softc *sc, | ||
| 787 | u8 function, u32 address, u16 offset, u32 data) | ||
| 788 | { | ||
| 789 | struct cmv cmv; | ||
| 790 | int ret; | ||
| 791 | |||
| 792 | /* we send a request, but we expect a reply */ | ||
| 793 | sc->cmv_function = function | 0x2; | ||
| 794 | sc->cmv_idx++; | ||
| 795 | sc->cmv_address = address; | ||
| 796 | sc->cmv_offset = offset; | ||
| 797 | |||
| 798 | cmv.wPreamble = cpu_to_le16(PREAMBLE); | ||
| 799 | cmv.bDirection = HOSTTOMODEM; | ||
| 800 | cmv.bFunction = function; | ||
| 801 | cmv.wIndex = cpu_to_le16(sc->cmv_idx); | ||
| 802 | put_unaligned(cpu_to_le32(address), &cmv.dwSymbolicAddress); | ||
| 803 | cmv.wOffsetAddress = cpu_to_le16(offset); | ||
| 804 | put_unaligned(cpu_to_le32(data >> 16 | data << 16), &cmv.dwData); | ||
| 805 | |||
| 806 | ret = uea_request(sc, UEA_SET_BLOCK, UEA_MPTX_START, CMV_SIZE, &cmv); | ||
| 807 | if (ret < 0) | ||
| 808 | return ret; | ||
| 809 | return wait_cmv_ack(sc); | ||
| 810 | } | ||
| 811 | |||
| 812 | static inline int uea_read_cmv(struct uea_softc *sc, | ||
| 813 | u32 address, u16 offset, u32 *data) | ||
| 814 | { | ||
| 815 | int ret = uea_cmv(sc, MAKEFUNCTION(MEMACCESS, REQUESTREAD), | ||
| 816 | address, offset, 0); | ||
| 817 | if (ret < 0) | ||
| 818 | uea_err(INS_TO_USBDEV(sc), | ||
| 819 | "reading cmv failed with error %d\n", ret); | ||
| 820 | else | ||
| 821 | *data = sc->data; | ||
| 822 | |||
| 823 | return ret; | ||
| 824 | } | ||
| 825 | |||
| 826 | static inline int uea_write_cmv(struct uea_softc *sc, | ||
| 827 | u32 address, u16 offset, u32 data) | ||
| 828 | { | ||
| 829 | int ret = uea_cmv(sc, MAKEFUNCTION(MEMACCESS, REQUESTWRITE), | ||
| 830 | address, offset, data); | ||
| 831 | if (ret < 0) | ||
| 832 | uea_err(INS_TO_USBDEV(sc), | ||
| 833 | "writing cmv failed with error %d\n", ret); | ||
| 834 | |||
| 835 | return ret; | ||
| 836 | } | ||
| 837 | |||
| 838 | /* | ||
| 839 | * Monitor the modem and update the stat | ||
| 840 | * return 0 if everything is ok | ||
| 841 | * return < 0 if an error occurs (-EAGAIN reboot needed) | ||
| 842 | */ | ||
| 843 | static int uea_stat(struct uea_softc *sc) | ||
| 844 | { | ||
| 845 | u32 data; | ||
| 846 | int ret; | ||
| 847 | |||
| 848 | uea_enters(INS_TO_USBDEV(sc)); | ||
| 849 | data = sc->stats.phy.state; | ||
| 850 | |||
| 851 | ret = uea_read_cmv(sc, SA_STAT, 0, &sc->stats.phy.state); | ||
| 852 | if (ret < 0) | ||
| 853 | return ret; | ||
| 854 | |||
| 855 | switch (GET_STATUS(sc->stats.phy.state)) { | ||
| 856 | case 0: /* not yet synchronized */ | ||
| 857 | uea_dbg(INS_TO_USBDEV(sc), | ||
| 858 | "modem not yet synchronized\n"); | ||
| 859 | return 0; | ||
| 860 | |||
| 861 | case 1: /* initialization */ | ||
| 862 | uea_dbg(INS_TO_USBDEV(sc), "modem initializing\n"); | ||
| 863 | return 0; | ||
| 864 | |||
| 865 | case 2: /* operational */ | ||
| 866 | uea_vdbg(INS_TO_USBDEV(sc), "modem operational\n"); | ||
| 867 | break; | ||
| 868 | |||
| 869 | case 3: /* fail ... */ | ||
| 870 | uea_info(INS_TO_USBDEV(sc), "modem synchronization failed\n"); | ||
| 871 | return -EAGAIN; | ||
| 872 | |||
| 873 | case 4 ... 6: /* test state */ | ||
| 874 | uea_warn(INS_TO_USBDEV(sc), | ||
| 875 | "modem in test mode - not supported\n"); | ||
| 876 | return -EAGAIN; | ||
| 877 | |||
| 878 | case 7: /* fast-retain ... */ | ||
| 879 | uea_info(INS_TO_USBDEV(sc), "modem in fast-retain mode\n"); | ||
| 880 | return 0; | ||
| 881 | default: | ||
| 882 | uea_err(INS_TO_USBDEV(sc), "modem invalid SW mode %d\n", | ||
| 883 | GET_STATUS(sc->stats.phy.state)); | ||
| 884 | return -EAGAIN; | ||
| 885 | } | ||
| 886 | |||
| 887 | if (GET_STATUS(data) != 2) { | ||
| 888 | uea_request(sc, UEA_SET_MODE, UEA_LOOPBACK_OFF, 0, NULL); | ||
| 889 | uea_info(INS_TO_USBDEV(sc), "modem operational\n"); | ||
| 890 | |||
| 891 | /* release the dsp firmware as it is not needed until | ||
| 892 | * the next failure | ||
| 893 | */ | ||
| 894 | if (sc->dsp_firm) { | ||
| 895 | release_firmware(sc->dsp_firm); | ||
| 896 | sc->dsp_firm = NULL; | ||
| 897 | } | ||
| 898 | |||
| 899 | ret = uea_read_cmv(sc, SA_INFO, 10, &sc->stats.phy.firmid); | ||
| 900 | if (ret < 0) | ||
| 901 | return ret; | ||
| 902 | uea_info(INS_TO_USBDEV(sc), "ATU-R firmware version : %x\n", | ||
| 903 | sc->stats.phy.firmid); | ||
| 904 | } | ||
| 905 | |||
| 906 | /* always update it as atm layer could not be init when we switch to | ||
| 907 | * operational state | ||
| 908 | */ | ||
| 909 | UPDATE_ATM_STAT(signal, ATM_PHY_SIG_FOUND); | ||
| 910 | |||
| 911 | /* wake up processes waiting for synchronization */ | ||
| 912 | wake_up(&sc->sync_q); | ||
| 913 | |||
| 914 | ret = uea_read_cmv(sc, SA_DIAG, 2, &sc->stats.phy.flags); | ||
| 915 | if (ret < 0) | ||
| 916 | return ret; | ||
| 917 | sc->stats.phy.mflags |= sc->stats.phy.flags; | ||
| 918 | |||
| 919 | /* in case of a flags ( for example delineation LOSS (& 0x10)), | ||
| 920 | * we check the status again in order to detect the failure earlier | ||
| 921 | */ | ||
| 922 | if (sc->stats.phy.flags) { | ||
| 923 | uea_dbg(INS_TO_USBDEV(sc), "Stat flag = %d\n", | ||
| 924 | sc->stats.phy.flags); | ||
| 925 | return 0; | ||
| 926 | } | ||
| 927 | |||
| 928 | ret = uea_read_cmv(sc, SA_RATE, 0, &data); | ||
| 929 | if (ret < 0) | ||
| 930 | return ret; | ||
| 931 | |||
| 932 | /* in bulk mode the modem have problem with high rate | ||
| 933 | * changing internal timing could improve things, but the | ||
| 934 | * value is misterious. | ||
| 935 | * ADI930 don't support it (-EPIPE error). | ||
| 936 | */ | ||
| 937 | if (UEA_CHIP_VERSION(sc) != ADI930 | ||
| 938 | && sc->stats.phy.dsrate != (data >> 16) * 32) { | ||
| 939 | /* Original timming from ADI(used in windows driver) | ||
| 940 | * 0x20ffff>>16 * 32 = 32 * 32 = 1Mbits | ||
| 941 | */ | ||
| 942 | u16 timeout = (data <= 0x20ffff) ? 0 : 1; | ||
| 943 | ret = uea_request(sc, UEA_SET_TIMEOUT, timeout, 0, NULL); | ||
| 944 | uea_info(INS_TO_USBDEV(sc), | ||
| 945 | "setting new timeout %d%s\n", timeout, | ||
| 946 | ret < 0?" failed":""); | ||
| 947 | } | ||
| 948 | sc->stats.phy.dsrate = (data >> 16) * 32; | ||
| 949 | sc->stats.phy.usrate = (data & 0xffff) * 32; | ||
| 950 | UPDATE_ATM_STAT(link_rate, sc->stats.phy.dsrate * 1000 / 424); | ||
| 951 | |||
| 952 | ret = uea_read_cmv(sc, SA_DIAG, 23, &data); | ||
| 953 | if (ret < 0) | ||
| 954 | return ret; | ||
| 955 | sc->stats.phy.dsattenuation = (data & 0xff) / 2; | ||
| 956 | |||
| 957 | ret = uea_read_cmv(sc, SA_DIAG, 47, &data); | ||
| 958 | if (ret < 0) | ||
| 959 | return ret; | ||
| 960 | sc->stats.phy.usattenuation = (data & 0xff) / 2; | ||
| 961 | |||
| 962 | ret = uea_read_cmv(sc, SA_DIAG, 25, &sc->stats.phy.dsmargin); | ||
| 963 | if (ret < 0) | ||
| 964 | return ret; | ||
| 965 | |||
| 966 | ret = uea_read_cmv(sc, SA_DIAG, 49, &sc->stats.phy.usmargin); | ||
| 967 | if (ret < 0) | ||
| 968 | return ret; | ||
| 969 | |||
| 970 | ret = uea_read_cmv(sc, SA_DIAG, 51, &sc->stats.phy.rxflow); | ||
| 971 | if (ret < 0) | ||
| 972 | return ret; | ||
| 973 | |||
| 974 | ret = uea_read_cmv(sc, SA_DIAG, 52, &sc->stats.phy.txflow); | ||
| 975 | if (ret < 0) | ||
| 976 | return ret; | ||
| 977 | |||
| 978 | ret = uea_read_cmv(sc, SA_DIAG, 54, &sc->stats.phy.dsunc); | ||
| 979 | if (ret < 0) | ||
| 980 | return ret; | ||
| 981 | |||
| 982 | /* only for atu-c */ | ||
| 983 | ret = uea_read_cmv(sc, SA_DIAG, 58, &sc->stats.phy.usunc); | ||
| 984 | if (ret < 0) | ||
| 985 | return ret; | ||
| 986 | |||
| 987 | ret = uea_read_cmv(sc, SA_DIAG, 53, &sc->stats.phy.dscorr); | ||
| 988 | if (ret < 0) | ||
| 989 | return ret; | ||
| 990 | |||
| 991 | /* only for atu-c */ | ||
| 992 | ret = uea_read_cmv(sc, SA_DIAG, 57, &sc->stats.phy.uscorr); | ||
| 993 | if (ret < 0) | ||
| 994 | return ret; | ||
| 995 | |||
| 996 | ret = uea_read_cmv(sc, SA_INFO, 8, &sc->stats.phy.vidco); | ||
| 997 | if (ret < 0) | ||
| 998 | return ret; | ||
| 999 | |||
| 1000 | ret = uea_read_cmv(sc, SA_INFO, 13, &sc->stats.phy.vidcpe); | ||
| 1001 | if (ret < 0) | ||
| 1002 | return ret; | ||
| 1003 | |||
| 1004 | return 0; | ||
| 1005 | } | ||
| 1006 | |||
| 1007 | static int request_cmvs(struct uea_softc *sc, | ||
| 1008 | struct uea_cmvs **cmvs, const struct firmware **fw) | ||
| 1009 | { | ||
| 1010 | int ret, size; | ||
| 1011 | u8 *data; | ||
| 1012 | char *file; | ||
| 1013 | static char cmv_name[256] = FW_DIR; | ||
| 1014 | |||
| 1015 | if (cmv_file[sc->modem_index] == NULL) { | ||
| 1016 | if (UEA_CHIP_VERSION(sc) == ADI930) | ||
| 1017 | file = (IS_ISDN(sc)) ? "CMV9i.bin" : "CMV9p.bin"; | ||
| 1018 | else | ||
| 1019 | file = (IS_ISDN(sc)) ? "CMVei.bin" : "CMVep.bin"; | ||
| 1020 | } else | ||
| 1021 | file = cmv_file[sc->modem_index]; | ||
| 1022 | |||
| 1023 | strcpy(cmv_name, FW_DIR); | ||
| 1024 | strlcat(cmv_name, file, sizeof(cmv_name)); | ||
| 1025 | |||
| 1026 | ret = request_firmware(fw, cmv_name, &sc->usb_dev->dev); | ||
| 1027 | if (ret < 0) { | ||
| 1028 | uea_err(INS_TO_USBDEV(sc), | ||
| 1029 | "requesting firmware %s failed with error %d\n", | ||
| 1030 | cmv_name, ret); | ||
| 1031 | return ret; | ||
| 1032 | } | ||
| 1033 | |||
| 1034 | data = (u8 *) (*fw)->data; | ||
| 1035 | size = *data * sizeof(struct uea_cmvs) + 1; | ||
| 1036 | if (size != (*fw)->size) { | ||
| 1037 | uea_err(INS_TO_USBDEV(sc), "firmware %s is corrupted\n", | ||
| 1038 | cmv_name); | ||
| 1039 | release_firmware(*fw); | ||
| 1040 | return -EILSEQ; | ||
| 1041 | } | ||
| 1042 | |||
| 1043 | *cmvs = (struct uea_cmvs *)(data + 1); | ||
| 1044 | return *data; | ||
| 1045 | } | ||
| 1046 | |||
| 1047 | /* Start boot post firmware modem: | ||
| 1048 | * - send reset commands through usb control pipe | ||
| 1049 | * - start workqueue for DSP loading | ||
| 1050 | * - send CMV options to modem | ||
| 1051 | */ | ||
| 1052 | |||
| 1053 | static int uea_start_reset(struct uea_softc *sc) | ||
| 1054 | { | ||
| 1055 | u16 zero = 0; /* ;-) */ | ||
| 1056 | int i, len, ret; | ||
| 1057 | struct uea_cmvs *cmvs; | ||
| 1058 | const struct firmware *cmvs_fw; | ||
| 1059 | |||
| 1060 | uea_enters(INS_TO_USBDEV(sc)); | ||
| 1061 | uea_info(INS_TO_USBDEV(sc), "(re)booting started\n"); | ||
| 1062 | |||
| 1063 | sc->booting = 1; | ||
| 1064 | UPDATE_ATM_STAT(signal, ATM_PHY_SIG_LOST); | ||
| 1065 | |||
| 1066 | /* reset statistics */ | ||
| 1067 | memset(&sc->stats, 0, sizeof(struct uea_stats)); | ||
| 1068 | |||
| 1069 | /* tell the modem that we want to boot in IDMA mode */ | ||
| 1070 | uea_request(sc, UEA_SET_MODE, UEA_LOOPBACK_ON, 0, NULL); | ||
| 1071 | uea_request(sc, UEA_SET_MODE, UEA_BOOT_IDMA, 0, NULL); | ||
| 1072 | |||
| 1073 | /* enter reset mode */ | ||
| 1074 | uea_request(sc, UEA_SET_MODE, UEA_START_RESET, 0, NULL); | ||
| 1075 | |||
| 1076 | /* original driver use 200ms, but windows driver use 100ms */ | ||
| 1077 | msleep(100); | ||
| 1078 | |||
| 1079 | /* leave reset mode */ | ||
| 1080 | uea_request(sc, UEA_SET_MODE, UEA_END_RESET, 0, NULL); | ||
| 1081 | |||
| 1082 | /* clear tx and rx mailboxes */ | ||
| 1083 | uea_request(sc, UEA_SET_2183_DATA, UEA_MPTX_MAILBOX, 2, &zero); | ||
| 1084 | uea_request(sc, UEA_SET_2183_DATA, UEA_MPRX_MAILBOX, 2, &zero); | ||
| 1085 | uea_request(sc, UEA_SET_2183_DATA, UEA_SWAP_MAILBOX, 2, &zero); | ||
| 1086 | |||
| 1087 | msleep(1000); | ||
| 1088 | sc->cmv_function = MAKEFUNCTION(ADSLDIRECTIVE, MODEMREADY); | ||
| 1089 | sc->booting = 0; | ||
| 1090 | |||
| 1091 | /* start loading DSP */ | ||
| 1092 | sc->pageno = 0; | ||
| 1093 | sc->ovl = 0; | ||
| 1094 | schedule_work(&sc->task); | ||
| 1095 | |||
| 1096 | /* wait for modem ready CMV */ | ||
| 1097 | ret = wait_cmv_ack(sc); | ||
| 1098 | if (ret < 0) | ||
| 1099 | return ret; | ||
| 1100 | |||
| 1101 | /* Enter in R-IDLE (cmv) until instructed otherwise */ | ||
| 1102 | ret = uea_write_cmv(sc, SA_CNTL, 0, 1); | ||
| 1103 | if (ret < 0) | ||
| 1104 | return ret; | ||
| 1105 | |||
| 1106 | /* get options */ | ||
| 1107 | ret = len = request_cmvs(sc, &cmvs, &cmvs_fw); | ||
| 1108 | if (ret < 0) | ||
| 1109 | return ret; | ||
| 1110 | |||
| 1111 | /* send options */ | ||
| 1112 | for (i = 0; i < len; i++) { | ||
| 1113 | ret = uea_write_cmv(sc, FW_GET_LONG(&cmvs[i].address), | ||
| 1114 | FW_GET_WORD(&cmvs[i].offset), | ||
| 1115 | FW_GET_LONG(&cmvs[i].data)); | ||
| 1116 | if (ret < 0) | ||
| 1117 | goto out; | ||
| 1118 | } | ||
| 1119 | /* Enter in R-ACT-REQ */ | ||
| 1120 | ret = uea_write_cmv(sc, SA_CNTL, 0, 2); | ||
| 1121 | out: | ||
| 1122 | release_firmware(cmvs_fw); | ||
| 1123 | sc->reset = 0; | ||
| 1124 | uea_leaves(INS_TO_USBDEV(sc)); | ||
| 1125 | return ret; | ||
| 1126 | } | ||
| 1127 | |||
| 1128 | /* | ||
| 1129 | * In case of an error wait 1s before rebooting the modem | ||
| 1130 | * if the modem don't request reboot (-EAGAIN). | ||
| 1131 | * Monitor the modem every 1s. | ||
| 1132 | */ | ||
| 1133 | |||
| 1134 | static int uea_kthread(void *data) | ||
| 1135 | { | ||
| 1136 | struct uea_softc *sc = data; | ||
| 1137 | int ret = -EAGAIN; | ||
| 1138 | |||
| 1139 | uea_enters(INS_TO_USBDEV(sc)); | ||
| 1140 | while (!kthread_should_stop()) { | ||
| 1141 | if (ret < 0 || sc->reset) | ||
| 1142 | ret = uea_start_reset(sc); | ||
| 1143 | if (!ret) | ||
| 1144 | ret = uea_stat(sc); | ||
| 1145 | if (ret != -EAGAIN) | ||
| 1146 | msleep(1000); | ||
| 1147 | } | ||
| 1148 | uea_leaves(INS_TO_USBDEV(sc)); | ||
| 1149 | return ret; | ||
| 1150 | } | ||
| 1151 | |||
| 1152 | /* Load second usb firmware for ADI930 chip */ | ||
| 1153 | static int load_XILINX_firmware(struct uea_softc *sc) | ||
| 1154 | { | ||
| 1155 | const struct firmware *fw_entry; | ||
| 1156 | int ret, size, u, ln; | ||
| 1157 | u8 *pfw, value; | ||
| 1158 | char *fw_name = FW_DIR "930-fpga.bin"; | ||
| 1159 | |||
| 1160 | uea_enters(INS_TO_USBDEV(sc)); | ||
| 1161 | |||
| 1162 | ret = request_firmware(&fw_entry, fw_name, &sc->usb_dev->dev); | ||
| 1163 | if (ret) { | ||
| 1164 | uea_err(INS_TO_USBDEV(sc), "firmware %s is not available\n", | ||
| 1165 | fw_name); | ||
| 1166 | goto err0; | ||
| 1167 | } | ||
| 1168 | |||
| 1169 | pfw = fw_entry->data; | ||
| 1170 | size = fw_entry->size; | ||
| 1171 | if (size != 0x577B) { | ||
| 1172 | uea_err(INS_TO_USBDEV(sc), "firmware %s is corrupted\n", | ||
| 1173 | fw_name); | ||
| 1174 | ret = -EILSEQ; | ||
| 1175 | goto err1; | ||
| 1176 | } | ||
| 1177 | for (u = 0; u < size; u += ln) { | ||
| 1178 | ln = min(size - u, 64); | ||
| 1179 | ret = uea_request(sc, 0xe, 0, ln, pfw + u); | ||
| 1180 | if (ret < 0) { | ||
| 1181 | uea_err(INS_TO_USBDEV(sc), | ||
| 1182 | "elsa download data failed (%d)\n", ret); | ||
| 1183 | goto err1; | ||
| 1184 | } | ||
| 1185 | } | ||
| 1186 | |||
| 1187 | /* finish to send the fpga | ||
| 1188 | */ | ||
| 1189 | ret = uea_request(sc, 0xe, 1, 0, NULL); | ||
| 1190 | if (ret < 0) { | ||
| 1191 | uea_err(INS_TO_USBDEV(sc), | ||
| 1192 | "elsa download data failed (%d)\n", ret); | ||
| 1193 | goto err1; | ||
| 1194 | } | ||
| 1195 | |||
| 1196 | /* | ||
| 1197 | * Tell the modem we finish : de-assert reset | ||
| 1198 | */ | ||
| 1199 | value = 0; | ||
| 1200 | ret = uea_send_modem_cmd(sc->usb_dev, 0xe, 1, &value); | ||
| 1201 | if (ret < 0) | ||
| 1202 | uea_err(sc->usb_dev, "elsa de-assert failed with error %d\n", ret); | ||
| 1203 | |||
| 1204 | |||
| 1205 | err1: | ||
| 1206 | release_firmware(fw_entry); | ||
| 1207 | err0: | ||
| 1208 | uea_leaves(INS_TO_USBDEV(sc)); | ||
| 1209 | return ret; | ||
| 1210 | } | ||
| 1211 | |||
| 1212 | static void uea_dispatch_cmv(struct uea_softc *sc, struct cmv* cmv) | ||
| 1213 | { | ||
| 1214 | uea_enters(INS_TO_USBDEV(sc)); | ||
| 1215 | if (le16_to_cpu(cmv->wPreamble) != PREAMBLE) | ||
| 1216 | goto bad1; | ||
| 1217 | |||
| 1218 | if (cmv->bDirection != MODEMTOHOST) | ||
| 1219 | goto bad1; | ||
| 1220 | |||
| 1221 | /* FIXME : ADI930 reply wrong preambule (func = 2, sub = 2) to | ||
| 1222 | * the first MEMACESS cmv. Ignore it... | ||
| 1223 | */ | ||
| 1224 | if (cmv->bFunction != sc->cmv_function) { | ||
| 1225 | if (UEA_CHIP_VERSION(sc) == ADI930 | ||
| 1226 | && cmv->bFunction == MAKEFUNCTION(2, 2)) { | ||
| 1227 | cmv->wIndex = cpu_to_le16(sc->cmv_idx); | ||
| 1228 | put_unaligned(cpu_to_le32(sc->cmv_address), &cmv->dwSymbolicAddress); | ||
| 1229 | cmv->wOffsetAddress = cpu_to_le16(sc->cmv_offset); | ||
| 1230 | } | ||
| 1231 | else | ||
| 1232 | goto bad2; | ||
| 1233 | } | ||
| 1234 | |||
| 1235 | if (cmv->bFunction == MAKEFUNCTION(ADSLDIRECTIVE, MODEMREADY)) { | ||
| 1236 | wake_up_cmv_ack(sc); | ||
| 1237 | return; | ||
| 1238 | } | ||
| 1239 | |||
| 1240 | /* in case of MEMACCESS */ | ||
| 1241 | if (le16_to_cpu(cmv->wIndex) != sc->cmv_idx || | ||
| 1242 | le32_to_cpu(get_unaligned(&cmv->dwSymbolicAddress)) != | ||
| 1243 | sc->cmv_address | ||
| 1244 | || le16_to_cpu(cmv->wOffsetAddress) != sc->cmv_offset) | ||
| 1245 | goto bad2; | ||
| 1246 | |||
| 1247 | sc->data = le32_to_cpu(get_unaligned(&cmv->dwData)); | ||
| 1248 | sc->data = sc->data << 16 | sc->data >> 16; | ||
| 1249 | |||
| 1250 | wake_up_cmv_ack(sc); | ||
| 1251 | return; | ||
| 1252 | |||
| 1253 | bad2: | ||
| 1254 | uea_err(INS_TO_USBDEV(sc), "unexpected cmv received," | ||
| 1255 | "Function : %d, Subfunction : %d\n", | ||
| 1256 | FUNCTION_TYPE(cmv->bFunction), | ||
| 1257 | FUNCTION_SUBTYPE(cmv->bFunction)); | ||
| 1258 | return; | ||
| 1259 | |||
| 1260 | bad1: | ||
| 1261 | uea_err(INS_TO_USBDEV(sc), "invalid cmv received, " | ||
| 1262 | "wPreamble %d, bDirection %d\n", | ||
| 1263 | le16_to_cpu(cmv->wPreamble), cmv->bDirection); | ||
| 1264 | } | ||
| 1265 | |||
| 1266 | /* | ||
| 1267 | * interrupt handler | ||
| 1268 | */ | ||
| 1269 | static void uea_intr(struct urb *urb, struct pt_regs *regs) | ||
| 1270 | { | ||
| 1271 | struct uea_softc *sc = (struct uea_softc *)urb->context; | ||
| 1272 | struct intr_pkt *intr; | ||
| 1273 | uea_enters(INS_TO_USBDEV(sc)); | ||
| 1274 | |||
| 1275 | if (urb->status < 0) { | ||
| 1276 | uea_err(INS_TO_USBDEV(sc), "uea_intr() failed with %d\n", | ||
| 1277 | urb->status); | ||
| 1278 | return; | ||
| 1279 | } | ||
| 1280 | |||
| 1281 | intr = (struct intr_pkt *) urb->transfer_buffer; | ||
| 1282 | |||
| 1283 | /* device-to-host interrupt */ | ||
| 1284 | if (intr->bType != 0x08 || sc->booting) { | ||
| 1285 | uea_err(INS_TO_USBDEV(sc), "wrong intr\n"); | ||
| 1286 | // rebooting ? | ||
| 1287 | // sc->reset = 1; | ||
| 1288 | goto resubmit; | ||
| 1289 | } | ||
| 1290 | |||
| 1291 | switch (le16_to_cpu(intr->wInterrupt)) { | ||
| 1292 | case INT_LOADSWAPPAGE: | ||
| 1293 | sc->pageno = intr->bSwapPageNo; | ||
| 1294 | sc->ovl = intr->bOvl >> 4 | intr->bOvl << 4; | ||
| 1295 | schedule_work(&sc->task); | ||
| 1296 | break; | ||
| 1297 | |||
| 1298 | case INT_INCOMINGCMV: | ||
| 1299 | uea_dispatch_cmv(sc, &intr->u.s2.cmv); | ||
| 1300 | break; | ||
| 1301 | |||
| 1302 | default: | ||
| 1303 | uea_err(INS_TO_USBDEV(sc), "unknown intr %u\n", | ||
| 1304 | le16_to_cpu(intr->wInterrupt)); | ||
| 1305 | } | ||
| 1306 | |||
| 1307 | resubmit: | ||
| 1308 | usb_submit_urb(sc->urb_int, GFP_ATOMIC); | ||
| 1309 | } | ||
| 1310 | |||
| 1311 | /* | ||
| 1312 | * Start the modem : init the data and start kernel thread | ||
| 1313 | */ | ||
| 1314 | static int uea_boot(struct uea_softc *sc) | ||
| 1315 | { | ||
| 1316 | int ret; | ||
| 1317 | struct intr_pkt *intr; | ||
| 1318 | |||
| 1319 | uea_enters(INS_TO_USBDEV(sc)); | ||
| 1320 | |||
| 1321 | INIT_WORK(&sc->task, uea_load_page, sc); | ||
| 1322 | init_waitqueue_head(&sc->sync_q); | ||
| 1323 | init_waitqueue_head(&sc->cmv_ack_wait); | ||
| 1324 | |||
| 1325 | if (UEA_CHIP_VERSION(sc) == ADI930) | ||
| 1326 | load_XILINX_firmware(sc); | ||
| 1327 | |||
| 1328 | intr = kmalloc(INTR_PKT_SIZE, GFP_KERNEL); | ||
| 1329 | if (!intr) { | ||
| 1330 | uea_err(INS_TO_USBDEV(sc), | ||
| 1331 | "cannot allocate interrupt package\n"); | ||
| 1332 | uea_leaves(INS_TO_USBDEV(sc)); | ||
| 1333 | return -ENOMEM; | ||
| 1334 | } | ||
| 1335 | |||
| 1336 | sc->urb_int = usb_alloc_urb(0, GFP_KERNEL); | ||
| 1337 | if (!sc->urb_int) { | ||
| 1338 | uea_err(INS_TO_USBDEV(sc), "cannot allocate interrupt URB\n"); | ||
| 1339 | goto err; | ||
| 1340 | } | ||
| 1341 | |||
| 1342 | usb_fill_int_urb(sc->urb_int, sc->usb_dev, | ||
| 1343 | usb_rcvintpipe(sc->usb_dev, UEA_INTR_PIPE), | ||
| 1344 | intr, INTR_PKT_SIZE, uea_intr, sc, | ||
| 1345 | sc->usb_dev->actconfig->interface[0]->altsetting[0]. | ||
| 1346 | endpoint[0].desc.bInterval); | ||
| 1347 | |||
| 1348 | ret = usb_submit_urb(sc->urb_int, GFP_KERNEL); | ||
| 1349 | if (ret < 0) { | ||
| 1350 | uea_err(INS_TO_USBDEV(sc), | ||
| 1351 | "urb submition failed with error %d\n", ret); | ||
| 1352 | goto err1; | ||
| 1353 | } | ||
| 1354 | |||
| 1355 | sc->kthread = kthread_run(uea_kthread, sc, "ueagle-atm"); | ||
| 1356 | if (sc->kthread == ERR_PTR(-ENOMEM)) { | ||
| 1357 | uea_err(INS_TO_USBDEV(sc), "failed to create thread\n"); | ||
| 1358 | goto err2; | ||
| 1359 | } | ||
| 1360 | |||
| 1361 | uea_leaves(INS_TO_USBDEV(sc)); | ||
| 1362 | return 0; | ||
| 1363 | |||
| 1364 | err2: | ||
| 1365 | usb_kill_urb(sc->urb_int); | ||
| 1366 | err1: | ||
| 1367 | kfree(intr); | ||
| 1368 | err: | ||
| 1369 | usb_free_urb(sc->urb_int); | ||
| 1370 | uea_leaves(INS_TO_USBDEV(sc)); | ||
| 1371 | return -ENOMEM; | ||
| 1372 | } | ||
| 1373 | |||
| 1374 | /* | ||
| 1375 | * Stop the modem : kill kernel thread and free data | ||
| 1376 | */ | ||
| 1377 | static void uea_stop(struct uea_softc *sc) | ||
| 1378 | { | ||
| 1379 | int ret; | ||
| 1380 | uea_enters(INS_TO_USBDEV(sc)); | ||
| 1381 | ret = kthread_stop(sc->kthread); | ||
| 1382 | uea_info(INS_TO_USBDEV(sc), "kthread finish with status %d\n", ret); | ||
| 1383 | |||
| 1384 | /* stop any pending boot process */ | ||
| 1385 | flush_scheduled_work(); | ||
| 1386 | |||
| 1387 | uea_request(sc, UEA_SET_MODE, UEA_LOOPBACK_ON, 0, NULL); | ||
| 1388 | |||
| 1389 | usb_kill_urb(sc->urb_int); | ||
| 1390 | kfree(sc->urb_int->transfer_buffer); | ||
| 1391 | usb_free_urb(sc->urb_int); | ||
| 1392 | |||
| 1393 | if (sc->dsp_firm) | ||
| 1394 | release_firmware(sc->dsp_firm); | ||
| 1395 | uea_leaves(INS_TO_USBDEV(sc)); | ||
| 1396 | } | ||
| 1397 | |||
| 1398 | /* syfs interface */ | ||
| 1399 | static struct uea_softc *dev_to_uea(struct device *dev) | ||
| 1400 | { | ||
| 1401 | struct usb_interface *intf; | ||
| 1402 | struct usbatm_data *usbatm; | ||
| 1403 | |||
| 1404 | intf = to_usb_interface(dev); | ||
| 1405 | if (!intf) | ||
| 1406 | return NULL; | ||
| 1407 | |||
| 1408 | usbatm = usb_get_intfdata(intf); | ||
| 1409 | if (!usbatm) | ||
| 1410 | return NULL; | ||
| 1411 | |||
| 1412 | return usbatm->driver_data; | ||
| 1413 | } | ||
| 1414 | |||
| 1415 | static ssize_t read_status(struct device *dev, struct device_attribute *attr, | ||
| 1416 | char *buf) | ||
| 1417 | { | ||
| 1418 | int ret = -ENODEV; | ||
| 1419 | struct uea_softc *sc; | ||
| 1420 | |||
| 1421 | down(&uea_semaphore); | ||
| 1422 | sc = dev_to_uea(dev); | ||
| 1423 | if (!sc) | ||
| 1424 | goto out; | ||
| 1425 | ret = snprintf(buf, 10, "%08x\n", sc->stats.phy.state); | ||
| 1426 | out: | ||
| 1427 | up(&uea_semaphore); | ||
| 1428 | return ret; | ||
| 1429 | } | ||
| 1430 | |||
| 1431 | static ssize_t reboot(struct device *dev, struct device_attribute *attr, | ||
| 1432 | const char *buf, size_t count) | ||
| 1433 | { | ||
| 1434 | int ret = -ENODEV; | ||
| 1435 | struct uea_softc *sc; | ||
| 1436 | |||
| 1437 | down(&uea_semaphore); | ||
| 1438 | sc = dev_to_uea(dev); | ||
| 1439 | if (!sc) | ||
| 1440 | goto out; | ||
| 1441 | sc->reset = 1; | ||
| 1442 | ret = count; | ||
| 1443 | out: | ||
| 1444 | up(&uea_semaphore); | ||
| 1445 | return ret; | ||
| 1446 | } | ||
| 1447 | |||
| 1448 | static DEVICE_ATTR(stat_status, S_IWUGO | S_IRUGO, read_status, reboot); | ||
| 1449 | |||
| 1450 | static ssize_t read_human_status(struct device *dev, struct device_attribute *attr, | ||
| 1451 | char *buf) | ||
| 1452 | { | ||
| 1453 | int ret = -ENODEV; | ||
| 1454 | struct uea_softc *sc; | ||
| 1455 | |||
| 1456 | down(&uea_semaphore); | ||
| 1457 | sc = dev_to_uea(dev); | ||
| 1458 | if (!sc) | ||
| 1459 | goto out; | ||
| 1460 | |||
| 1461 | switch (GET_STATUS(sc->stats.phy.state)) { | ||
| 1462 | case 0: | ||
| 1463 | ret = sprintf(buf, "Modem is booting\n"); | ||
| 1464 | break; | ||
| 1465 | case 1: | ||
| 1466 | ret = sprintf(buf, "Modem is initializing\n"); | ||
| 1467 | break; | ||
| 1468 | case 2: | ||
| 1469 | ret = sprintf(buf, "Modem is operational\n"); | ||
| 1470 | break; | ||
| 1471 | default: | ||
| 1472 | ret = sprintf(buf, "Modem synchronization failed\n"); | ||
| 1473 | break; | ||
| 1474 | } | ||
| 1475 | out: | ||
| 1476 | up(&uea_semaphore); | ||
| 1477 | return ret; | ||
| 1478 | } | ||
| 1479 | |||
| 1480 | static DEVICE_ATTR(stat_human_status, S_IWUGO | S_IRUGO, read_human_status, NULL); | ||
| 1481 | |||
| 1482 | static ssize_t read_delin(struct device *dev, struct device_attribute *attr, | ||
| 1483 | char *buf) | ||
| 1484 | { | ||
| 1485 | int ret = -ENODEV; | ||
| 1486 | struct uea_softc *sc; | ||
| 1487 | |||
| 1488 | down(&uea_semaphore); | ||
| 1489 | sc = dev_to_uea(dev); | ||
| 1490 | if (!sc) | ||
| 1491 | goto out; | ||
| 1492 | |||
| 1493 | if (sc->stats.phy.flags & 0x0C00) | ||
| 1494 | ret = sprintf(buf, "ERROR\n"); | ||
| 1495 | else if (sc->stats.phy.flags & 0x0030) | ||
| 1496 | ret = sprintf(buf, "LOSS\n"); | ||
| 1497 | else | ||
| 1498 | ret = sprintf(buf, "GOOD\n"); | ||
| 1499 | out: | ||
| 1500 | up(&uea_semaphore); | ||
| 1501 | return ret; | ||
| 1502 | } | ||
| 1503 | |||
| 1504 | static DEVICE_ATTR(stat_delin, S_IWUGO | S_IRUGO, read_delin, NULL); | ||
| 1505 | |||
| 1506 | #define UEA_ATTR(name, reset) \ | ||
| 1507 | \ | ||
| 1508 | static ssize_t read_##name(struct device *dev, \ | ||
| 1509 | struct device_attribute *attr, char *buf) \ | ||
| 1510 | { \ | ||
| 1511 | int ret = -ENODEV; \ | ||
| 1512 | struct uea_softc *sc; \ | ||
| 1513 | \ | ||
| 1514 | down(&uea_semaphore); \ | ||
| 1515 | sc = dev_to_uea(dev); \ | ||
| 1516 | if (!sc) \ | ||
| 1517 | goto out; \ | ||
| 1518 | ret = snprintf(buf, 10, "%08x\n", sc->stats.phy.name); \ | ||
| 1519 | if (reset) \ | ||
| 1520 | sc->stats.phy.name = 0; \ | ||
| 1521 | out: \ | ||
| 1522 | up(&uea_semaphore); \ | ||
| 1523 | return ret; \ | ||
| 1524 | } \ | ||
| 1525 | \ | ||
| 1526 | static DEVICE_ATTR(stat_##name, S_IRUGO, read_##name, NULL) | ||
| 1527 | |||
| 1528 | UEA_ATTR(mflags, 1); | ||
| 1529 | UEA_ATTR(vidcpe, 0); | ||
| 1530 | UEA_ATTR(usrate, 0); | ||
| 1531 | UEA_ATTR(dsrate, 0); | ||
| 1532 | UEA_ATTR(usattenuation, 0); | ||
| 1533 | UEA_ATTR(dsattenuation, 0); | ||
| 1534 | UEA_ATTR(usmargin, 0); | ||
| 1535 | UEA_ATTR(dsmargin, 0); | ||
| 1536 | UEA_ATTR(txflow, 0); | ||
| 1537 | UEA_ATTR(rxflow, 0); | ||
| 1538 | UEA_ATTR(uscorr, 0); | ||
| 1539 | UEA_ATTR(dscorr, 0); | ||
| 1540 | UEA_ATTR(usunc, 0); | ||
| 1541 | UEA_ATTR(dsunc, 0); | ||
| 1542 | |||
| 1543 | /* Retrieve the device End System Identifier (MAC) */ | ||
| 1544 | |||
| 1545 | #define htoi(x) (isdigit(x) ? x-'0' : toupper(x)-'A'+10) | ||
| 1546 | static int uea_getesi(struct uea_softc *sc, u_char * esi) | ||
| 1547 | { | ||
| 1548 | unsigned char mac_str[2 * ETH_ALEN + 1]; | ||
| 1549 | int i; | ||
| 1550 | if (usb_string | ||
| 1551 | (sc->usb_dev, sc->usb_dev->descriptor.iSerialNumber, mac_str, | ||
| 1552 | sizeof(mac_str)) != 2 * ETH_ALEN) | ||
| 1553 | return 1; | ||
| 1554 | |||
| 1555 | for (i = 0; i < ETH_ALEN; i++) | ||
| 1556 | esi[i] = htoi(mac_str[2 * i]) * 16 + htoi(mac_str[2 * i + 1]); | ||
| 1557 | |||
| 1558 | return 0; | ||
| 1559 | } | ||
| 1560 | |||
| 1561 | /* ATM stuff */ | ||
| 1562 | static int uea_atm_open(struct usbatm_data *usbatm, struct atm_dev *atm_dev) | ||
| 1563 | { | ||
| 1564 | struct uea_softc *sc = usbatm->driver_data; | ||
| 1565 | |||
| 1566 | return uea_getesi(sc, atm_dev->esi); | ||
| 1567 | } | ||
| 1568 | |||
| 1569 | static int uea_heavy(struct usbatm_data *usbatm, struct usb_interface *intf) | ||
| 1570 | { | ||
| 1571 | struct uea_softc *sc = usbatm->driver_data; | ||
| 1572 | |||
| 1573 | wait_event(sc->sync_q, IS_OPERATIONAL(sc)); | ||
| 1574 | |||
| 1575 | return 0; | ||
| 1576 | |||
| 1577 | } | ||
| 1578 | |||
| 1579 | static int claim_interface(struct usb_device *usb_dev, | ||
| 1580 | struct usbatm_data *usbatm, int ifnum) | ||
| 1581 | { | ||
| 1582 | int ret; | ||
| 1583 | struct usb_interface *intf = usb_ifnum_to_if(usb_dev, ifnum); | ||
| 1584 | |||
| 1585 | if (!intf) { | ||
| 1586 | uea_err(usb_dev, "interface %d not found\n", ifnum); | ||
| 1587 | return -ENODEV; | ||
| 1588 | } | ||
| 1589 | |||
| 1590 | ret = usb_driver_claim_interface(&uea_driver, intf, usbatm); | ||
| 1591 | if (ret != 0) | ||
| 1592 | uea_err(usb_dev, "can't claim interface %d, error %d\n", ifnum, | ||
| 1593 | ret); | ||
| 1594 | return ret; | ||
| 1595 | } | ||
| 1596 | |||
| 1597 | static void create_fs_entries(struct uea_softc *sc, struct usb_interface *intf) | ||
| 1598 | { | ||
| 1599 | /* sysfs interface */ | ||
| 1600 | device_create_file(&intf->dev, &dev_attr_stat_status); | ||
| 1601 | device_create_file(&intf->dev, &dev_attr_stat_mflags); | ||
| 1602 | device_create_file(&intf->dev, &dev_attr_stat_human_status); | ||
| 1603 | device_create_file(&intf->dev, &dev_attr_stat_delin); | ||
| 1604 | device_create_file(&intf->dev, &dev_attr_stat_vidcpe); | ||
| 1605 | device_create_file(&intf->dev, &dev_attr_stat_usrate); | ||
| 1606 | device_create_file(&intf->dev, &dev_attr_stat_dsrate); | ||
| 1607 | device_create_file(&intf->dev, &dev_attr_stat_usattenuation); | ||
| 1608 | device_create_file(&intf->dev, &dev_attr_stat_dsattenuation); | ||
| 1609 | device_create_file(&intf->dev, &dev_attr_stat_usmargin); | ||
| 1610 | device_create_file(&intf->dev, &dev_attr_stat_dsmargin); | ||
| 1611 | device_create_file(&intf->dev, &dev_attr_stat_txflow); | ||
| 1612 | device_create_file(&intf->dev, &dev_attr_stat_rxflow); | ||
| 1613 | device_create_file(&intf->dev, &dev_attr_stat_uscorr); | ||
| 1614 | device_create_file(&intf->dev, &dev_attr_stat_dscorr); | ||
| 1615 | device_create_file(&intf->dev, &dev_attr_stat_usunc); | ||
| 1616 | device_create_file(&intf->dev, &dev_attr_stat_dsunc); | ||
| 1617 | } | ||
| 1618 | |||
| 1619 | static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf, | ||
| 1620 | const struct usb_device_id *id, int *heavy) | ||
| 1621 | { | ||
| 1622 | struct usb_device *usb = interface_to_usbdev(intf); | ||
| 1623 | struct uea_softc *sc; | ||
| 1624 | int ret, ifnum = intf->altsetting->desc.bInterfaceNumber; | ||
| 1625 | |||
| 1626 | uea_enters(usb); | ||
| 1627 | |||
| 1628 | /* interface 0 is for firmware/monitoring */ | ||
| 1629 | if (ifnum != UEA_INTR_IFACE_NO) | ||
| 1630 | return -ENODEV; | ||
| 1631 | |||
| 1632 | *heavy = sync_wait[modem_index]; | ||
| 1633 | |||
| 1634 | /* interface 1 is for outbound traffic */ | ||
| 1635 | ret = claim_interface(usb, usbatm, UEA_US_IFACE_NO); | ||
| 1636 | if (ret < 0) | ||
| 1637 | return ret; | ||
| 1638 | |||
| 1639 | /* ADI930 has only 2 interfaces and inbound traffic | ||
| 1640 | * is on interface 1 | ||
| 1641 | */ | ||
| 1642 | if (UEA_CHIP_VERSION(id) != ADI930) { | ||
| 1643 | /* interface 2 is for inbound traffic */ | ||
| 1644 | ret = claim_interface(usb, usbatm, UEA_DS_IFACE_NO); | ||
| 1645 | if (ret < 0) | ||
| 1646 | return ret; | ||
| 1647 | } | ||
| 1648 | |||
| 1649 | sc = kzalloc(sizeof(struct uea_softc), GFP_KERNEL); | ||
| 1650 | if (!sc) { | ||
| 1651 | uea_err(INS_TO_USBDEV(sc), "uea_init: not enough memory !\n"); | ||
| 1652 | return -ENOMEM; | ||
| 1653 | } | ||
| 1654 | |||
| 1655 | sc->usb_dev = usb; | ||
| 1656 | usbatm->driver_data = sc; | ||
| 1657 | sc->usbatm = usbatm; | ||
| 1658 | sc->modem_index = (modem_index < NB_MODEM) ? modem_index++ : 0; | ||
| 1659 | sc->driver_info = id->driver_info; | ||
| 1660 | |||
| 1661 | ret = uea_boot(sc); | ||
| 1662 | if (ret < 0) { | ||
| 1663 | kfree(sc); | ||
| 1664 | return ret; | ||
| 1665 | } | ||
| 1666 | |||
| 1667 | create_fs_entries(sc, intf); | ||
| 1668 | return 0; | ||
| 1669 | } | ||
| 1670 | |||
| 1671 | static void destroy_fs_entries(struct uea_softc *sc, struct usb_interface *intf) | ||
| 1672 | { | ||
| 1673 | /* sysfs interface */ | ||
| 1674 | device_remove_file(&intf->dev, &dev_attr_stat_status); | ||
| 1675 | device_remove_file(&intf->dev, &dev_attr_stat_mflags); | ||
| 1676 | device_remove_file(&intf->dev, &dev_attr_stat_human_status); | ||
| 1677 | device_remove_file(&intf->dev, &dev_attr_stat_delin); | ||
| 1678 | device_remove_file(&intf->dev, &dev_attr_stat_vidcpe); | ||
| 1679 | device_remove_file(&intf->dev, &dev_attr_stat_usrate); | ||
| 1680 | device_remove_file(&intf->dev, &dev_attr_stat_dsrate); | ||
| 1681 | device_remove_file(&intf->dev, &dev_attr_stat_usattenuation); | ||
| 1682 | device_remove_file(&intf->dev, &dev_attr_stat_dsattenuation); | ||
| 1683 | device_remove_file(&intf->dev, &dev_attr_stat_usmargin); | ||
| 1684 | device_remove_file(&intf->dev, &dev_attr_stat_dsmargin); | ||
| 1685 | device_remove_file(&intf->dev, &dev_attr_stat_txflow); | ||
| 1686 | device_remove_file(&intf->dev, &dev_attr_stat_rxflow); | ||
| 1687 | device_remove_file(&intf->dev, &dev_attr_stat_uscorr); | ||
| 1688 | device_remove_file(&intf->dev, &dev_attr_stat_dscorr); | ||
| 1689 | device_remove_file(&intf->dev, &dev_attr_stat_usunc); | ||
| 1690 | device_remove_file(&intf->dev, &dev_attr_stat_dsunc); | ||
| 1691 | } | ||
| 1692 | |||
| 1693 | static void uea_unbind(struct usbatm_data *usbatm, struct usb_interface *intf) | ||
| 1694 | { | ||
| 1695 | struct uea_softc *sc = usbatm->driver_data; | ||
| 1696 | |||
| 1697 | destroy_fs_entries(sc, intf); | ||
| 1698 | uea_stop(sc); | ||
| 1699 | kfree(sc); | ||
| 1700 | } | ||
| 1701 | |||
| 1702 | static struct usbatm_driver uea_usbatm_driver = { | ||
| 1703 | .driver_name = "ueagle-atm", | ||
| 1704 | .owner = THIS_MODULE, | ||
| 1705 | .bind = uea_bind, | ||
| 1706 | .atm_start = uea_atm_open, | ||
| 1707 | .unbind = uea_unbind, | ||
| 1708 | .heavy_init = uea_heavy, | ||
| 1709 | .in = UEA_BULK_DATA_PIPE, | ||
| 1710 | .out = UEA_BULK_DATA_PIPE, | ||
| 1711 | }; | ||
| 1712 | |||
| 1713 | static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id) | ||
| 1714 | { | ||
| 1715 | struct usb_device *usb = interface_to_usbdev(intf); | ||
| 1716 | |||
| 1717 | uea_enters(usb); | ||
| 1718 | uea_info(usb, "ADSL device founded vid (%#X) pid (%#X) : %s\n", | ||
| 1719 | le16_to_cpu(usb->descriptor.idVendor), | ||
| 1720 | le16_to_cpu(usb->descriptor.idProduct), | ||
| 1721 | chip_name[UEA_CHIP_VERSION(id)]); | ||
| 1722 | |||
| 1723 | usb_reset_device(usb); | ||
| 1724 | |||
| 1725 | if (UEA_IS_PREFIRM(id)) | ||
| 1726 | return uea_load_firmware(usb, UEA_CHIP_VERSION(id)); | ||
| 1727 | |||
| 1728 | return usbatm_usb_probe(intf, id, &uea_usbatm_driver); | ||
| 1729 | } | ||
| 1730 | |||
| 1731 | static void uea_disconnect(struct usb_interface *intf) | ||
| 1732 | { | ||
| 1733 | struct usb_device *usb = interface_to_usbdev(intf); | ||
| 1734 | int ifnum = intf->altsetting->desc.bInterfaceNumber; | ||
| 1735 | uea_enters(usb); | ||
| 1736 | |||
| 1737 | /* ADI930 has 2 interfaces and eagle 3 interfaces. | ||
| 1738 | * Pre-firmware device has one interface | ||
| 1739 | */ | ||
| 1740 | if (usb->config->desc.bNumInterfaces != 1 && ifnum == 0) { | ||
| 1741 | down(&uea_semaphore); | ||
| 1742 | usbatm_usb_disconnect(intf); | ||
| 1743 | up(&uea_semaphore); | ||
| 1744 | uea_info(usb, "ADSL device removed\n"); | ||
| 1745 | } | ||
| 1746 | |||
| 1747 | uea_leaves(usb); | ||
| 1748 | } | ||
| 1749 | |||
| 1750 | /* | ||
| 1751 | * List of supported VID/PID | ||
| 1752 | */ | ||
| 1753 | static const struct usb_device_id uea_ids[] = { | ||
| 1754 | {USB_DEVICE(ELSA_VID, ELSA_PID_PREFIRM), .driver_info = ADI930 | PREFIRM}, | ||
| 1755 | {USB_DEVICE(ELSA_VID, ELSA_PID_PSTFIRM), .driver_info = ADI930 | PSTFIRM}, | ||
| 1756 | {USB_DEVICE(EAGLE_VID, EAGLE_I_PID_PREFIRM), .driver_info = EAGLE_I | PREFIRM}, | ||
| 1757 | {USB_DEVICE(EAGLE_VID, EAGLE_I_PID_PSTFIRM), .driver_info = EAGLE_I | PSTFIRM}, | ||
| 1758 | {USB_DEVICE(EAGLE_VID, EAGLE_II_PID_PREFIRM), .driver_info = EAGLE_II | PREFIRM}, | ||
| 1759 | {USB_DEVICE(EAGLE_VID, EAGLE_II_PID_PSTFIRM), .driver_info = EAGLE_II | PSTFIRM}, | ||
| 1760 | {USB_DEVICE(EAGLE_VID, EAGLE_IIC_PID_PREFIRM), .driver_info = EAGLE_II | PREFIRM}, | ||
| 1761 | {USB_DEVICE(EAGLE_VID, EAGLE_IIC_PID_PSTFIRM), .driver_info = EAGLE_II | PSTFIRM}, | ||
| 1762 | {USB_DEVICE(EAGLE_VID, EAGLE_III_PID_PREFIRM), .driver_info = EAGLE_III | PREFIRM}, | ||
| 1763 | {USB_DEVICE(EAGLE_VID, EAGLE_III_PID_PSTFIRM), .driver_info = EAGLE_III | PSTFIRM}, | ||
| 1764 | {USB_DEVICE(USR_VID, MILLER_A_PID_PREFIRM), .driver_info = EAGLE_I | PREFIRM}, | ||
| 1765 | {USB_DEVICE(USR_VID, MILLER_A_PID_PSTFIRM), .driver_info = EAGLE_I | PSTFIRM}, | ||
| 1766 | {USB_DEVICE(USR_VID, MILLER_B_PID_PREFIRM), .driver_info = EAGLE_I | PREFIRM}, | ||
| 1767 | {USB_DEVICE(USR_VID, MILLER_B_PID_PSTFIRM), .driver_info = EAGLE_I | PSTFIRM}, | ||
| 1768 | {USB_DEVICE(USR_VID, HEINEKEN_A_PID_PREFIRM),.driver_info = EAGLE_I | PREFIRM}, | ||
| 1769 | {USB_DEVICE(USR_VID, HEINEKEN_A_PID_PSTFIRM),.driver_info = EAGLE_I | PSTFIRM}, | ||
| 1770 | {USB_DEVICE(USR_VID, HEINEKEN_B_PID_PREFIRM),.driver_info = EAGLE_I | PREFIRM}, | ||
| 1771 | {USB_DEVICE(USR_VID, HEINEKEN_B_PID_PSTFIRM),.driver_info = EAGLE_I | PSTFIRM}, | ||
| 1772 | {} | ||
| 1773 | }; | ||
| 1774 | |||
| 1775 | /* | ||
| 1776 | * USB driver descriptor | ||
| 1777 | */ | ||
| 1778 | static struct usb_driver uea_driver = { | ||
| 1779 | .name = "ueagle-atm", | ||
| 1780 | .id_table = uea_ids, | ||
| 1781 | .probe = uea_probe, | ||
| 1782 | .disconnect = uea_disconnect, | ||
| 1783 | }; | ||
| 1784 | |||
| 1785 | MODULE_DEVICE_TABLE(usb, uea_ids); | ||
| 1786 | |||
| 1787 | /** | ||
| 1788 | * uea_init - Initialize the module. | ||
| 1789 | * Register to USB subsystem | ||
| 1790 | */ | ||
| 1791 | static int __init uea_init(void) | ||
| 1792 | { | ||
| 1793 | printk(KERN_INFO "[ueagle-atm] driver " EAGLEUSBVERSION " loaded\n"); | ||
| 1794 | |||
| 1795 | usb_register(&uea_driver); | ||
| 1796 | |||
| 1797 | return 0; | ||
| 1798 | } | ||
| 1799 | |||
| 1800 | module_init(uea_init); | ||
| 1801 | |||
| 1802 | /** | ||
| 1803 | * uea_exit - Destroy module | ||
| 1804 | * Deregister with USB subsystem | ||
| 1805 | */ | ||
| 1806 | static void __exit uea_exit(void) | ||
| 1807 | { | ||
| 1808 | /* | ||
| 1809 | * This calls automatically the uea_disconnect method if necessary: | ||
| 1810 | */ | ||
| 1811 | usb_deregister(&uea_driver); | ||
| 1812 | |||
| 1813 | printk(KERN_INFO "[ueagle-atm] driver unloaded\n"); | ||
| 1814 | } | ||
| 1815 | |||
| 1816 | module_exit(uea_exit); | ||
| 1817 | |||
| 1818 | MODULE_AUTHOR("Damien Bergamini/Matthieu Castet/Stanislaw W. Gruszka"); | ||
| 1819 | MODULE_DESCRIPTION("ADI 930/Eagle USB ADSL Modem driver"); | ||
| 1820 | MODULE_LICENSE("Dual BSD/GPL"); | ||
diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c index 2e6593e6c1bd..9baa6296fc95 100644 --- a/drivers/usb/atm/usbatm.c +++ b/drivers/usb/atm/usbatm.c | |||
| @@ -646,14 +646,14 @@ static void usbatm_destroy_instance(struct kref *kref) | |||
| 646 | kfree(instance); | 646 | kfree(instance); |
| 647 | } | 647 | } |
| 648 | 648 | ||
| 649 | void usbatm_get_instance(struct usbatm_data *instance) | 649 | static void usbatm_get_instance(struct usbatm_data *instance) |
| 650 | { | 650 | { |
| 651 | dbg("%s", __func__); | 651 | dbg("%s", __func__); |
| 652 | 652 | ||
| 653 | kref_get(&instance->refcount); | 653 | kref_get(&instance->refcount); |
| 654 | } | 654 | } |
| 655 | 655 | ||
| 656 | void usbatm_put_instance(struct usbatm_data *instance) | 656 | static void usbatm_put_instance(struct usbatm_data *instance) |
| 657 | { | 657 | { |
| 658 | dbg("%s", __func__); | 658 | dbg("%s", __func__); |
| 659 | 659 | ||
diff --git a/drivers/usb/atm/xusbatm.c b/drivers/usb/atm/xusbatm.c index 7fe7fb484d10..5c76e3aaaa5e 100644 --- a/drivers/usb/atm/xusbatm.c +++ b/drivers/usb/atm/xusbatm.c | |||
| @@ -140,7 +140,6 @@ static int xusbatm_usb_probe(struct usb_interface *intf, | |||
| 140 | } | 140 | } |
| 141 | 141 | ||
| 142 | static struct usb_driver xusbatm_usb_driver = { | 142 | static struct usb_driver xusbatm_usb_driver = { |
| 143 | .owner = THIS_MODULE, | ||
| 144 | .name = xusbatm_driver_name, | 143 | .name = xusbatm_driver_name, |
| 145 | .probe = xusbatm_usb_probe, | 144 | .probe = xusbatm_usb_probe, |
| 146 | .disconnect = usbatm_usb_disconnect, | 145 | .disconnect = usbatm_usb_disconnect, |
diff --git a/drivers/usb/class/audio.c b/drivers/usb/class/audio.c index 50858273f8d3..3ad9ee8b84a9 100644 --- a/drivers/usb/class/audio.c +++ b/drivers/usb/class/audio.c | |||
| @@ -2732,7 +2732,6 @@ static struct usb_device_id usb_audio_ids [] = { | |||
| 2732 | MODULE_DEVICE_TABLE (usb, usb_audio_ids); | 2732 | MODULE_DEVICE_TABLE (usb, usb_audio_ids); |
| 2733 | 2733 | ||
| 2734 | static struct usb_driver usb_audio_driver = { | 2734 | static struct usb_driver usb_audio_driver = { |
| 2735 | .owner = THIS_MODULE, | ||
| 2736 | .name = "audio", | 2735 | .name = "audio", |
| 2737 | .probe = usb_audio_probe, | 2736 | .probe = usb_audio_probe, |
| 2738 | .disconnect = usb_audio_disconnect, | 2737 | .disconnect = usb_audio_disconnect, |
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 1b4751412970..248279e44c99 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | * Copyright (c) 1999 Johannes Erdfelt <johannes@erdfelt.com> | 6 | * Copyright (c) 1999 Johannes Erdfelt <johannes@erdfelt.com> |
| 7 | * Copyright (c) 2000 Vojtech Pavlik <vojtech@suse.cz> | 7 | * Copyright (c) 2000 Vojtech Pavlik <vojtech@suse.cz> |
| 8 | * Copyright (c) 2004 Oliver Neukum <oliver@neukum.name> | 8 | * Copyright (c) 2004 Oliver Neukum <oliver@neukum.name> |
| 9 | * Copyright (c) 2005 David Kubicek <dave@awk.cz> | ||
| 9 | * | 10 | * |
| 10 | * USB Abstract Control Model driver for USB modems and ISDN adapters | 11 | * USB Abstract Control Model driver for USB modems and ISDN adapters |
| 11 | * | 12 | * |
| @@ -29,6 +30,7 @@ | |||
| 29 | * config we want, sysadmin changes bConfigurationValue in sysfs. | 30 | * config we want, sysadmin changes bConfigurationValue in sysfs. |
| 30 | * v0.23 - use softirq for rx processing, as needed by tty layer | 31 | * v0.23 - use softirq for rx processing, as needed by tty layer |
| 31 | * v0.24 - change probe method to evaluate CDC union descriptor | 32 | * v0.24 - change probe method to evaluate CDC union descriptor |
| 33 | * v0.25 - downstream tasks paralelized to maximize throughput | ||
| 32 | */ | 34 | */ |
| 33 | 35 | ||
| 34 | /* | 36 | /* |
| @@ -63,14 +65,15 @@ | |||
| 63 | #include <linux/usb_cdc.h> | 65 | #include <linux/usb_cdc.h> |
| 64 | #include <asm/byteorder.h> | 66 | #include <asm/byteorder.h> |
| 65 | #include <asm/unaligned.h> | 67 | #include <asm/unaligned.h> |
| 68 | #include <linux/list.h> | ||
| 66 | 69 | ||
| 67 | #include "cdc-acm.h" | 70 | #include "cdc-acm.h" |
| 68 | 71 | ||
| 69 | /* | 72 | /* |
| 70 | * Version Information | 73 | * Version Information |
| 71 | */ | 74 | */ |
| 72 | #define DRIVER_VERSION "v0.23" | 75 | #define DRIVER_VERSION "v0.25" |
| 73 | #define DRIVER_AUTHOR "Armin Fuerst, Pavel Machek, Johannes Erdfelt, Vojtech Pavlik" | 76 | #define DRIVER_AUTHOR "Armin Fuerst, Pavel Machek, Johannes Erdfelt, Vojtech Pavlik, David Kubicek" |
| 74 | #define DRIVER_DESC "USB Abstract Control Model driver for USB modems and ISDN adapters" | 77 | #define DRIVER_DESC "USB Abstract Control Model driver for USB modems and ISDN adapters" |
| 75 | 78 | ||
| 76 | static struct usb_driver acm_driver; | 79 | static struct usb_driver acm_driver; |
| @@ -284,7 +287,9 @@ exit: | |||
| 284 | /* data interface returns incoming bytes, or we got unthrottled */ | 287 | /* data interface returns incoming bytes, or we got unthrottled */ |
| 285 | static void acm_read_bulk(struct urb *urb, struct pt_regs *regs) | 288 | static void acm_read_bulk(struct urb *urb, struct pt_regs *regs) |
| 286 | { | 289 | { |
| 287 | struct acm *acm = urb->context; | 290 | struct acm_rb *buf; |
| 291 | struct acm_ru *rcv = urb->context; | ||
| 292 | struct acm *acm = rcv->instance; | ||
| 288 | dbg("Entering acm_read_bulk with status %d\n", urb->status); | 293 | dbg("Entering acm_read_bulk with status %d\n", urb->status); |
| 289 | 294 | ||
| 290 | if (!ACM_READY(acm)) | 295 | if (!ACM_READY(acm)) |
| @@ -293,49 +298,109 @@ static void acm_read_bulk(struct urb *urb, struct pt_regs *regs) | |||
| 293 | if (urb->status) | 298 | if (urb->status) |
| 294 | dev_dbg(&acm->data->dev, "bulk rx status %d\n", urb->status); | 299 | dev_dbg(&acm->data->dev, "bulk rx status %d\n", urb->status); |
| 295 | 300 | ||
| 296 | /* calling tty_flip_buffer_push() in_irq() isn't allowed */ | 301 | buf = rcv->buffer; |
| 297 | tasklet_schedule(&acm->bh); | 302 | buf->size = urb->actual_length; |
| 303 | |||
| 304 | spin_lock(&acm->read_lock); | ||
| 305 | list_add_tail(&rcv->list, &acm->spare_read_urbs); | ||
| 306 | list_add_tail(&buf->list, &acm->filled_read_bufs); | ||
| 307 | spin_unlock(&acm->read_lock); | ||
| 308 | |||
| 309 | tasklet_schedule(&acm->urb_task); | ||
| 298 | } | 310 | } |
| 299 | 311 | ||
| 300 | static void acm_rx_tasklet(unsigned long _acm) | 312 | static void acm_rx_tasklet(unsigned long _acm) |
| 301 | { | 313 | { |
| 302 | struct acm *acm = (void *)_acm; | 314 | struct acm *acm = (void *)_acm; |
| 303 | struct urb *urb = acm->readurb; | 315 | struct acm_rb *buf; |
| 304 | struct tty_struct *tty = acm->tty; | 316 | struct tty_struct *tty = acm->tty; |
| 305 | unsigned char *data = urb->transfer_buffer; | 317 | struct acm_ru *rcv; |
| 318 | //unsigned long flags; | ||
| 306 | int i = 0; | 319 | int i = 0; |
| 307 | dbg("Entering acm_rx_tasklet"); | 320 | dbg("Entering acm_rx_tasklet"); |
| 308 | 321 | ||
| 309 | if (urb->actual_length > 0 && !acm->throttle) { | 322 | if (!ACM_READY(acm) || acm->throttle) |
| 310 | for (i = 0; i < urb->actual_length && !acm->throttle; i++) { | 323 | return; |
| 311 | /* if we insert more than TTY_FLIPBUF_SIZE characters, | 324 | |
| 312 | * we drop them. */ | 325 | next_buffer: |
| 313 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { | 326 | spin_lock(&acm->read_lock); |
| 314 | tty_flip_buffer_push(tty); | 327 | if (list_empty(&acm->filled_read_bufs)) { |
| 315 | } | 328 | spin_unlock(&acm->read_lock); |
| 316 | tty_insert_flip_char(tty, data[i], 0); | 329 | goto urbs; |
| 317 | } | ||
| 318 | dbg("Handed %d bytes to tty layer", i+1); | ||
| 319 | tty_flip_buffer_push(tty); | ||
| 320 | } | 330 | } |
| 331 | buf = list_entry(acm->filled_read_bufs.next, | ||
| 332 | struct acm_rb, list); | ||
| 333 | list_del(&buf->list); | ||
| 334 | spin_unlock(&acm->read_lock); | ||
| 335 | |||
| 336 | dbg("acm_rx_tasklet: procesing buf 0x%p, size = %d\n", buf, buf->size); | ||
| 337 | |||
| 338 | for (i = 0; i < buf->size && !acm->throttle; i++) { | ||
| 339 | /* if we insert more than TTY_FLIPBUF_SIZE characters, | ||
| 340 | we drop them. */ | ||
| 341 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
| 342 | tty_flip_buffer_push(tty); | ||
| 343 | } | ||
| 344 | tty_insert_flip_char(tty, buf->base[i], 0); | ||
| 345 | } | ||
| 346 | tty_flip_buffer_push(tty); | ||
| 321 | 347 | ||
| 322 | spin_lock(&acm->throttle_lock); | 348 | spin_lock(&acm->throttle_lock); |
| 323 | if (acm->throttle) { | 349 | if (acm->throttle) { |
| 324 | dbg("Throtteling noticed"); | 350 | dbg("Throtteling noticed"); |
| 325 | memmove(data, data + i, urb->actual_length - i); | 351 | memmove(buf->base, buf->base + i, buf->size - i); |
| 326 | urb->actual_length -= i; | 352 | buf->size -= i; |
| 327 | acm->resubmit_to_unthrottle = 1; | ||
| 328 | spin_unlock(&acm->throttle_lock); | 353 | spin_unlock(&acm->throttle_lock); |
| 354 | spin_lock(&acm->read_lock); | ||
| 355 | list_add(&buf->list, &acm->filled_read_bufs); | ||
| 356 | spin_unlock(&acm->read_lock); | ||
| 329 | return; | 357 | return; |
| 330 | } | 358 | } |
| 331 | spin_unlock(&acm->throttle_lock); | 359 | spin_unlock(&acm->throttle_lock); |
| 332 | 360 | ||
| 333 | urb->actual_length = 0; | 361 | spin_lock(&acm->read_lock); |
| 334 | urb->dev = acm->dev; | 362 | list_add(&buf->list, &acm->spare_read_bufs); |
| 335 | 363 | spin_unlock(&acm->read_lock); | |
| 336 | i = usb_submit_urb(urb, GFP_ATOMIC); | 364 | goto next_buffer; |
| 337 | if (i) | 365 | |
| 338 | dev_dbg(&acm->data->dev, "bulk rx resubmit %d\n", i); | 366 | urbs: |
| 367 | while (!list_empty(&acm->spare_read_bufs)) { | ||
| 368 | spin_lock(&acm->read_lock); | ||
| 369 | if (list_empty(&acm->spare_read_urbs)) { | ||
| 370 | spin_unlock(&acm->read_lock); | ||
| 371 | return; | ||
| 372 | } | ||
| 373 | rcv = list_entry(acm->spare_read_urbs.next, | ||
| 374 | struct acm_ru, list); | ||
| 375 | list_del(&rcv->list); | ||
| 376 | spin_unlock(&acm->read_lock); | ||
| 377 | |||
| 378 | buf = list_entry(acm->spare_read_bufs.next, | ||
| 379 | struct acm_rb, list); | ||
| 380 | list_del(&buf->list); | ||
| 381 | |||
| 382 | rcv->buffer = buf; | ||
| 383 | |||
| 384 | usb_fill_bulk_urb(rcv->urb, acm->dev, | ||
| 385 | acm->rx_endpoint, | ||
| 386 | buf->base, | ||
| 387 | acm->readsize, | ||
| 388 | acm_read_bulk, rcv); | ||
| 389 | rcv->urb->transfer_dma = buf->dma; | ||
| 390 | rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
| 391 | |||
| 392 | dbg("acm_rx_tasklet: sending urb 0x%p, rcv 0x%p, buf 0x%p\n", rcv->urb, rcv, buf); | ||
| 393 | |||
| 394 | /* This shouldn't kill the driver as unsuccessful URBs are returned to the | ||
| 395 | free-urbs-pool and resubmited ASAP */ | ||
| 396 | if (usb_submit_urb(rcv->urb, GFP_ATOMIC) < 0) { | ||
| 397 | list_add(&buf->list, &acm->spare_read_bufs); | ||
| 398 | spin_lock(&acm->read_lock); | ||
| 399 | list_add(&rcv->list, &acm->spare_read_urbs); | ||
| 400 | spin_unlock(&acm->read_lock); | ||
| 401 | return; | ||
| 402 | } | ||
| 403 | } | ||
| 339 | } | 404 | } |
| 340 | 405 | ||
| 341 | /* data interface wrote those outgoing bytes */ | 406 | /* data interface wrote those outgoing bytes */ |
| @@ -369,6 +434,7 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) | |||
| 369 | { | 434 | { |
| 370 | struct acm *acm; | 435 | struct acm *acm; |
| 371 | int rv = -EINVAL; | 436 | int rv = -EINVAL; |
| 437 | int i; | ||
| 372 | dbg("Entering acm_tty_open.\n"); | 438 | dbg("Entering acm_tty_open.\n"); |
| 373 | 439 | ||
| 374 | down(&open_sem); | 440 | down(&open_sem); |
| @@ -382,7 +448,9 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) | |||
| 382 | tty->driver_data = acm; | 448 | tty->driver_data = acm; |
| 383 | acm->tty = tty; | 449 | acm->tty = tty; |
| 384 | 450 | ||
| 385 | 451 | /* force low_latency on so that our tty_push actually forces the data through, | |
| 452 | otherwise it is scheduled, and with high data rates data can get lost. */ | ||
| 453 | tty->low_latency = 1; | ||
| 386 | 454 | ||
| 387 | if (acm->used++) { | 455 | if (acm->used++) { |
| 388 | goto done; | 456 | goto done; |
| @@ -394,18 +462,20 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) | |||
| 394 | goto bail_out; | 462 | goto bail_out; |
| 395 | } | 463 | } |
| 396 | 464 | ||
| 397 | acm->readurb->dev = acm->dev; | ||
| 398 | if (usb_submit_urb(acm->readurb, GFP_KERNEL)) { | ||
| 399 | dbg("usb_submit_urb(read bulk) failed"); | ||
| 400 | goto bail_out_and_unlink; | ||
| 401 | } | ||
| 402 | |||
| 403 | if (0 > acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS)) | 465 | if (0 > acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS)) |
| 404 | goto full_bailout; | 466 | goto full_bailout; |
| 405 | 467 | ||
| 406 | /* force low_latency on so that our tty_push actually forces the data through, | 468 | INIT_LIST_HEAD(&acm->spare_read_urbs); |
| 407 | otherwise it is scheduled, and with high data rates data can get lost. */ | 469 | INIT_LIST_HEAD(&acm->spare_read_bufs); |
| 408 | tty->low_latency = 1; | 470 | INIT_LIST_HEAD(&acm->filled_read_bufs); |
| 471 | for (i = 0; i < ACM_NRU; i++) { | ||
| 472 | list_add(&(acm->ru[i].list), &acm->spare_read_urbs); | ||
| 473 | } | ||
| 474 | for (i = 0; i < ACM_NRB; i++) { | ||
| 475 | list_add(&(acm->rb[i].list), &acm->spare_read_bufs); | ||
| 476 | } | ||
| 477 | |||
| 478 | tasklet_schedule(&acm->urb_task); | ||
| 409 | 479 | ||
| 410 | done: | 480 | done: |
| 411 | err_out: | 481 | err_out: |
| @@ -413,8 +483,6 @@ err_out: | |||
| 413 | return rv; | 483 | return rv; |
| 414 | 484 | ||
| 415 | full_bailout: | 485 | full_bailout: |
| 416 | usb_kill_urb(acm->readurb); | ||
| 417 | bail_out_and_unlink: | ||
| 418 | usb_kill_urb(acm->ctrlurb); | 486 | usb_kill_urb(acm->ctrlurb); |
| 419 | bail_out: | 487 | bail_out: |
| 420 | acm->used--; | 488 | acm->used--; |
| @@ -424,18 +492,22 @@ bail_out: | |||
| 424 | 492 | ||
| 425 | static void acm_tty_unregister(struct acm *acm) | 493 | static void acm_tty_unregister(struct acm *acm) |
| 426 | { | 494 | { |
| 495 | int i; | ||
| 496 | |||
| 427 | tty_unregister_device(acm_tty_driver, acm->minor); | 497 | tty_unregister_device(acm_tty_driver, acm->minor); |
| 428 | usb_put_intf(acm->control); | 498 | usb_put_intf(acm->control); |
| 429 | acm_table[acm->minor] = NULL; | 499 | acm_table[acm->minor] = NULL; |
| 430 | usb_free_urb(acm->ctrlurb); | 500 | usb_free_urb(acm->ctrlurb); |
| 431 | usb_free_urb(acm->readurb); | ||
| 432 | usb_free_urb(acm->writeurb); | 501 | usb_free_urb(acm->writeurb); |
| 502 | for (i = 0; i < ACM_NRU; i++) | ||
| 503 | usb_free_urb(acm->ru[i].urb); | ||
| 433 | kfree(acm); | 504 | kfree(acm); |
| 434 | } | 505 | } |
| 435 | 506 | ||
| 436 | static void acm_tty_close(struct tty_struct *tty, struct file *filp) | 507 | static void acm_tty_close(struct tty_struct *tty, struct file *filp) |
| 437 | { | 508 | { |
| 438 | struct acm *acm = tty->driver_data; | 509 | struct acm *acm = tty->driver_data; |
| 510 | int i; | ||
| 439 | 511 | ||
| 440 | if (!acm || !acm->used) | 512 | if (!acm || !acm->used) |
| 441 | return; | 513 | return; |
| @@ -446,7 +518,8 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp) | |||
| 446 | acm_set_control(acm, acm->ctrlout = 0); | 518 | acm_set_control(acm, acm->ctrlout = 0); |
| 447 | usb_kill_urb(acm->ctrlurb); | 519 | usb_kill_urb(acm->ctrlurb); |
| 448 | usb_kill_urb(acm->writeurb); | 520 | usb_kill_urb(acm->writeurb); |
| 449 | usb_kill_urb(acm->readurb); | 521 | for (i = 0; i < ACM_NRU; i++) |
| 522 | usb_kill_urb(acm->ru[i].urb); | ||
| 450 | } else | 523 | } else |
| 451 | acm_tty_unregister(acm); | 524 | acm_tty_unregister(acm); |
| 452 | } | 525 | } |
| @@ -528,10 +601,7 @@ static void acm_tty_unthrottle(struct tty_struct *tty) | |||
| 528 | spin_lock_bh(&acm->throttle_lock); | 601 | spin_lock_bh(&acm->throttle_lock); |
| 529 | acm->throttle = 0; | 602 | acm->throttle = 0; |
| 530 | spin_unlock_bh(&acm->throttle_lock); | 603 | spin_unlock_bh(&acm->throttle_lock); |
| 531 | if (acm->resubmit_to_unthrottle) { | 604 | tasklet_schedule(&acm->urb_task); |
| 532 | acm->resubmit_to_unthrottle = 0; | ||
| 533 | acm_read_bulk(acm->readurb, NULL); | ||
| 534 | } | ||
| 535 | } | 605 | } |
| 536 | 606 | ||
| 537 | static void acm_tty_break_ctl(struct tty_struct *tty, int state) | 607 | static void acm_tty_break_ctl(struct tty_struct *tty, int state) |
| @@ -588,7 +658,7 @@ static int acm_tty_ioctl(struct tty_struct *tty, struct file *file, unsigned int | |||
| 588 | return -ENOIOCTLCMD; | 658 | return -ENOIOCTLCMD; |
| 589 | } | 659 | } |
| 590 | 660 | ||
| 591 | static __u32 acm_tty_speed[] = { | 661 | static const __u32 acm_tty_speed[] = { |
| 592 | 0, 50, 75, 110, 134, 150, 200, 300, 600, | 662 | 0, 50, 75, 110, 134, 150, 200, 300, 600, |
| 593 | 1200, 1800, 2400, 4800, 9600, 19200, 38400, | 663 | 1200, 1800, 2400, 4800, 9600, 19200, 38400, |
| 594 | 57600, 115200, 230400, 460800, 500000, 576000, | 664 | 57600, 115200, 230400, 460800, 500000, 576000, |
| @@ -596,7 +666,7 @@ static __u32 acm_tty_speed[] = { | |||
| 596 | 2500000, 3000000, 3500000, 4000000 | 666 | 2500000, 3000000, 3500000, 4000000 |
| 597 | }; | 667 | }; |
| 598 | 668 | ||
| 599 | static __u8 acm_tty_size[] = { | 669 | static const __u8 acm_tty_size[] = { |
| 600 | 5, 6, 7, 8 | 670 | 5, 6, 7, 8 |
| 601 | }; | 671 | }; |
| 602 | 672 | ||
| @@ -694,6 +764,7 @@ static int acm_probe (struct usb_interface *intf, | |||
| 694 | int call_interface_num = -1; | 764 | int call_interface_num = -1; |
| 695 | int data_interface_num; | 765 | int data_interface_num; |
| 696 | unsigned long quirks; | 766 | unsigned long quirks; |
| 767 | int i; | ||
| 697 | 768 | ||
| 698 | /* handle quirks deadly to normal probing*/ | 769 | /* handle quirks deadly to normal probing*/ |
| 699 | quirks = (unsigned long)id->driver_info; | 770 | quirks = (unsigned long)id->driver_info; |
| @@ -833,7 +904,7 @@ skip_normal_probe: | |||
| 833 | } | 904 | } |
| 834 | 905 | ||
| 835 | ctrlsize = le16_to_cpu(epctrl->wMaxPacketSize); | 906 | ctrlsize = le16_to_cpu(epctrl->wMaxPacketSize); |
| 836 | readsize = le16_to_cpu(epread->wMaxPacketSize); | 907 | readsize = le16_to_cpu(epread->wMaxPacketSize)*2; |
| 837 | acm->writesize = le16_to_cpu(epwrite->wMaxPacketSize); | 908 | acm->writesize = le16_to_cpu(epwrite->wMaxPacketSize); |
| 838 | acm->control = control_interface; | 909 | acm->control = control_interface; |
| 839 | acm->data = data_interface; | 910 | acm->data = data_interface; |
| @@ -842,12 +913,14 @@ skip_normal_probe: | |||
| 842 | acm->ctrl_caps = ac_management_function; | 913 | acm->ctrl_caps = ac_management_function; |
| 843 | acm->ctrlsize = ctrlsize; | 914 | acm->ctrlsize = ctrlsize; |
| 844 | acm->readsize = readsize; | 915 | acm->readsize = readsize; |
| 845 | acm->bh.func = acm_rx_tasklet; | 916 | acm->urb_task.func = acm_rx_tasklet; |
| 846 | acm->bh.data = (unsigned long) acm; | 917 | acm->urb_task.data = (unsigned long) acm; |
| 847 | INIT_WORK(&acm->work, acm_softint, acm); | 918 | INIT_WORK(&acm->work, acm_softint, acm); |
| 848 | spin_lock_init(&acm->throttle_lock); | 919 | spin_lock_init(&acm->throttle_lock); |
| 849 | spin_lock_init(&acm->write_lock); | 920 | spin_lock_init(&acm->write_lock); |
| 921 | spin_lock_init(&acm->read_lock); | ||
| 850 | acm->write_ready = 1; | 922 | acm->write_ready = 1; |
| 923 | acm->rx_endpoint = usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress); | ||
| 851 | 924 | ||
| 852 | buf = usb_buffer_alloc(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma); | 925 | buf = usb_buffer_alloc(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma); |
| 853 | if (!buf) { | 926 | if (!buf) { |
| @@ -856,13 +929,6 @@ skip_normal_probe: | |||
| 856 | } | 929 | } |
| 857 | acm->ctrl_buffer = buf; | 930 | acm->ctrl_buffer = buf; |
| 858 | 931 | ||
| 859 | buf = usb_buffer_alloc(usb_dev, readsize, GFP_KERNEL, &acm->read_dma); | ||
| 860 | if (!buf) { | ||
| 861 | dev_dbg(&intf->dev, "out of memory (read buffer alloc)\n"); | ||
| 862 | goto alloc_fail3; | ||
| 863 | } | ||
| 864 | acm->read_buffer = buf; | ||
| 865 | |||
| 866 | if (acm_write_buffers_alloc(acm) < 0) { | 932 | if (acm_write_buffers_alloc(acm) < 0) { |
| 867 | dev_dbg(&intf->dev, "out of memory (write buffer alloc)\n"); | 933 | dev_dbg(&intf->dev, "out of memory (write buffer alloc)\n"); |
| 868 | goto alloc_fail4; | 934 | goto alloc_fail4; |
| @@ -873,10 +939,25 @@ skip_normal_probe: | |||
| 873 | dev_dbg(&intf->dev, "out of memory (ctrlurb kmalloc)\n"); | 939 | dev_dbg(&intf->dev, "out of memory (ctrlurb kmalloc)\n"); |
| 874 | goto alloc_fail5; | 940 | goto alloc_fail5; |
| 875 | } | 941 | } |
| 876 | acm->readurb = usb_alloc_urb(0, GFP_KERNEL); | 942 | for (i = 0; i < ACM_NRU; i++) { |
| 877 | if (!acm->readurb) { | 943 | struct acm_ru *rcv = &(acm->ru[i]); |
| 878 | dev_dbg(&intf->dev, "out of memory (readurb kmalloc)\n"); | 944 | |
| 879 | goto alloc_fail6; | 945 | if (!(rcv->urb = usb_alloc_urb(0, GFP_KERNEL))) { |
| 946 | dev_dbg(&intf->dev, "out of memory (read urbs usb_alloc_urb)\n"); | ||
| 947 | goto alloc_fail7; | ||
| 948 | } | ||
| 949 | |||
| 950 | rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
| 951 | rcv->instance = acm; | ||
| 952 | } | ||
| 953 | for (i = 0; i < ACM_NRB; i++) { | ||
| 954 | struct acm_rb *buf = &(acm->rb[i]); | ||
| 955 | |||
| 956 | // Using usb_buffer_alloc instead of kmalloc as Oliver suggested | ||
| 957 | if (!(buf->base = usb_buffer_alloc(acm->dev, readsize, GFP_KERNEL, &buf->dma))) { | ||
| 958 | dev_dbg(&intf->dev, "out of memory (read bufs usb_buffer_alloc)\n"); | ||
| 959 | goto alloc_fail7; | ||
| 960 | } | ||
| 880 | } | 961 | } |
| 881 | acm->writeurb = usb_alloc_urb(0, GFP_KERNEL); | 962 | acm->writeurb = usb_alloc_urb(0, GFP_KERNEL); |
| 882 | if (!acm->writeurb) { | 963 | if (!acm->writeurb) { |
| @@ -889,15 +970,9 @@ skip_normal_probe: | |||
| 889 | acm->ctrlurb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 970 | acm->ctrlurb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
| 890 | acm->ctrlurb->transfer_dma = acm->ctrl_dma; | 971 | acm->ctrlurb->transfer_dma = acm->ctrl_dma; |
| 891 | 972 | ||
| 892 | usb_fill_bulk_urb(acm->readurb, usb_dev, usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress), | ||
| 893 | acm->read_buffer, readsize, acm_read_bulk, acm); | ||
| 894 | acm->readurb->transfer_flags |= URB_NO_FSBR | URB_NO_TRANSFER_DMA_MAP; | ||
| 895 | acm->readurb->transfer_dma = acm->read_dma; | ||
| 896 | |||
| 897 | usb_fill_bulk_urb(acm->writeurb, usb_dev, usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress), | 973 | usb_fill_bulk_urb(acm->writeurb, usb_dev, usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress), |
| 898 | NULL, acm->writesize, acm_write_bulk, acm); | 974 | NULL, acm->writesize, acm_write_bulk, acm); |
| 899 | acm->writeurb->transfer_flags |= URB_NO_FSBR | URB_NO_TRANSFER_DMA_MAP; | 975 | acm->writeurb->transfer_flags |= URB_NO_FSBR | URB_NO_TRANSFER_DMA_MAP; |
| 900 | /* acm->writeurb->transfer_dma = 0; */ | ||
| 901 | 976 | ||
| 902 | dev_info(&intf->dev, "ttyACM%d: USB ACM device\n", minor); | 977 | dev_info(&intf->dev, "ttyACM%d: USB ACM device\n", minor); |
| 903 | 978 | ||
| @@ -917,14 +992,14 @@ skip_normal_probe: | |||
| 917 | return 0; | 992 | return 0; |
| 918 | 993 | ||
| 919 | alloc_fail7: | 994 | alloc_fail7: |
| 920 | usb_free_urb(acm->readurb); | 995 | for (i = 0; i < ACM_NRB; i++) |
| 921 | alloc_fail6: | 996 | usb_buffer_free(usb_dev, acm->readsize, acm->rb[i].base, acm->rb[i].dma); |
| 997 | for (i = 0; i < ACM_NRU; i++) | ||
| 998 | usb_free_urb(acm->ru[i].urb); | ||
| 922 | usb_free_urb(acm->ctrlurb); | 999 | usb_free_urb(acm->ctrlurb); |
| 923 | alloc_fail5: | 1000 | alloc_fail5: |
| 924 | acm_write_buffers_free(acm); | 1001 | acm_write_buffers_free(acm); |
| 925 | alloc_fail4: | 1002 | alloc_fail4: |
| 926 | usb_buffer_free(usb_dev, readsize, acm->read_buffer, acm->read_dma); | ||
| 927 | alloc_fail3: | ||
| 928 | usb_buffer_free(usb_dev, ctrlsize, acm->ctrl_buffer, acm->ctrl_dma); | 1003 | usb_buffer_free(usb_dev, ctrlsize, acm->ctrl_buffer, acm->ctrl_dma); |
| 929 | alloc_fail2: | 1004 | alloc_fail2: |
| 930 | kfree(acm); | 1005 | kfree(acm); |
| @@ -936,6 +1011,7 @@ static void acm_disconnect(struct usb_interface *intf) | |||
| 936 | { | 1011 | { |
| 937 | struct acm *acm = usb_get_intfdata (intf); | 1012 | struct acm *acm = usb_get_intfdata (intf); |
| 938 | struct usb_device *usb_dev = interface_to_usbdev(intf); | 1013 | struct usb_device *usb_dev = interface_to_usbdev(intf); |
| 1014 | int i; | ||
| 939 | 1015 | ||
| 940 | if (!acm || !acm->dev) { | 1016 | if (!acm || !acm->dev) { |
| 941 | dbg("disconnect on nonexisting interface"); | 1017 | dbg("disconnect on nonexisting interface"); |
| @@ -946,15 +1022,24 @@ static void acm_disconnect(struct usb_interface *intf) | |||
| 946 | acm->dev = NULL; | 1022 | acm->dev = NULL; |
| 947 | usb_set_intfdata (intf, NULL); | 1023 | usb_set_intfdata (intf, NULL); |
| 948 | 1024 | ||
| 1025 | tasklet_disable(&acm->urb_task); | ||
| 1026 | |||
| 949 | usb_kill_urb(acm->ctrlurb); | 1027 | usb_kill_urb(acm->ctrlurb); |
| 950 | usb_kill_urb(acm->readurb); | ||
| 951 | usb_kill_urb(acm->writeurb); | 1028 | usb_kill_urb(acm->writeurb); |
| 1029 | for (i = 0; i < ACM_NRU; i++) | ||
| 1030 | usb_kill_urb(acm->ru[i].urb); | ||
| 1031 | |||
| 1032 | INIT_LIST_HEAD(&acm->filled_read_bufs); | ||
| 1033 | INIT_LIST_HEAD(&acm->spare_read_bufs); | ||
| 1034 | |||
| 1035 | tasklet_enable(&acm->urb_task); | ||
| 952 | 1036 | ||
| 953 | flush_scheduled_work(); /* wait for acm_softint */ | 1037 | flush_scheduled_work(); /* wait for acm_softint */ |
| 954 | 1038 | ||
| 955 | acm_write_buffers_free(acm); | 1039 | acm_write_buffers_free(acm); |
| 956 | usb_buffer_free(usb_dev, acm->readsize, acm->read_buffer, acm->read_dma); | ||
| 957 | usb_buffer_free(usb_dev, acm->ctrlsize, acm->ctrl_buffer, acm->ctrl_dma); | 1040 | usb_buffer_free(usb_dev, acm->ctrlsize, acm->ctrl_buffer, acm->ctrl_dma); |
| 1041 | for (i = 0; i < ACM_NRB; i++) | ||
| 1042 | usb_buffer_free(usb_dev, acm->readsize, acm->rb[i].base, acm->rb[i].dma); | ||
| 958 | 1043 | ||
| 959 | usb_driver_release_interface(&acm_driver, acm->data); | 1044 | usb_driver_release_interface(&acm_driver, acm->data); |
| 960 | 1045 | ||
| @@ -1003,7 +1088,6 @@ static struct usb_device_id acm_ids[] = { | |||
| 1003 | MODULE_DEVICE_TABLE (usb, acm_ids); | 1088 | MODULE_DEVICE_TABLE (usb, acm_ids); |
| 1004 | 1089 | ||
| 1005 | static struct usb_driver acm_driver = { | 1090 | static struct usb_driver acm_driver = { |
| 1006 | .owner = THIS_MODULE, | ||
| 1007 | .name = "cdc_acm", | 1091 | .name = "cdc_acm", |
| 1008 | .probe = acm_probe, | 1092 | .probe = acm_probe, |
| 1009 | .disconnect = acm_disconnect, | 1093 | .disconnect = acm_disconnect, |
diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h index 963a5dfd2096..fd2aaccdcbac 100644 --- a/drivers/usb/class/cdc-acm.h +++ b/drivers/usb/class/cdc-acm.h | |||
| @@ -59,6 +59,9 @@ | |||
| 59 | * when processing onlcr, so we only need 2 buffers. | 59 | * when processing onlcr, so we only need 2 buffers. |
| 60 | */ | 60 | */ |
| 61 | #define ACM_NWB 2 | 61 | #define ACM_NWB 2 |
| 62 | #define ACM_NRU 16 | ||
| 63 | #define ACM_NRB 16 | ||
| 64 | |||
| 62 | struct acm_wb { | 65 | struct acm_wb { |
| 63 | unsigned char *buf; | 66 | unsigned char *buf; |
| 64 | dma_addr_t dmah; | 67 | dma_addr_t dmah; |
| @@ -66,22 +69,43 @@ struct acm_wb { | |||
| 66 | int use; | 69 | int use; |
| 67 | }; | 70 | }; |
| 68 | 71 | ||
| 72 | struct acm_rb { | ||
| 73 | struct list_head list; | ||
| 74 | int size; | ||
| 75 | unsigned char *base; | ||
| 76 | dma_addr_t dma; | ||
| 77 | }; | ||
| 78 | |||
| 79 | struct acm_ru { | ||
| 80 | struct list_head list; | ||
| 81 | struct acm_rb *buffer; | ||
| 82 | struct urb *urb; | ||
| 83 | struct acm *instance; | ||
| 84 | }; | ||
| 85 | |||
| 69 | struct acm { | 86 | struct acm { |
| 70 | struct usb_device *dev; /* the corresponding usb device */ | 87 | struct usb_device *dev; /* the corresponding usb device */ |
| 71 | struct usb_interface *control; /* control interface */ | 88 | struct usb_interface *control; /* control interface */ |
| 72 | struct usb_interface *data; /* data interface */ | 89 | struct usb_interface *data; /* data interface */ |
| 73 | struct tty_struct *tty; /* the corresponding tty */ | 90 | struct tty_struct *tty; /* the corresponding tty */ |
| 74 | struct urb *ctrlurb, *readurb, *writeurb; /* urbs */ | 91 | struct urb *ctrlurb, *writeurb; /* urbs */ |
| 75 | u8 *ctrl_buffer, *read_buffer; /* buffers of urbs */ | 92 | u8 *ctrl_buffer; /* buffers of urbs */ |
| 76 | dma_addr_t ctrl_dma, read_dma; /* dma handles of buffers */ | 93 | dma_addr_t ctrl_dma; /* dma handles of buffers */ |
| 77 | struct acm_wb wb[ACM_NWB]; | 94 | struct acm_wb wb[ACM_NWB]; |
| 95 | struct acm_ru ru[ACM_NRU]; | ||
| 96 | struct acm_rb rb[ACM_NRB]; | ||
| 97 | int rx_endpoint; | ||
| 98 | spinlock_t read_lock; | ||
| 99 | struct list_head spare_read_urbs; | ||
| 100 | struct list_head spare_read_bufs; | ||
| 101 | struct list_head filled_read_bufs; | ||
| 78 | int write_current; /* current write buffer */ | 102 | int write_current; /* current write buffer */ |
| 79 | int write_used; /* number of non-empty write buffers */ | 103 | int write_used; /* number of non-empty write buffers */ |
| 80 | int write_ready; /* write urb is not running */ | 104 | int write_ready; /* write urb is not running */ |
| 81 | spinlock_t write_lock; | 105 | spinlock_t write_lock; |
| 82 | struct usb_cdc_line_coding line; /* bits, stop, parity */ | 106 | struct usb_cdc_line_coding line; /* bits, stop, parity */ |
| 83 | struct work_struct work; /* work queue entry for line discipline waking up */ | 107 | struct work_struct work; /* work queue entry for line discipline waking up */ |
| 84 | struct tasklet_struct bh; /* rx processing */ | 108 | struct tasklet_struct urb_task; /* rx processing */ |
| 85 | spinlock_t throttle_lock; /* synchronize throtteling and read callback */ | 109 | spinlock_t throttle_lock; /* synchronize throtteling and read callback */ |
| 86 | unsigned int ctrlin; /* input control lines (DCD, DSR, RI, break, overruns) */ | 110 | unsigned int ctrlin; /* input control lines (DCD, DSR, RI, break, overruns) */ |
| 87 | unsigned int ctrlout; /* output control lines (DTR, RTS) */ | 111 | unsigned int ctrlout; /* output control lines (DTR, RTS) */ |
| @@ -91,7 +115,6 @@ struct acm { | |||
| 91 | unsigned int minor; /* acm minor number */ | 115 | unsigned int minor; /* acm minor number */ |
| 92 | unsigned char throttle; /* throttled by tty layer */ | 116 | unsigned char throttle; /* throttled by tty layer */ |
| 93 | unsigned char clocal; /* termios CLOCAL */ | 117 | unsigned char clocal; /* termios CLOCAL */ |
| 94 | unsigned char resubmit_to_unthrottle; /* throtteling has disabled the read urb */ | ||
| 95 | unsigned int ctrl_caps; /* control capabilities from the class specific header */ | 118 | unsigned int ctrl_caps; /* control capabilities from the class specific header */ |
| 96 | }; | 119 | }; |
| 97 | 120 | ||
diff --git a/drivers/usb/class/usb-midi.c b/drivers/usb/class/usb-midi.c index 5f8af35e7633..f13f004d311f 100644 --- a/drivers/usb/class/usb-midi.c +++ b/drivers/usb/class/usb-midi.c | |||
| @@ -2027,7 +2027,6 @@ static struct usb_device_id id_table[] = { | |||
| 2027 | }; | 2027 | }; |
| 2028 | 2028 | ||
| 2029 | static struct usb_driver usb_midi_driver = { | 2029 | static struct usb_driver usb_midi_driver = { |
| 2030 | .owner = THIS_MODULE, | ||
| 2031 | .name = "midi", | 2030 | .name = "midi", |
| 2032 | .probe = usb_midi_probe, | 2031 | .probe = usb_midi_probe, |
| 2033 | .disconnect = usb_midi_disconnect, | 2032 | .disconnect = usb_midi_disconnect, |
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index 357e75335f17..27e9404547f3 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c | |||
| @@ -199,7 +199,7 @@ struct quirk_printer_struct { | |||
| 199 | #define USBLP_QUIRK_BIDIR 0x1 /* reports bidir but requires unidirectional mode (no INs/reads) */ | 199 | #define USBLP_QUIRK_BIDIR 0x1 /* reports bidir but requires unidirectional mode (no INs/reads) */ |
| 200 | #define USBLP_QUIRK_USB_INIT 0x2 /* needs vendor USB init string */ | 200 | #define USBLP_QUIRK_USB_INIT 0x2 /* needs vendor USB init string */ |
| 201 | 201 | ||
| 202 | static struct quirk_printer_struct quirk_printers[] = { | 202 | static const struct quirk_printer_struct quirk_printers[] = { |
| 203 | { 0x03f0, 0x0004, USBLP_QUIRK_BIDIR }, /* HP DeskJet 895C */ | 203 | { 0x03f0, 0x0004, USBLP_QUIRK_BIDIR }, /* HP DeskJet 895C */ |
| 204 | { 0x03f0, 0x0104, USBLP_QUIRK_BIDIR }, /* HP DeskJet 880C */ | 204 | { 0x03f0, 0x0104, USBLP_QUIRK_BIDIR }, /* HP DeskJet 880C */ |
| 205 | { 0x03f0, 0x0204, USBLP_QUIRK_BIDIR }, /* HP DeskJet 815C */ | 205 | { 0x03f0, 0x0204, USBLP_QUIRK_BIDIR }, /* HP DeskJet 815C */ |
| @@ -301,7 +301,7 @@ static void usblp_bulk_write(struct urb *urb, struct pt_regs *regs) | |||
| 301 | * Get and print printer errors. | 301 | * Get and print printer errors. |
| 302 | */ | 302 | */ |
| 303 | 303 | ||
| 304 | static char *usblp_messages[] = { "ok", "out of paper", "off-line", "on fire" }; | 304 | static const char *usblp_messages[] = { "ok", "out of paper", "off-line", "on fire" }; |
| 305 | 305 | ||
| 306 | static int usblp_check_status(struct usblp *usblp, int err) | 306 | static int usblp_check_status(struct usblp *usblp, int err) |
| 307 | { | 307 | { |
| @@ -438,7 +438,7 @@ static unsigned int usblp_poll(struct file *file, struct poll_table_struct *wait | |||
| 438 | | (!usblp->wcomplete ? 0 : POLLOUT | POLLWRNORM); | 438 | | (!usblp->wcomplete ? 0 : POLLOUT | POLLWRNORM); |
| 439 | } | 439 | } |
| 440 | 440 | ||
| 441 | static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | 441 | static long usblp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
| 442 | { | 442 | { |
| 443 | struct usblp *usblp = file->private_data; | 443 | struct usblp *usblp = file->private_data; |
| 444 | int length, err, i; | 444 | int length, err, i; |
| @@ -838,7 +838,8 @@ static struct file_operations usblp_fops = { | |||
| 838 | .read = usblp_read, | 838 | .read = usblp_read, |
| 839 | .write = usblp_write, | 839 | .write = usblp_write, |
| 840 | .poll = usblp_poll, | 840 | .poll = usblp_poll, |
| 841 | .ioctl = usblp_ioctl, | 841 | .unlocked_ioctl = usblp_ioctl, |
| 842 | .compat_ioctl = usblp_ioctl, | ||
| 842 | .open = usblp_open, | 843 | .open = usblp_open, |
| 843 | .release = usblp_release, | 844 | .release = usblp_release, |
| 844 | }; | 845 | }; |
| @@ -849,6 +850,20 @@ static struct usb_class_driver usblp_class = { | |||
| 849 | .minor_base = USBLP_MINOR_BASE, | 850 | .minor_base = USBLP_MINOR_BASE, |
| 850 | }; | 851 | }; |
| 851 | 852 | ||
| 853 | static ssize_t usblp_show_ieee1284_id(struct device *dev, struct device_attribute *attr, char *buf) | ||
| 854 | { | ||
| 855 | struct usb_interface *intf = to_usb_interface(dev); | ||
| 856 | struct usblp *usblp = usb_get_intfdata (intf); | ||
| 857 | |||
| 858 | if (usblp->device_id_string[0] == 0 && | ||
| 859 | usblp->device_id_string[1] == 0) | ||
| 860 | return 0; | ||
| 861 | |||
| 862 | return sprintf(buf, "%s", usblp->device_id_string+2); | ||
| 863 | } | ||
| 864 | |||
| 865 | static DEVICE_ATTR(ieee1284_id, S_IRUGO, usblp_show_ieee1284_id, NULL); | ||
| 866 | |||
| 852 | static int usblp_probe(struct usb_interface *intf, | 867 | static int usblp_probe(struct usb_interface *intf, |
| 853 | const struct usb_device_id *id) | 868 | const struct usb_device_id *id) |
| 854 | { | 869 | { |
| @@ -933,20 +948,12 @@ static int usblp_probe(struct usb_interface *intf, | |||
| 933 | 948 | ||
| 934 | /* Retrieve and store the device ID string. */ | 949 | /* Retrieve and store the device ID string. */ |
| 935 | usblp_cache_device_id_string(usblp); | 950 | usblp_cache_device_id_string(usblp); |
| 951 | device_create_file(&intf->dev, &dev_attr_ieee1284_id); | ||
| 936 | 952 | ||
| 937 | #ifdef DEBUG | 953 | #ifdef DEBUG |
| 938 | usblp_check_status(usblp, 0); | 954 | usblp_check_status(usblp, 0); |
| 939 | #endif | 955 | #endif |
| 940 | 956 | ||
| 941 | info("usblp%d: USB %sdirectional printer dev %d " | ||
| 942 | "if %d alt %d proto %d vid 0x%4.4X pid 0x%4.4X", | ||
| 943 | usblp->minor, usblp->bidir ? "Bi" : "Uni", dev->devnum, | ||
| 944 | usblp->ifnum, | ||
| 945 | usblp->protocol[usblp->current_protocol].alt_setting, | ||
| 946 | usblp->current_protocol, | ||
| 947 | le16_to_cpu(usblp->dev->descriptor.idVendor), | ||
| 948 | le16_to_cpu(usblp->dev->descriptor.idProduct)); | ||
| 949 | |||
| 950 | usb_set_intfdata (intf, usblp); | 957 | usb_set_intfdata (intf, usblp); |
| 951 | 958 | ||
| 952 | usblp->present = 1; | 959 | usblp->present = 1; |
| @@ -957,11 +964,20 @@ static int usblp_probe(struct usb_interface *intf, | |||
| 957 | goto abort_intfdata; | 964 | goto abort_intfdata; |
| 958 | } | 965 | } |
| 959 | usblp->minor = intf->minor; | 966 | usblp->minor = intf->minor; |
| 967 | info("usblp%d: USB %sdirectional printer dev %d " | ||
| 968 | "if %d alt %d proto %d vid 0x%4.4X pid 0x%4.4X", | ||
| 969 | usblp->minor, usblp->bidir ? "Bi" : "Uni", dev->devnum, | ||
| 970 | usblp->ifnum, | ||
| 971 | usblp->protocol[usblp->current_protocol].alt_setting, | ||
| 972 | usblp->current_protocol, | ||
| 973 | le16_to_cpu(usblp->dev->descriptor.idVendor), | ||
| 974 | le16_to_cpu(usblp->dev->descriptor.idProduct)); | ||
| 960 | 975 | ||
| 961 | return 0; | 976 | return 0; |
| 962 | 977 | ||
| 963 | abort_intfdata: | 978 | abort_intfdata: |
| 964 | usb_set_intfdata (intf, NULL); | 979 | usb_set_intfdata (intf, NULL); |
| 980 | device_remove_file(&intf->dev, &dev_attr_ieee1284_id); | ||
| 965 | abort: | 981 | abort: |
| 966 | if (usblp) { | 982 | if (usblp) { |
| 967 | if (usblp->writebuf) | 983 | if (usblp->writebuf) |
| @@ -1156,6 +1172,8 @@ static void usblp_disconnect(struct usb_interface *intf) | |||
| 1156 | BUG (); | 1172 | BUG (); |
| 1157 | } | 1173 | } |
| 1158 | 1174 | ||
| 1175 | device_remove_file(&intf->dev, &dev_attr_ieee1284_id); | ||
| 1176 | |||
| 1159 | down (&usblp_sem); | 1177 | down (&usblp_sem); |
| 1160 | down (&usblp->sem); | 1178 | down (&usblp->sem); |
| 1161 | usblp->present = 0; | 1179 | usblp->present = 0; |
| @@ -1186,7 +1204,6 @@ static struct usb_device_id usblp_ids [] = { | |||
| 1186 | MODULE_DEVICE_TABLE (usb, usblp_ids); | 1204 | MODULE_DEVICE_TABLE (usb, usblp_ids); |
| 1187 | 1205 | ||
| 1188 | static struct usb_driver usblp_driver = { | 1206 | static struct usb_driver usblp_driver = { |
| 1189 | .owner = THIS_MODULE, | ||
| 1190 | .name = "usblp", | 1207 | .name = "usblp", |
| 1191 | .probe = usblp_probe, | 1208 | .probe = usblp_probe, |
| 1192 | .disconnect = usblp_disconnect, | 1209 | .disconnect = usblp_disconnect, |
diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile index 86d5c380892d..28329ddf187c 100644 --- a/drivers/usb/core/Makefile +++ b/drivers/usb/core/Makefile | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | # Makefile for USB Core files and filesystem | 2 | # Makefile for USB Core files and filesystem |
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | usbcore-objs := usb.o hub.o hcd.o urb.o message.o \ | 5 | usbcore-objs := usb.o hub.o hcd.o urb.o message.o driver.o \ |
| 6 | config.o file.o buffer.o sysfs.o devio.o notify.o | 6 | config.o file.o buffer.o sysfs.o devio.o notify.o |
| 7 | 7 | ||
| 8 | ifeq ($(CONFIG_PCI),y) | 8 | ifeq ($(CONFIG_PCI),y) |
diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c index 419c9943a7cb..ad742cec94fa 100644 --- a/drivers/usb/core/buffer.c +++ b/drivers/usb/core/buffer.c | |||
| @@ -55,6 +55,9 @@ int hcd_buffer_create (struct usb_hcd *hcd) | |||
| 55 | char name [16]; | 55 | char name [16]; |
| 56 | int i, size; | 56 | int i, size; |
| 57 | 57 | ||
| 58 | if (!hcd->self.controller->dma_mask) | ||
| 59 | return 0; | ||
| 60 | |||
| 58 | for (i = 0; i < HCD_BUFFER_POOLS; i++) { | 61 | for (i = 0; i < HCD_BUFFER_POOLS; i++) { |
| 59 | if (!(size = pool_max [i])) | 62 | if (!(size = pool_max [i])) |
| 60 | continue; | 63 | continue; |
diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c index 83e815d3cd52..2684e15b813b 100644 --- a/drivers/usb/core/devices.c +++ b/drivers/usb/core/devices.c | |||
| @@ -67,45 +67,45 @@ | |||
| 67 | /* Define ALLOW_SERIAL_NUMBER if you want to see the serial number of devices */ | 67 | /* Define ALLOW_SERIAL_NUMBER if you want to see the serial number of devices */ |
| 68 | #define ALLOW_SERIAL_NUMBER | 68 | #define ALLOW_SERIAL_NUMBER |
| 69 | 69 | ||
| 70 | static char *format_topo = | 70 | static const char *format_topo = |
| 71 | /* T: Bus=dd Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=ddd MxCh=dd */ | 71 | /* T: Bus=dd Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=ddd MxCh=dd */ |
| 72 | "\nT: Bus=%2.2d Lev=%2.2d Prnt=%2.2d Port=%2.2d Cnt=%2.2d Dev#=%3d Spd=%3s MxCh=%2d\n"; | 72 | "\nT: Bus=%2.2d Lev=%2.2d Prnt=%2.2d Port=%2.2d Cnt=%2.2d Dev#=%3d Spd=%3s MxCh=%2d\n"; |
| 73 | 73 | ||
| 74 | static char *format_string_manufacturer = | 74 | static const char *format_string_manufacturer = |
| 75 | /* S: Manufacturer=xxxx */ | 75 | /* S: Manufacturer=xxxx */ |
| 76 | "S: Manufacturer=%.100s\n"; | 76 | "S: Manufacturer=%.100s\n"; |
| 77 | 77 | ||
| 78 | static char *format_string_product = | 78 | static const char *format_string_product = |
| 79 | /* S: Product=xxxx */ | 79 | /* S: Product=xxxx */ |
| 80 | "S: Product=%.100s\n"; | 80 | "S: Product=%.100s\n"; |
| 81 | 81 | ||
| 82 | #ifdef ALLOW_SERIAL_NUMBER | 82 | #ifdef ALLOW_SERIAL_NUMBER |
| 83 | static char *format_string_serialnumber = | 83 | static const char *format_string_serialnumber = |
| 84 | /* S: SerialNumber=xxxx */ | 84 | /* S: SerialNumber=xxxx */ |
| 85 | "S: SerialNumber=%.100s\n"; | 85 | "S: SerialNumber=%.100s\n"; |
| 86 | #endif | 86 | #endif |
| 87 | 87 | ||
| 88 | static char *format_bandwidth = | 88 | static const char *format_bandwidth = |
| 89 | /* B: Alloc=ddd/ddd us (xx%), #Int=ddd, #Iso=ddd */ | 89 | /* B: Alloc=ddd/ddd us (xx%), #Int=ddd, #Iso=ddd */ |
| 90 | "B: Alloc=%3d/%3d us (%2d%%), #Int=%3d, #Iso=%3d\n"; | 90 | "B: Alloc=%3d/%3d us (%2d%%), #Int=%3d, #Iso=%3d\n"; |
| 91 | 91 | ||
| 92 | static char *format_device1 = | 92 | static const char *format_device1 = |
| 93 | /* D: Ver=xx.xx Cls=xx(sssss) Sub=xx Prot=xx MxPS=dd #Cfgs=dd */ | 93 | /* D: Ver=xx.xx Cls=xx(sssss) Sub=xx Prot=xx MxPS=dd #Cfgs=dd */ |
| 94 | "D: Ver=%2x.%02x Cls=%02x(%-5s) Sub=%02x Prot=%02x MxPS=%2d #Cfgs=%3d\n"; | 94 | "D: Ver=%2x.%02x Cls=%02x(%-5s) Sub=%02x Prot=%02x MxPS=%2d #Cfgs=%3d\n"; |
| 95 | 95 | ||
| 96 | static char *format_device2 = | 96 | static const char *format_device2 = |
| 97 | /* P: Vendor=xxxx ProdID=xxxx Rev=xx.xx */ | 97 | /* P: Vendor=xxxx ProdID=xxxx Rev=xx.xx */ |
| 98 | "P: Vendor=%04x ProdID=%04x Rev=%2x.%02x\n"; | 98 | "P: Vendor=%04x ProdID=%04x Rev=%2x.%02x\n"; |
| 99 | 99 | ||
| 100 | static char *format_config = | 100 | static const char *format_config = |
| 101 | /* C: #Ifs=dd Cfg#=dd Atr=xx MPwr=dddmA */ | 101 | /* C: #Ifs=dd Cfg#=dd Atr=xx MPwr=dddmA */ |
| 102 | "C:%c #Ifs=%2d Cfg#=%2d Atr=%02x MxPwr=%3dmA\n"; | 102 | "C:%c #Ifs=%2d Cfg#=%2d Atr=%02x MxPwr=%3dmA\n"; |
| 103 | 103 | ||
| 104 | static char *format_iface = | 104 | static const char *format_iface = |
| 105 | /* I: If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx Driver=xxxx*/ | 105 | /* I: If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx Driver=xxxx*/ |
| 106 | "I: If#=%2d Alt=%2d #EPs=%2d Cls=%02x(%-5s) Sub=%02x Prot=%02x Driver=%s\n"; | 106 | "I: If#=%2d Alt=%2d #EPs=%2d Cls=%02x(%-5s) Sub=%02x Prot=%02x Driver=%s\n"; |
| 107 | 107 | ||
| 108 | static char *format_endpt = | 108 | static const char *format_endpt = |
| 109 | /* E: Ad=xx(s) Atr=xx(ssss) MxPS=dddd Ivl=D?s */ | 109 | /* E: Ad=xx(s) Atr=xx(ssss) MxPS=dddd Ivl=D?s */ |
| 110 | "E: Ad=%02x(%c) Atr=%02x(%-4s) MxPS=%4d Ivl=%d%cs\n"; | 110 | "E: Ad=%02x(%c) Atr=%02x(%-4s) MxPS=%4d Ivl=%d%cs\n"; |
| 111 | 111 | ||
| @@ -545,10 +545,10 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes, loff_t *ski | |||
| 545 | struct usb_device *childdev = usbdev->children[chix]; | 545 | struct usb_device *childdev = usbdev->children[chix]; |
| 546 | 546 | ||
| 547 | if (childdev) { | 547 | if (childdev) { |
| 548 | down(&childdev->serialize); | 548 | usb_lock_device(childdev); |
| 549 | ret = usb_device_dump(buffer, nbytes, skip_bytes, file_offset, childdev, | 549 | ret = usb_device_dump(buffer, nbytes, skip_bytes, file_offset, childdev, |
| 550 | bus, level + 1, chix, ++cnt); | 550 | bus, level + 1, chix, ++cnt); |
| 551 | up(&childdev->serialize); | 551 | usb_unlock_device(childdev); |
| 552 | if (ret == -EFAULT) | 552 | if (ret == -EFAULT) |
| 553 | return total_written; | 553 | return total_written; |
| 554 | total_written += ret; | 554 | total_written += ret; |
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index b1d6e9af732d..2b68998fe4b3 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
| @@ -402,7 +402,6 @@ static void driver_disconnect(struct usb_interface *intf) | |||
| 402 | } | 402 | } |
| 403 | 403 | ||
| 404 | struct usb_driver usbfs_driver = { | 404 | struct usb_driver usbfs_driver = { |
| 405 | .owner = THIS_MODULE, | ||
| 406 | .name = "usbfs", | 405 | .name = "usbfs", |
| 407 | .probe = driver_probe, | 406 | .probe = driver_probe, |
| 408 | .disconnect = driver_disconnect, | 407 | .disconnect = driver_disconnect, |
| @@ -1350,9 +1349,7 @@ static int proc_ioctl(struct dev_state *ps, struct usbdevfs_ioctl *ctl) | |||
| 1350 | /* let kernel drivers try to (re)bind to the interface */ | 1349 | /* let kernel drivers try to (re)bind to the interface */ |
| 1351 | case USBDEVFS_CONNECT: | 1350 | case USBDEVFS_CONNECT: |
| 1352 | usb_unlock_device(ps->dev); | 1351 | usb_unlock_device(ps->dev); |
| 1353 | usb_lock_all_devices(); | ||
| 1354 | bus_rescan_devices(intf->dev.bus); | 1352 | bus_rescan_devices(intf->dev.bus); |
| 1355 | usb_unlock_all_devices(); | ||
| 1356 | usb_lock_device(ps->dev); | 1353 | usb_lock_device(ps->dev); |
| 1357 | break; | 1354 | break; |
| 1358 | 1355 | ||
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c new file mode 100644 index 000000000000..076462c8ba2a --- /dev/null +++ b/drivers/usb/core/driver.c | |||
| @@ -0,0 +1,472 @@ | |||
| 1 | /* | ||
| 2 | * drivers/usb/driver.c - most of the driver model stuff for usb | ||
| 3 | * | ||
| 4 | * (C) Copyright 2005 Greg Kroah-Hartman <gregkh@suse.de> | ||
| 5 | * | ||
| 6 | * based on drivers/usb/usb.c which had the following copyrights: | ||
| 7 | * (C) Copyright Linus Torvalds 1999 | ||
| 8 | * (C) Copyright Johannes Erdfelt 1999-2001 | ||
| 9 | * (C) Copyright Andreas Gal 1999 | ||
| 10 | * (C) Copyright Gregory P. Smith 1999 | ||
| 11 | * (C) Copyright Deti Fliegl 1999 (new USB architecture) | ||
| 12 | * (C) Copyright Randy Dunlap 2000 | ||
| 13 | * (C) Copyright David Brownell 2000-2004 | ||
| 14 | * (C) Copyright Yggdrasil Computing, Inc. 2000 | ||
| 15 | * (usb_device_id matching changes by Adam J. Richter) | ||
| 16 | * (C) Copyright Greg Kroah-Hartman 2002-2003 | ||
| 17 | * | ||
| 18 | * NOTE! This is not actually a driver at all, rather this is | ||
| 19 | * just a collection of helper routines that implement the | ||
| 20 | * generic USB things that the real drivers can use.. | ||
| 21 | * | ||
| 22 | */ | ||
| 23 | |||
| 24 | #include <linux/config.h> | ||
| 25 | #include <linux/device.h> | ||
| 26 | #include <linux/usb.h> | ||
| 27 | #include "hcd.h" | ||
| 28 | #include "usb.h" | ||
| 29 | |||
| 30 | static int usb_match_one_id(struct usb_interface *interface, | ||
| 31 | const struct usb_device_id *id); | ||
| 32 | |||
| 33 | struct usb_dynid { | ||
| 34 | struct list_head node; | ||
| 35 | struct usb_device_id id; | ||
| 36 | }; | ||
| 37 | |||
| 38 | |||
| 39 | static int generic_probe(struct device *dev) | ||
| 40 | { | ||
| 41 | return 0; | ||
| 42 | } | ||
| 43 | static int generic_remove(struct device *dev) | ||
| 44 | { | ||
| 45 | struct usb_device *udev = to_usb_device(dev); | ||
| 46 | |||
| 47 | /* if this is only an unbind, not a physical disconnect, then | ||
| 48 | * unconfigure the device */ | ||
| 49 | if (udev->state == USB_STATE_CONFIGURED) | ||
| 50 | usb_set_configuration(udev, 0); | ||
| 51 | |||
| 52 | /* in case the call failed or the device was suspended */ | ||
| 53 | if (udev->state >= USB_STATE_CONFIGURED) | ||
| 54 | usb_disable_device(udev, 0); | ||
| 55 | return 0; | ||
| 56 | } | ||
| 57 | |||
| 58 | struct device_driver usb_generic_driver = { | ||
| 59 | .owner = THIS_MODULE, | ||
| 60 | .name = "usb", | ||
| 61 | .bus = &usb_bus_type, | ||
| 62 | .probe = generic_probe, | ||
| 63 | .remove = generic_remove, | ||
| 64 | }; | ||
| 65 | |||
| 66 | /* Fun hack to determine if the struct device is a | ||
| 67 | * usb device or a usb interface. */ | ||
| 68 | int usb_generic_driver_data; | ||
| 69 | |||
| 70 | #ifdef CONFIG_HOTPLUG | ||
| 71 | |||
| 72 | /* | ||
| 73 | * Adds a new dynamic USBdevice ID to this driver, | ||
| 74 | * and cause the driver to probe for all devices again. | ||
| 75 | */ | ||
| 76 | static ssize_t store_new_id(struct device_driver *driver, | ||
| 77 | const char *buf, size_t count) | ||
| 78 | { | ||
| 79 | struct usb_driver *usb_drv = to_usb_driver(driver); | ||
| 80 | struct usb_dynid *dynid; | ||
| 81 | u32 idVendor = 0; | ||
| 82 | u32 idProduct = 0; | ||
| 83 | int fields = 0; | ||
| 84 | |||
| 85 | fields = sscanf(buf, "%x %x", &idVendor, &idProduct); | ||
| 86 | if (fields < 2) | ||
| 87 | return -EINVAL; | ||
| 88 | |||
| 89 | dynid = kzalloc(sizeof(*dynid), GFP_KERNEL); | ||
| 90 | if (!dynid) | ||
| 91 | return -ENOMEM; | ||
| 92 | |||
| 93 | INIT_LIST_HEAD(&dynid->node); | ||
| 94 | dynid->id.idVendor = idVendor; | ||
| 95 | dynid->id.idProduct = idProduct; | ||
| 96 | dynid->id.match_flags = USB_DEVICE_ID_MATCH_DEVICE; | ||
| 97 | |||
| 98 | spin_lock(&usb_drv->dynids.lock); | ||
| 99 | list_add_tail(&usb_drv->dynids.list, &dynid->node); | ||
| 100 | spin_unlock(&usb_drv->dynids.lock); | ||
| 101 | |||
| 102 | if (get_driver(driver)) { | ||
| 103 | driver_attach(driver); | ||
| 104 | put_driver(driver); | ||
| 105 | } | ||
| 106 | |||
| 107 | return count; | ||
| 108 | } | ||
| 109 | static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id); | ||
| 110 | |||
| 111 | static int usb_create_newid_file(struct usb_driver *usb_drv) | ||
| 112 | { | ||
| 113 | int error = 0; | ||
| 114 | |||
| 115 | if (usb_drv->no_dynamic_id) | ||
| 116 | goto exit; | ||
| 117 | |||
| 118 | if (usb_drv->probe != NULL) | ||
| 119 | error = sysfs_create_file(&usb_drv->driver.kobj, | ||
| 120 | &driver_attr_new_id.attr); | ||
| 121 | exit: | ||
| 122 | return error; | ||
| 123 | } | ||
| 124 | |||
| 125 | static void usb_remove_newid_file(struct usb_driver *usb_drv) | ||
| 126 | { | ||
| 127 | if (usb_drv->no_dynamic_id) | ||
| 128 | return; | ||
| 129 | |||
| 130 | if (usb_drv->probe != NULL) | ||
| 131 | sysfs_remove_file(&usb_drv->driver.kobj, | ||
| 132 | &driver_attr_new_id.attr); | ||
| 133 | } | ||
| 134 | |||
| 135 | static void usb_free_dynids(struct usb_driver *usb_drv) | ||
| 136 | { | ||
| 137 | struct usb_dynid *dynid, *n; | ||
| 138 | |||
| 139 | spin_lock(&usb_drv->dynids.lock); | ||
| 140 | list_for_each_entry_safe(dynid, n, &usb_drv->dynids.list, node) { | ||
| 141 | list_del(&dynid->node); | ||
| 142 | kfree(dynid); | ||
| 143 | } | ||
| 144 | spin_unlock(&usb_drv->dynids.lock); | ||
| 145 | } | ||
| 146 | #else | ||
| 147 | static inline int usb_create_newid_file(struct usb_driver *usb_drv) | ||
| 148 | { | ||
| 149 | return 0; | ||
| 150 | } | ||
| 151 | |||
| 152 | static void usb_remove_newid_file(struct usb_driver *usb_drv) | ||
| 153 | { | ||
| 154 | } | ||
| 155 | |||
| 156 | static inline void usb_free_dynids(struct usb_driver *usb_drv) | ||
| 157 | { | ||
| 158 | } | ||
| 159 | #endif | ||
| 160 | |||
| 161 | static const struct usb_device_id *usb_match_dynamic_id(struct usb_interface *intf, | ||
| 162 | struct usb_driver *drv) | ||
| 163 | { | ||
| 164 | struct usb_dynid *dynid; | ||
| 165 | |||
| 166 | spin_lock(&drv->dynids.lock); | ||
| 167 | list_for_each_entry(dynid, &drv->dynids.list, node) { | ||
| 168 | if (usb_match_one_id(intf, &dynid->id)) { | ||
| 169 | spin_unlock(&drv->dynids.lock); | ||
| 170 | return &dynid->id; | ||
| 171 | } | ||
| 172 | } | ||
| 173 | spin_unlock(&drv->dynids.lock); | ||
| 174 | return NULL; | ||
| 175 | } | ||
| 176 | |||
| 177 | |||
| 178 | /* called from driver core with usb_bus_type.subsys writelock */ | ||
| 179 | static int usb_probe_interface(struct device *dev) | ||
| 180 | { | ||
| 181 | struct usb_interface * intf = to_usb_interface(dev); | ||
| 182 | struct usb_driver * driver = to_usb_driver(dev->driver); | ||
| 183 | const struct usb_device_id *id; | ||
| 184 | int error = -ENODEV; | ||
| 185 | |||
| 186 | dev_dbg(dev, "%s\n", __FUNCTION__); | ||
| 187 | |||
| 188 | if (!driver->probe) | ||
| 189 | return error; | ||
| 190 | /* FIXME we'd much prefer to just resume it ... */ | ||
| 191 | if (interface_to_usbdev(intf)->state == USB_STATE_SUSPENDED) | ||
| 192 | return -EHOSTUNREACH; | ||
| 193 | |||
| 194 | id = usb_match_id(intf, driver->id_table); | ||
| 195 | if (!id) | ||
| 196 | id = usb_match_dynamic_id(intf, driver); | ||
| 197 | if (id) { | ||
| 198 | dev_dbg(dev, "%s - got id\n", __FUNCTION__); | ||
| 199 | |||
| 200 | /* Interface "power state" doesn't correspond to any hardware | ||
| 201 | * state whatsoever. We use it to record when it's bound to | ||
| 202 | * a driver that may start I/0: it's not frozen/quiesced. | ||
| 203 | */ | ||
| 204 | mark_active(intf); | ||
| 205 | intf->condition = USB_INTERFACE_BINDING; | ||
| 206 | error = driver->probe(intf, id); | ||
| 207 | if (error) { | ||
| 208 | mark_quiesced(intf); | ||
| 209 | intf->condition = USB_INTERFACE_UNBOUND; | ||
| 210 | } else | ||
| 211 | intf->condition = USB_INTERFACE_BOUND; | ||
| 212 | } | ||
| 213 | |||
| 214 | return error; | ||
| 215 | } | ||
| 216 | |||
| 217 | /* called from driver core with usb_bus_type.subsys writelock */ | ||
| 218 | static int usb_unbind_interface(struct device *dev) | ||
| 219 | { | ||
| 220 | struct usb_interface *intf = to_usb_interface(dev); | ||
| 221 | struct usb_driver *driver = to_usb_driver(intf->dev.driver); | ||
| 222 | |||
| 223 | intf->condition = USB_INTERFACE_UNBINDING; | ||
| 224 | |||
| 225 | /* release all urbs for this interface */ | ||
| 226 | usb_disable_interface(interface_to_usbdev(intf), intf); | ||
| 227 | |||
| 228 | if (driver && driver->disconnect) | ||
| 229 | driver->disconnect(intf); | ||
| 230 | |||
| 231 | /* reset other interface state */ | ||
| 232 | usb_set_interface(interface_to_usbdev(intf), | ||
| 233 | intf->altsetting[0].desc.bInterfaceNumber, | ||
| 234 | 0); | ||
| 235 | usb_set_intfdata(intf, NULL); | ||
| 236 | intf->condition = USB_INTERFACE_UNBOUND; | ||
| 237 | mark_quiesced(intf); | ||
| 238 | |||
| 239 | return 0; | ||
| 240 | } | ||
| 241 | |||
| 242 | /* returns 0 if no match, 1 if match */ | ||
| 243 | static int usb_match_one_id(struct usb_interface *interface, | ||
| 244 | const struct usb_device_id *id) | ||
| 245 | { | ||
| 246 | struct usb_host_interface *intf; | ||
| 247 | struct usb_device *dev; | ||
| 248 | |||
| 249 | /* proc_connectinfo in devio.c may call us with id == NULL. */ | ||
| 250 | if (id == NULL) | ||
| 251 | return 0; | ||
| 252 | |||
| 253 | intf = interface->cur_altsetting; | ||
| 254 | dev = interface_to_usbdev(interface); | ||
| 255 | |||
| 256 | if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) && | ||
| 257 | id->idVendor != le16_to_cpu(dev->descriptor.idVendor)) | ||
| 258 | return 0; | ||
| 259 | |||
| 260 | if ((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) && | ||
| 261 | id->idProduct != le16_to_cpu(dev->descriptor.idProduct)) | ||
| 262 | return 0; | ||
| 263 | |||
| 264 | /* No need to test id->bcdDevice_lo != 0, since 0 is never | ||
| 265 | greater than any unsigned number. */ | ||
| 266 | if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_LO) && | ||
| 267 | (id->bcdDevice_lo > le16_to_cpu(dev->descriptor.bcdDevice))) | ||
| 268 | return 0; | ||
| 269 | |||
| 270 | if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI) && | ||
| 271 | (id->bcdDevice_hi < le16_to_cpu(dev->descriptor.bcdDevice))) | ||
| 272 | return 0; | ||
| 273 | |||
| 274 | if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS) && | ||
| 275 | (id->bDeviceClass != dev->descriptor.bDeviceClass)) | ||
| 276 | return 0; | ||
| 277 | |||
| 278 | if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS) && | ||
| 279 | (id->bDeviceSubClass!= dev->descriptor.bDeviceSubClass)) | ||
| 280 | return 0; | ||
| 281 | |||
| 282 | if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL) && | ||
| 283 | (id->bDeviceProtocol != dev->descriptor.bDeviceProtocol)) | ||
| 284 | return 0; | ||
| 285 | |||
| 286 | if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) && | ||
| 287 | (id->bInterfaceClass != intf->desc.bInterfaceClass)) | ||
| 288 | return 0; | ||
| 289 | |||
| 290 | if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_SUBCLASS) && | ||
| 291 | (id->bInterfaceSubClass != intf->desc.bInterfaceSubClass)) | ||
| 292 | return 0; | ||
| 293 | |||
| 294 | if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_PROTOCOL) && | ||
| 295 | (id->bInterfaceProtocol != intf->desc.bInterfaceProtocol)) | ||
| 296 | return 0; | ||
| 297 | |||
| 298 | return 1; | ||
| 299 | } | ||
| 300 | /** | ||
| 301 | * usb_match_id - find first usb_device_id matching device or interface | ||
| 302 | * @interface: the interface of interest | ||
| 303 | * @id: array of usb_device_id structures, terminated by zero entry | ||
| 304 | * | ||
| 305 | * usb_match_id searches an array of usb_device_id's and returns | ||
| 306 | * the first one matching the device or interface, or null. | ||
| 307 | * This is used when binding (or rebinding) a driver to an interface. | ||
| 308 | * Most USB device drivers will use this indirectly, through the usb core, | ||
| 309 | * but some layered driver frameworks use it directly. | ||
| 310 | * These device tables are exported with MODULE_DEVICE_TABLE, through | ||
| 311 | * modutils, to support the driver loading functionality of USB hotplugging. | ||
| 312 | * | ||
| 313 | * What Matches: | ||
| 314 | * | ||
| 315 | * The "match_flags" element in a usb_device_id controls which | ||
| 316 | * members are used. If the corresponding bit is set, the | ||
| 317 | * value in the device_id must match its corresponding member | ||
| 318 | * in the device or interface descriptor, or else the device_id | ||
| 319 | * does not match. | ||
| 320 | * | ||
| 321 | * "driver_info" is normally used only by device drivers, | ||
| 322 | * but you can create a wildcard "matches anything" usb_device_id | ||
| 323 | * as a driver's "modules.usbmap" entry if you provide an id with | ||
| 324 | * only a nonzero "driver_info" field. If you do this, the USB device | ||
| 325 | * driver's probe() routine should use additional intelligence to | ||
| 326 | * decide whether to bind to the specified interface. | ||
| 327 | * | ||
| 328 | * What Makes Good usb_device_id Tables: | ||
| 329 | * | ||
| 330 | * The match algorithm is very simple, so that intelligence in | ||
| 331 | * driver selection must come from smart driver id records. | ||
| 332 | * Unless you have good reasons to use another selection policy, | ||
| 333 | * provide match elements only in related groups, and order match | ||
| 334 | * specifiers from specific to general. Use the macros provided | ||
| 335 | * for that purpose if you can. | ||
| 336 | * | ||
| 337 | * The most specific match specifiers use device descriptor | ||
| 338 | * data. These are commonly used with product-specific matches; | ||
| 339 | * the USB_DEVICE macro lets you provide vendor and product IDs, | ||
| 340 | * and you can also match against ranges of product revisions. | ||
| 341 | * These are widely used for devices with application or vendor | ||
| 342 | * specific bDeviceClass values. | ||
| 343 | * | ||
| 344 | * Matches based on device class/subclass/protocol specifications | ||
| 345 | * are slightly more general; use the USB_DEVICE_INFO macro, or | ||
| 346 | * its siblings. These are used with single-function devices | ||
| 347 | * where bDeviceClass doesn't specify that each interface has | ||
| 348 | * its own class. | ||
| 349 | * | ||
| 350 | * Matches based on interface class/subclass/protocol are the | ||
| 351 | * most general; they let drivers bind to any interface on a | ||
| 352 | * multiple-function device. Use the USB_INTERFACE_INFO | ||
| 353 | * macro, or its siblings, to match class-per-interface style | ||
| 354 | * devices (as recorded in bDeviceClass). | ||
| 355 | * | ||
| 356 | * Within those groups, remember that not all combinations are | ||
| 357 | * meaningful. For example, don't give a product version range | ||
| 358 | * without vendor and product IDs; or specify a protocol without | ||
| 359 | * its associated class and subclass. | ||
| 360 | */ | ||
| 361 | const struct usb_device_id *usb_match_id(struct usb_interface *interface, | ||
| 362 | const struct usb_device_id *id) | ||
| 363 | { | ||
| 364 | /* proc_connectinfo in devio.c may call us with id == NULL. */ | ||
| 365 | if (id == NULL) | ||
| 366 | return NULL; | ||
| 367 | |||
| 368 | /* It is important to check that id->driver_info is nonzero, | ||
| 369 | since an entry that is all zeroes except for a nonzero | ||
| 370 | id->driver_info is the way to create an entry that | ||
| 371 | indicates that the driver want to examine every | ||
| 372 | device and interface. */ | ||
| 373 | for (; id->idVendor || id->bDeviceClass || id->bInterfaceClass || | ||
| 374 | id->driver_info; id++) { | ||
| 375 | if (usb_match_one_id(interface, id)) | ||
| 376 | return id; | ||
| 377 | } | ||
| 378 | |||
| 379 | return NULL; | ||
| 380 | } | ||
| 381 | EXPORT_SYMBOL_GPL(usb_match_id); | ||
| 382 | |||
| 383 | int usb_device_match(struct device *dev, struct device_driver *drv) | ||
| 384 | { | ||
| 385 | struct usb_interface *intf; | ||
| 386 | struct usb_driver *usb_drv; | ||
| 387 | const struct usb_device_id *id; | ||
| 388 | |||
| 389 | /* check for generic driver, which we don't match any device with */ | ||
| 390 | if (drv == &usb_generic_driver) | ||
| 391 | return 0; | ||
| 392 | |||
| 393 | intf = to_usb_interface(dev); | ||
| 394 | usb_drv = to_usb_driver(drv); | ||
| 395 | |||
| 396 | id = usb_match_id(intf, usb_drv->id_table); | ||
| 397 | if (id) | ||
| 398 | return 1; | ||
| 399 | |||
| 400 | id = usb_match_dynamic_id(intf, usb_drv); | ||
| 401 | if (id) | ||
| 402 | return 1; | ||
| 403 | return 0; | ||
| 404 | } | ||
| 405 | |||
| 406 | /** | ||
| 407 | * usb_register_driver - register a USB driver | ||
| 408 | * @new_driver: USB operations for the driver | ||
| 409 | * @owner: module owner of this driver. | ||
| 410 | * | ||
| 411 | * Registers a USB driver with the USB core. The list of unattached | ||
| 412 | * interfaces will be rescanned whenever a new driver is added, allowing | ||
| 413 | * the new driver to attach to any recognized devices. | ||
| 414 | * Returns a negative error code on failure and 0 on success. | ||
| 415 | * | ||
| 416 | * NOTE: if you want your driver to use the USB major number, you must call | ||
| 417 | * usb_register_dev() to enable that functionality. This function no longer | ||
| 418 | * takes care of that. | ||
| 419 | */ | ||
| 420 | int usb_register_driver(struct usb_driver *new_driver, struct module *owner) | ||
| 421 | { | ||
| 422 | int retval = 0; | ||
| 423 | |||
| 424 | if (usb_disabled()) | ||
| 425 | return -ENODEV; | ||
| 426 | |||
| 427 | new_driver->driver.name = (char *)new_driver->name; | ||
| 428 | new_driver->driver.bus = &usb_bus_type; | ||
| 429 | new_driver->driver.probe = usb_probe_interface; | ||
| 430 | new_driver->driver.remove = usb_unbind_interface; | ||
| 431 | new_driver->driver.owner = owner; | ||
| 432 | spin_lock_init(&new_driver->dynids.lock); | ||
| 433 | INIT_LIST_HEAD(&new_driver->dynids.list); | ||
| 434 | |||
| 435 | retval = driver_register(&new_driver->driver); | ||
| 436 | |||
| 437 | if (!retval) { | ||
| 438 | pr_info("%s: registered new driver %s\n", | ||
| 439 | usbcore_name, new_driver->name); | ||
| 440 | usbfs_update_special(); | ||
| 441 | usb_create_newid_file(new_driver); | ||
| 442 | } else { | ||
| 443 | printk(KERN_ERR "%s: error %d registering driver %s\n", | ||
| 444 | usbcore_name, retval, new_driver->name); | ||
| 445 | } | ||
| 446 | |||
| 447 | return retval; | ||
| 448 | } | ||
| 449 | EXPORT_SYMBOL_GPL(usb_register_driver); | ||
| 450 | |||
| 451 | /** | ||
| 452 | * usb_deregister - unregister a USB driver | ||
| 453 | * @driver: USB operations of the driver to unregister | ||
| 454 | * Context: must be able to sleep | ||
| 455 | * | ||
| 456 | * Unlinks the specified driver from the internal USB driver list. | ||
| 457 | * | ||
| 458 | * NOTE: If you called usb_register_dev(), you still need to call | ||
| 459 | * usb_deregister_dev() to clean up your driver's allocated minor numbers, | ||
| 460 | * this * call will no longer do it for you. | ||
| 461 | */ | ||
| 462 | void usb_deregister(struct usb_driver *driver) | ||
| 463 | { | ||
| 464 | pr_info("%s: deregistering driver %s\n", usbcore_name, driver->name); | ||
| 465 | |||
| 466 | usb_remove_newid_file(driver); | ||
| 467 | usb_free_dynids(driver); | ||
| 468 | driver_unregister(&driver->driver); | ||
| 469 | |||
| 470 | usbfs_update_special(); | ||
| 471 | } | ||
| 472 | EXPORT_SYMBOL_GPL(usb_deregister); | ||
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index da24c31ee00d..0018bbc4de34 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
| @@ -857,9 +857,7 @@ static int register_root_hub (struct usb_device *usb_dev, | |||
| 857 | return (retval < 0) ? retval : -EMSGSIZE; | 857 | return (retval < 0) ? retval : -EMSGSIZE; |
| 858 | } | 858 | } |
| 859 | 859 | ||
| 860 | usb_lock_device (usb_dev); | ||
| 861 | retval = usb_new_device (usb_dev); | 860 | retval = usb_new_device (usb_dev); |
| 862 | usb_unlock_device (usb_dev); | ||
| 863 | if (retval) { | 861 | if (retval) { |
| 864 | usb_dev->bus->root_hub = NULL; | 862 | usb_dev->bus->root_hub = NULL; |
| 865 | dev_err (parent_dev, "can't register root hub for %s, %d\n", | 863 | dev_err (parent_dev, "can't register root hub for %s, %d\n", |
| @@ -1827,8 +1825,6 @@ int usb_add_hcd(struct usb_hcd *hcd, | |||
| 1827 | retval = -ENOMEM; | 1825 | retval = -ENOMEM; |
| 1828 | goto err_allocate_root_hub; | 1826 | goto err_allocate_root_hub; |
| 1829 | } | 1827 | } |
| 1830 | rhdev->speed = (hcd->driver->flags & HCD_USB2) ? USB_SPEED_HIGH : | ||
| 1831 | USB_SPEED_FULL; | ||
| 1832 | 1828 | ||
| 1833 | /* Although in principle hcd->driver->start() might need to use rhdev, | 1829 | /* Although in principle hcd->driver->start() might need to use rhdev, |
| 1834 | * none of the current drivers do. | 1830 | * none of the current drivers do. |
| @@ -1846,6 +1842,9 @@ int usb_add_hcd(struct usb_hcd *hcd, | |||
| 1846 | dev_dbg(hcd->self.controller, "supports USB remote wakeup\n"); | 1842 | dev_dbg(hcd->self.controller, "supports USB remote wakeup\n"); |
| 1847 | hcd->remote_wakeup = hcd->can_wakeup; | 1843 | hcd->remote_wakeup = hcd->can_wakeup; |
| 1848 | 1844 | ||
| 1845 | rhdev->speed = (hcd->driver->flags & HCD_USB2) ? USB_SPEED_HIGH : | ||
| 1846 | USB_SPEED_FULL; | ||
| 1847 | rhdev->bus_mA = min(500u, hcd->power_budget); | ||
| 1849 | if ((retval = register_root_hub(rhdev, hcd)) != 0) | 1848 | if ((retval = register_root_hub(rhdev, hcd)) != 0) |
| 1850 | goto err_register_root_hub; | 1849 | goto err_register_root_hub; |
| 1851 | 1850 | ||
| @@ -1891,7 +1890,10 @@ void usb_remove_hcd(struct usb_hcd *hcd) | |||
| 1891 | spin_lock_irq (&hcd_root_hub_lock); | 1890 | spin_lock_irq (&hcd_root_hub_lock); |
| 1892 | hcd->rh_registered = 0; | 1891 | hcd->rh_registered = 0; |
| 1893 | spin_unlock_irq (&hcd_root_hub_lock); | 1892 | spin_unlock_irq (&hcd_root_hub_lock); |
| 1893 | |||
| 1894 | down(&usb_bus_list_lock); | ||
| 1894 | usb_disconnect(&hcd->self.root_hub); | 1895 | usb_disconnect(&hcd->self.root_hub); |
| 1896 | up(&usb_bus_list_lock); | ||
| 1895 | 1897 | ||
| 1896 | hcd->poll_rh = 0; | 1898 | hcd->poll_rh = 0; |
| 1897 | del_timer_sync(&hcd->rh_timer); | 1899 | del_timer_sync(&hcd->rh_timer); |
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index c8a1b350e2cf..591b5aad1a18 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h | |||
| @@ -380,6 +380,7 @@ extern int usb_find_interface_driver (struct usb_device *dev, | |||
| 380 | #ifdef CONFIG_PM | 380 | #ifdef CONFIG_PM |
| 381 | extern void usb_hcd_suspend_root_hub (struct usb_hcd *hcd); | 381 | extern void usb_hcd_suspend_root_hub (struct usb_hcd *hcd); |
| 382 | extern void usb_hcd_resume_root_hub (struct usb_hcd *hcd); | 382 | extern void usb_hcd_resume_root_hub (struct usb_hcd *hcd); |
| 383 | extern void usb_root_hub_lost_power (struct usb_device *rhdev); | ||
| 383 | extern int hcd_bus_suspend (struct usb_bus *bus); | 384 | extern int hcd_bus_suspend (struct usb_bus *bus); |
| 384 | extern int hcd_bus_resume (struct usb_bus *bus); | 385 | extern int hcd_bus_resume (struct usb_bus *bus); |
| 385 | #else | 386 | #else |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index f78bd124d290..650d5ee5871b 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
| @@ -32,7 +32,7 @@ | |||
| 32 | #include "hub.h" | 32 | #include "hub.h" |
| 33 | 33 | ||
| 34 | /* Protect struct usb_device->state and ->children members | 34 | /* Protect struct usb_device->state and ->children members |
| 35 | * Note: Both are also protected by ->serialize, except that ->state can | 35 | * Note: Both are also protected by ->dev.sem, except that ->state can |
| 36 | * change to USB_STATE_NOTATTACHED even when the semaphore isn't held. */ | 36 | * change to USB_STATE_NOTATTACHED even when the semaphore isn't held. */ |
| 37 | static DEFINE_SPINLOCK(device_state_lock); | 37 | static DEFINE_SPINLOCK(device_state_lock); |
| 38 | 38 | ||
| @@ -515,6 +515,31 @@ static int hub_port_disable(struct usb_hub *hub, int port1, int set_state) | |||
| 515 | return ret; | 515 | return ret; |
| 516 | } | 516 | } |
| 517 | 517 | ||
| 518 | |||
| 519 | /* caller has locked the hub device */ | ||
| 520 | static void hub_pre_reset(struct usb_hub *hub, int disable_ports) | ||
| 521 | { | ||
| 522 | struct usb_device *hdev = hub->hdev; | ||
| 523 | int port1; | ||
| 524 | |||
| 525 | for (port1 = 1; port1 <= hdev->maxchild; ++port1) { | ||
| 526 | if (hdev->children[port1 - 1]) { | ||
| 527 | usb_disconnect(&hdev->children[port1 - 1]); | ||
| 528 | if (disable_ports) | ||
| 529 | hub_port_disable(hub, port1, 0); | ||
| 530 | } | ||
| 531 | } | ||
| 532 | hub_quiesce(hub); | ||
| 533 | } | ||
| 534 | |||
| 535 | /* caller has locked the hub device */ | ||
| 536 | static void hub_post_reset(struct usb_hub *hub) | ||
| 537 | { | ||
| 538 | hub_activate(hub); | ||
| 539 | hub_power_on(hub); | ||
| 540 | } | ||
| 541 | |||
| 542 | |||
| 518 | static int hub_configure(struct usb_hub *hub, | 543 | static int hub_configure(struct usb_hub *hub, |
| 519 | struct usb_endpoint_descriptor *endpoint) | 544 | struct usb_endpoint_descriptor *endpoint) |
| 520 | { | 545 | { |
| @@ -677,26 +702,40 @@ static int hub_configure(struct usb_hub *hub, | |||
| 677 | * and battery-powered root hubs (may provide just 8 mA). | 702 | * and battery-powered root hubs (may provide just 8 mA). |
| 678 | */ | 703 | */ |
| 679 | ret = usb_get_status(hdev, USB_RECIP_DEVICE, 0, &hubstatus); | 704 | ret = usb_get_status(hdev, USB_RECIP_DEVICE, 0, &hubstatus); |
| 680 | if (ret < 0) { | 705 | if (ret < 2) { |
| 681 | message = "can't get hub status"; | 706 | message = "can't get hub status"; |
| 682 | goto fail; | 707 | goto fail; |
| 683 | } | 708 | } |
| 684 | le16_to_cpus(&hubstatus); | 709 | le16_to_cpus(&hubstatus); |
| 685 | if (hdev == hdev->bus->root_hub) { | 710 | if (hdev == hdev->bus->root_hub) { |
| 686 | struct usb_hcd *hcd = | 711 | if (hdev->bus_mA == 0 || hdev->bus_mA >= 500) |
| 687 | container_of(hdev->bus, struct usb_hcd, self); | 712 | hub->mA_per_port = 500; |
| 688 | 713 | else { | |
| 689 | hub->power_budget = min(500u, hcd->power_budget) / 2; | 714 | hub->mA_per_port = hdev->bus_mA; |
| 715 | hub->limited_power = 1; | ||
| 716 | } | ||
| 690 | } else if ((hubstatus & (1 << USB_DEVICE_SELF_POWERED)) == 0) { | 717 | } else if ((hubstatus & (1 << USB_DEVICE_SELF_POWERED)) == 0) { |
| 691 | dev_dbg(hub_dev, "hub controller current requirement: %dmA\n", | 718 | dev_dbg(hub_dev, "hub controller current requirement: %dmA\n", |
| 692 | hub->descriptor->bHubContrCurrent); | 719 | hub->descriptor->bHubContrCurrent); |
| 693 | hub->power_budget = (501 - hub->descriptor->bHubContrCurrent) | 720 | hub->limited_power = 1; |
| 694 | / 2; | 721 | if (hdev->maxchild > 0) { |
| 722 | int remaining = hdev->bus_mA - | ||
| 723 | hub->descriptor->bHubContrCurrent; | ||
| 724 | |||
| 725 | if (remaining < hdev->maxchild * 100) | ||
| 726 | dev_warn(hub_dev, | ||
| 727 | "insufficient power available " | ||
| 728 | "to use all downstream ports\n"); | ||
| 729 | hub->mA_per_port = 100; /* 7.2.1.1 */ | ||
| 730 | } | ||
| 731 | } else { /* Self-powered external hub */ | ||
| 732 | /* FIXME: What about battery-powered external hubs that | ||
| 733 | * provide less current per port? */ | ||
| 734 | hub->mA_per_port = 500; | ||
| 695 | } | 735 | } |
| 696 | if (hub->power_budget) | 736 | if (hub->mA_per_port < 500) |
| 697 | dev_dbg(hub_dev, "%dmA bus power budget for children\n", | 737 | dev_dbg(hub_dev, "%umA bus power budget for each child\n", |
| 698 | hub->power_budget * 2); | 738 | hub->mA_per_port); |
| 699 | |||
| 700 | 739 | ||
| 701 | ret = hub_hub_status(hub, &hubstatus, &hubchange); | 740 | ret = hub_hub_status(hub, &hubstatus, &hubchange); |
| 702 | if (ret < 0) { | 741 | if (ret < 0) { |
| @@ -750,29 +789,10 @@ fail: | |||
| 750 | 789 | ||
| 751 | static unsigned highspeed_hubs; | 790 | static unsigned highspeed_hubs; |
| 752 | 791 | ||
| 753 | /* Called after the hub driver is unbound from a hub with children */ | ||
| 754 | static void hub_remove_children_work(void *__hub) | ||
| 755 | { | ||
| 756 | struct usb_hub *hub = __hub; | ||
| 757 | struct usb_device *hdev = hub->hdev; | ||
| 758 | int i; | ||
| 759 | |||
| 760 | kfree(hub); | ||
| 761 | |||
| 762 | usb_lock_device(hdev); | ||
| 763 | for (i = 0; i < hdev->maxchild; ++i) { | ||
| 764 | if (hdev->children[i]) | ||
| 765 | usb_disconnect(&hdev->children[i]); | ||
| 766 | } | ||
| 767 | usb_unlock_device(hdev); | ||
| 768 | usb_put_dev(hdev); | ||
| 769 | } | ||
| 770 | |||
| 771 | static void hub_disconnect(struct usb_interface *intf) | 792 | static void hub_disconnect(struct usb_interface *intf) |
| 772 | { | 793 | { |
| 773 | struct usb_hub *hub = usb_get_intfdata (intf); | 794 | struct usb_hub *hub = usb_get_intfdata (intf); |
| 774 | struct usb_device *hdev; | 795 | struct usb_device *hdev; |
| 775 | int n, port1; | ||
| 776 | 796 | ||
| 777 | usb_set_intfdata (intf, NULL); | 797 | usb_set_intfdata (intf, NULL); |
| 778 | hdev = hub->hdev; | 798 | hdev = hub->hdev; |
| @@ -780,7 +800,9 @@ static void hub_disconnect(struct usb_interface *intf) | |||
| 780 | if (hdev->speed == USB_SPEED_HIGH) | 800 | if (hdev->speed == USB_SPEED_HIGH) |
| 781 | highspeed_hubs--; | 801 | highspeed_hubs--; |
| 782 | 802 | ||
| 783 | hub_quiesce(hub); | 803 | /* Disconnect all children and quiesce the hub */ |
| 804 | hub_pre_reset(hub, 1); | ||
| 805 | |||
| 784 | usb_free_urb(hub->urb); | 806 | usb_free_urb(hub->urb); |
| 785 | hub->urb = NULL; | 807 | hub->urb = NULL; |
| 786 | 808 | ||
| @@ -800,27 +822,7 @@ static void hub_disconnect(struct usb_interface *intf) | |||
| 800 | hub->buffer = NULL; | 822 | hub->buffer = NULL; |
| 801 | } | 823 | } |
| 802 | 824 | ||
| 803 | /* If there are any children then this is an unbind only, not a | 825 | kfree(hub); |
| 804 | * physical disconnection. The active ports must be disabled | ||
| 805 | * and later on we must call usb_disconnect(). We can't call | ||
| 806 | * it now because we may not hold the hub's device lock. | ||
| 807 | */ | ||
| 808 | n = 0; | ||
| 809 | for (port1 = 1; port1 <= hdev->maxchild; ++port1) { | ||
| 810 | if (hdev->children[port1 - 1]) { | ||
| 811 | ++n; | ||
| 812 | hub_port_disable(hub, port1, 1); | ||
| 813 | } | ||
| 814 | } | ||
| 815 | |||
| 816 | if (n == 0) | ||
| 817 | kfree(hub); | ||
| 818 | else { | ||
| 819 | /* Reuse the hub->leds work_struct for our own purposes */ | ||
| 820 | INIT_WORK(&hub->leds, hub_remove_children_work, hub); | ||
| 821 | schedule_work(&hub->leds); | ||
| 822 | usb_get_dev(hdev); | ||
| 823 | } | ||
| 824 | } | 826 | } |
| 825 | 827 | ||
| 826 | static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) | 828 | static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) |
| @@ -917,26 +919,6 @@ hub_ioctl(struct usb_interface *intf, unsigned int code, void *user_data) | |||
| 917 | } | 919 | } |
| 918 | } | 920 | } |
| 919 | 921 | ||
| 920 | /* caller has locked the hub device */ | ||
| 921 | static void hub_pre_reset(struct usb_hub *hub) | ||
| 922 | { | ||
| 923 | struct usb_device *hdev = hub->hdev; | ||
| 924 | int i; | ||
| 925 | |||
| 926 | for (i = 0; i < hdev->maxchild; ++i) { | ||
| 927 | if (hdev->children[i]) | ||
| 928 | usb_disconnect(&hdev->children[i]); | ||
| 929 | } | ||
| 930 | hub_quiesce(hub); | ||
| 931 | } | ||
| 932 | |||
| 933 | /* caller has locked the hub device */ | ||
| 934 | static void hub_post_reset(struct usb_hub *hub) | ||
| 935 | { | ||
| 936 | hub_activate(hub); | ||
| 937 | hub_power_on(hub); | ||
| 938 | } | ||
| 939 | |||
| 940 | 922 | ||
| 941 | /* grab device/port lock, returning index of that port (zero based). | 923 | /* grab device/port lock, returning index of that port (zero based). |
| 942 | * protects the upstream link used by this device from concurrent | 924 | * protects the upstream link used by this device from concurrent |
| @@ -964,24 +946,21 @@ static int locktree(struct usb_device *udev) | |||
| 964 | t = locktree(hdev); | 946 | t = locktree(hdev); |
| 965 | if (t < 0) | 947 | if (t < 0) |
| 966 | return t; | 948 | return t; |
| 967 | for (t = 0; t < hdev->maxchild; t++) { | ||
| 968 | if (hdev->children[t] == udev) { | ||
| 969 | /* everything is fail-fast once disconnect | ||
| 970 | * processing starts | ||
| 971 | */ | ||
| 972 | if (udev->state == USB_STATE_NOTATTACHED) | ||
| 973 | break; | ||
| 974 | 949 | ||
| 975 | /* when everyone grabs locks top->bottom, | 950 | /* everything is fail-fast once disconnect |
| 976 | * non-overlapping work may be concurrent | 951 | * processing starts |
| 977 | */ | 952 | */ |
| 978 | down(&udev->serialize); | 953 | if (udev->state == USB_STATE_NOTATTACHED) { |
| 979 | up(&hdev->serialize); | 954 | usb_unlock_device(hdev); |
| 980 | return t + 1; | 955 | return -ENODEV; |
| 981 | } | ||
| 982 | } | 956 | } |
| 957 | |||
| 958 | /* when everyone grabs locks top->bottom, | ||
| 959 | * non-overlapping work may be concurrent | ||
| 960 | */ | ||
| 961 | usb_lock_device(udev); | ||
| 983 | usb_unlock_device(hdev); | 962 | usb_unlock_device(hdev); |
| 984 | return -ENODEV; | 963 | return udev->portnum; |
| 985 | } | 964 | } |
| 986 | 965 | ||
| 987 | static void recursively_mark_NOTATTACHED(struct usb_device *udev) | 966 | static void recursively_mark_NOTATTACHED(struct usb_device *udev) |
| @@ -1039,6 +1018,39 @@ void usb_set_device_state(struct usb_device *udev, | |||
| 1039 | EXPORT_SYMBOL(usb_set_device_state); | 1018 | EXPORT_SYMBOL(usb_set_device_state); |
| 1040 | 1019 | ||
| 1041 | 1020 | ||
| 1021 | #ifdef CONFIG_PM | ||
| 1022 | |||
| 1023 | /** | ||
| 1024 | * usb_root_hub_lost_power - called by HCD if the root hub lost Vbus power | ||
| 1025 | * @rhdev: struct usb_device for the root hub | ||
| 1026 | * | ||
| 1027 | * The USB host controller driver calls this function when its root hub | ||
| 1028 | * is resumed and Vbus power has been interrupted or the controller | ||
| 1029 | * has been reset. The routine marks all the children of the root hub | ||
| 1030 | * as NOTATTACHED and marks logical connect-change events on their ports. | ||
| 1031 | */ | ||
| 1032 | void usb_root_hub_lost_power(struct usb_device *rhdev) | ||
| 1033 | { | ||
| 1034 | struct usb_hub *hub; | ||
| 1035 | int port1; | ||
| 1036 | unsigned long flags; | ||
| 1037 | |||
| 1038 | dev_warn(&rhdev->dev, "root hub lost power or was reset\n"); | ||
| 1039 | spin_lock_irqsave(&device_state_lock, flags); | ||
| 1040 | hub = hdev_to_hub(rhdev); | ||
| 1041 | for (port1 = 1; port1 <= rhdev->maxchild; ++port1) { | ||
| 1042 | if (rhdev->children[port1 - 1]) { | ||
| 1043 | recursively_mark_NOTATTACHED( | ||
| 1044 | rhdev->children[port1 - 1]); | ||
| 1045 | set_bit(port1, hub->change_bits); | ||
| 1046 | } | ||
| 1047 | } | ||
| 1048 | spin_unlock_irqrestore(&device_state_lock, flags); | ||
| 1049 | } | ||
| 1050 | EXPORT_SYMBOL_GPL(usb_root_hub_lost_power); | ||
| 1051 | |||
| 1052 | #endif | ||
| 1053 | |||
| 1042 | static void choose_address(struct usb_device *udev) | 1054 | static void choose_address(struct usb_device *udev) |
| 1043 | { | 1055 | { |
| 1044 | int devnum; | 1056 | int devnum; |
| @@ -1099,16 +1111,10 @@ void usb_disconnect(struct usb_device **pdev) | |||
| 1099 | * this quiesces everyting except pending urbs. | 1111 | * this quiesces everyting except pending urbs. |
| 1100 | */ | 1112 | */ |
| 1101 | usb_set_device_state(udev, USB_STATE_NOTATTACHED); | 1113 | usb_set_device_state(udev, USB_STATE_NOTATTACHED); |
| 1102 | |||
| 1103 | /* lock the bus list on behalf of HCDs unregistering their root hubs */ | ||
| 1104 | if (!udev->parent) { | ||
| 1105 | down(&usb_bus_list_lock); | ||
| 1106 | usb_lock_device(udev); | ||
| 1107 | } else | ||
| 1108 | down(&udev->serialize); | ||
| 1109 | |||
| 1110 | dev_info (&udev->dev, "USB disconnect, address %d\n", udev->devnum); | 1114 | dev_info (&udev->dev, "USB disconnect, address %d\n", udev->devnum); |
| 1111 | 1115 | ||
| 1116 | usb_lock_device(udev); | ||
| 1117 | |||
| 1112 | /* Free up all the children before we remove this device */ | 1118 | /* Free up all the children before we remove this device */ |
| 1113 | for (i = 0; i < USB_MAXCHILDREN; i++) { | 1119 | for (i = 0; i < USB_MAXCHILDREN; i++) { |
| 1114 | if (udev->children[i]) | 1120 | if (udev->children[i]) |
| @@ -1136,54 +1142,112 @@ void usb_disconnect(struct usb_device **pdev) | |||
| 1136 | *pdev = NULL; | 1142 | *pdev = NULL; |
| 1137 | spin_unlock_irq(&device_state_lock); | 1143 | spin_unlock_irq(&device_state_lock); |
| 1138 | 1144 | ||
| 1139 | if (!udev->parent) { | 1145 | usb_unlock_device(udev); |
| 1140 | usb_unlock_device(udev); | ||
| 1141 | up(&usb_bus_list_lock); | ||
| 1142 | } else | ||
| 1143 | up(&udev->serialize); | ||
| 1144 | 1146 | ||
| 1145 | device_unregister(&udev->dev); | 1147 | device_unregister(&udev->dev); |
| 1146 | } | 1148 | } |
| 1147 | 1149 | ||
| 1150 | static inline const char *plural(int n) | ||
| 1151 | { | ||
| 1152 | return (n == 1 ? "" : "s"); | ||
| 1153 | } | ||
| 1154 | |||
| 1148 | static int choose_configuration(struct usb_device *udev) | 1155 | static int choose_configuration(struct usb_device *udev) |
| 1149 | { | 1156 | { |
| 1150 | int c, i; | 1157 | int i; |
| 1158 | u16 devstatus; | ||
| 1159 | int bus_powered; | ||
| 1160 | int num_configs; | ||
| 1161 | struct usb_host_config *c, *best; | ||
| 1162 | |||
| 1163 | /* If this fails, assume the device is bus-powered */ | ||
| 1164 | devstatus = 0; | ||
| 1165 | usb_get_status(udev, USB_RECIP_DEVICE, 0, &devstatus); | ||
| 1166 | le16_to_cpus(&devstatus); | ||
| 1167 | bus_powered = ((devstatus & (1 << USB_DEVICE_SELF_POWERED)) == 0); | ||
| 1168 | dev_dbg(&udev->dev, "device is %s-powered\n", | ||
| 1169 | bus_powered ? "bus" : "self"); | ||
| 1170 | |||
| 1171 | best = NULL; | ||
| 1172 | c = udev->config; | ||
| 1173 | num_configs = udev->descriptor.bNumConfigurations; | ||
| 1174 | for (i = 0; i < num_configs; (i++, c++)) { | ||
| 1175 | struct usb_interface_descriptor *desc = | ||
| 1176 | &c->intf_cache[0]->altsetting->desc; | ||
| 1177 | |||
| 1178 | /* | ||
| 1179 | * HP's USB bus-powered keyboard has only one configuration | ||
| 1180 | * and it claims to be self-powered; other devices may have | ||
| 1181 | * similar errors in their descriptors. If the next test | ||
| 1182 | * were allowed to execute, such configurations would always | ||
| 1183 | * be rejected and the devices would not work as expected. | ||
| 1184 | */ | ||
| 1185 | #if 0 | ||
| 1186 | /* Rule out self-powered configs for a bus-powered device */ | ||
| 1187 | if (bus_powered && (c->desc.bmAttributes & | ||
| 1188 | USB_CONFIG_ATT_SELFPOWER)) | ||
| 1189 | continue; | ||
| 1190 | #endif | ||
| 1151 | 1191 | ||
| 1152 | /* NOTE: this should interact with hub power budgeting */ | 1192 | /* |
| 1193 | * The next test may not be as effective as it should be. | ||
| 1194 | * Some hubs have errors in their descriptor, claiming | ||
| 1195 | * to be self-powered when they are really bus-powered. | ||
| 1196 | * We will overestimate the amount of current such hubs | ||
| 1197 | * make available for each port. | ||
| 1198 | * | ||
| 1199 | * This is a fairly benign sort of failure. It won't | ||
| 1200 | * cause us to reject configurations that we should have | ||
| 1201 | * accepted. | ||
| 1202 | */ | ||
| 1153 | 1203 | ||
| 1154 | c = udev->config[0].desc.bConfigurationValue; | 1204 | /* Rule out configs that draw too much bus current */ |
| 1155 | if (udev->descriptor.bNumConfigurations != 1) { | 1205 | if (c->desc.bMaxPower * 2 > udev->bus_mA) |
| 1156 | for (i = 0; i < udev->descriptor.bNumConfigurations; i++) { | 1206 | continue; |
| 1157 | struct usb_interface_descriptor *desc; | ||
| 1158 | 1207 | ||
| 1159 | /* heuristic: Linux is more likely to have class | 1208 | /* If the first config's first interface is COMM/2/0xff |
| 1160 | * drivers, so avoid vendor-specific interfaces. | 1209 | * (MSFT RNDIS), rule it out unless Linux has host-side |
| 1161 | */ | 1210 | * RNDIS support. */ |
| 1162 | desc = &udev->config[i].intf_cache[0] | 1211 | if (i == 0 && desc->bInterfaceClass == USB_CLASS_COMM |
| 1163 | ->altsetting->desc; | 1212 | && desc->bInterfaceSubClass == 2 |
| 1164 | if (desc->bInterfaceClass == USB_CLASS_VENDOR_SPEC) | 1213 | && desc->bInterfaceProtocol == 0xff) { |
| 1165 | continue; | 1214 | #ifndef CONFIG_USB_NET_RNDIS |
| 1166 | /* COMM/2/all is CDC ACM, except 0xff is MSFT RNDIS. | 1215 | continue; |
| 1167 | * MSFT needs this to be the first config; never use | 1216 | #else |
| 1168 | * it as the default unless Linux has host-side RNDIS. | 1217 | best = c; |
| 1169 | * A second config would ideally be CDC-Ethernet, but | 1218 | #endif |
| 1170 | * may instead be the "vendor specific" CDC subset | 1219 | } |
| 1171 | * long used by ARM Linux for sa1100 or pxa255. | 1220 | |
| 1172 | */ | 1221 | /* From the remaining configs, choose the first one whose |
| 1173 | if (desc->bInterfaceClass == USB_CLASS_COMM | 1222 | * first interface is for a non-vendor-specific class. |
| 1174 | && desc->bInterfaceSubClass == 2 | 1223 | * Reason: Linux is more likely to have a class driver |
| 1175 | && desc->bInterfaceProtocol == 0xff) { | 1224 | * than a vendor-specific driver. */ |
| 1176 | c = udev->config[1].desc.bConfigurationValue; | 1225 | else if (udev->descriptor.bDeviceClass != |
| 1177 | continue; | 1226 | USB_CLASS_VENDOR_SPEC && |
| 1178 | } | 1227 | desc->bInterfaceClass != |
| 1179 | c = udev->config[i].desc.bConfigurationValue; | 1228 | USB_CLASS_VENDOR_SPEC) { |
| 1229 | best = c; | ||
| 1180 | break; | 1230 | break; |
| 1181 | } | 1231 | } |
| 1232 | |||
| 1233 | /* If all the remaining configs are vendor-specific, | ||
| 1234 | * choose the first one. */ | ||
| 1235 | else if (!best) | ||
| 1236 | best = c; | ||
| 1237 | } | ||
| 1238 | |||
| 1239 | if (best) { | ||
| 1240 | i = best->desc.bConfigurationValue; | ||
| 1182 | dev_info(&udev->dev, | 1241 | dev_info(&udev->dev, |
| 1183 | "configuration #%d chosen from %d choices\n", | 1242 | "configuration #%d chosen from %d choice%s\n", |
| 1184 | c, udev->descriptor.bNumConfigurations); | 1243 | i, num_configs, plural(num_configs)); |
| 1244 | } else { | ||
| 1245 | i = -1; | ||
| 1246 | dev_warn(&udev->dev, | ||
| 1247 | "no configuration chosen from %d choice%s\n", | ||
| 1248 | num_configs, plural(num_configs)); | ||
| 1185 | } | 1249 | } |
| 1186 | return c; | 1250 | return i; |
| 1187 | } | 1251 | } |
| 1188 | 1252 | ||
| 1189 | #ifdef DEBUG | 1253 | #ifdef DEBUG |
| @@ -1210,8 +1274,8 @@ static inline void show_string(struct usb_device *udev, char *id, char *string) | |||
| 1210 | * | 1274 | * |
| 1211 | * This is called with devices which have been enumerated, but not yet | 1275 | * This is called with devices which have been enumerated, but not yet |
| 1212 | * configured. The device descriptor is available, but not descriptors | 1276 | * configured. The device descriptor is available, but not descriptors |
| 1213 | * for any device configuration. The caller must have locked udev and | 1277 | * for any device configuration. The caller must have locked either |
| 1214 | * either the parent hub (if udev is a normal device) or else the | 1278 | * the parent hub (if udev is a normal device) or else the |
| 1215 | * usb_bus_list_lock (if udev is a root hub). The parent's pointer to | 1279 | * usb_bus_list_lock (if udev is a root hub). The parent's pointer to |
| 1216 | * udev has already been installed, but udev is not yet visible through | 1280 | * udev has already been installed, but udev is not yet visible through |
| 1217 | * sysfs or other filesystem code. | 1281 | * sysfs or other filesystem code. |
| @@ -1221,8 +1285,7 @@ static inline void show_string(struct usb_device *udev, char *id, char *string) | |||
| 1221 | * | 1285 | * |
| 1222 | * This call is synchronous, and may not be used in an interrupt context. | 1286 | * This call is synchronous, and may not be used in an interrupt context. |
| 1223 | * | 1287 | * |
| 1224 | * Only the hub driver should ever call this; root hub registration | 1288 | * Only the hub driver or root-hub registrar should ever call this. |
| 1225 | * uses it indirectly. | ||
| 1226 | */ | 1289 | */ |
| 1227 | int usb_new_device(struct usb_device *udev) | 1290 | int usb_new_device(struct usb_device *udev) |
| 1228 | { | 1291 | { |
| @@ -1269,15 +1332,9 @@ int usb_new_device(struct usb_device *udev) | |||
| 1269 | le16_to_cpu(udev->config[0].desc.wTotalLength), | 1332 | le16_to_cpu(udev->config[0].desc.wTotalLength), |
| 1270 | USB_DT_OTG, (void **) &desc) == 0) { | 1333 | USB_DT_OTG, (void **) &desc) == 0) { |
| 1271 | if (desc->bmAttributes & USB_OTG_HNP) { | 1334 | if (desc->bmAttributes & USB_OTG_HNP) { |
| 1272 | unsigned port1; | 1335 | unsigned port1 = udev->portnum; |
| 1273 | struct usb_device *root = udev->parent; | 1336 | struct usb_device *root = udev->parent; |
| 1274 | 1337 | ||
| 1275 | for (port1 = 1; port1 <= root->maxchild; | ||
| 1276 | port1++) { | ||
| 1277 | if (root->children[port1-1] == udev) | ||
| 1278 | break; | ||
| 1279 | } | ||
| 1280 | |||
| 1281 | dev_info(&udev->dev, | 1338 | dev_info(&udev->dev, |
| 1282 | "Dual-Role OTG device on %sHNP port\n", | 1339 | "Dual-Role OTG device on %sHNP port\n", |
| 1283 | (port1 == bus->otg_port) | 1340 | (port1 == bus->otg_port) |
| @@ -1331,27 +1388,27 @@ int usb_new_device(struct usb_device *udev) | |||
| 1331 | } | 1388 | } |
| 1332 | usb_create_sysfs_dev_files (udev); | 1389 | usb_create_sysfs_dev_files (udev); |
| 1333 | 1390 | ||
| 1391 | usb_lock_device(udev); | ||
| 1392 | |||
| 1334 | /* choose and set the configuration. that registers the interfaces | 1393 | /* choose and set the configuration. that registers the interfaces |
| 1335 | * with the driver core, and lets usb device drivers bind to them. | 1394 | * with the driver core, and lets usb device drivers bind to them. |
| 1336 | */ | 1395 | */ |
| 1337 | c = choose_configuration(udev); | 1396 | c = choose_configuration(udev); |
| 1338 | if (c < 0) | 1397 | if (c >= 0) { |
| 1339 | dev_warn(&udev->dev, | ||
| 1340 | "can't choose an initial configuration\n"); | ||
| 1341 | else { | ||
| 1342 | err = usb_set_configuration(udev, c); | 1398 | err = usb_set_configuration(udev, c); |
| 1343 | if (err) { | 1399 | if (err) { |
| 1344 | dev_err(&udev->dev, "can't set config #%d, error %d\n", | 1400 | dev_err(&udev->dev, "can't set config #%d, error %d\n", |
| 1345 | c, err); | 1401 | c, err); |
| 1346 | usb_remove_sysfs_dev_files(udev); | 1402 | /* This need not be fatal. The user can try to |
| 1347 | device_del(&udev->dev); | 1403 | * set other configurations. */ |
| 1348 | goto fail; | ||
| 1349 | } | 1404 | } |
| 1350 | } | 1405 | } |
| 1351 | 1406 | ||
| 1352 | /* USB device state == configured ... usable */ | 1407 | /* USB device state == configured ... usable */ |
| 1353 | usb_notify_add_device(udev); | 1408 | usb_notify_add_device(udev); |
| 1354 | 1409 | ||
| 1410 | usb_unlock_device(udev); | ||
| 1411 | |||
| 1355 | return 0; | 1412 | return 0; |
| 1356 | 1413 | ||
| 1357 | fail: | 1414 | fail: |
| @@ -1654,15 +1711,9 @@ static int __usb_suspend_device (struct usb_device *udev, int port1) | |||
| 1654 | int usb_suspend_device(struct usb_device *udev) | 1711 | int usb_suspend_device(struct usb_device *udev) |
| 1655 | { | 1712 | { |
| 1656 | #ifdef CONFIG_USB_SUSPEND | 1713 | #ifdef CONFIG_USB_SUSPEND |
| 1657 | int port1, status; | 1714 | if (udev->state == USB_STATE_NOTATTACHED) |
| 1658 | 1715 | return -ENODEV; | |
| 1659 | port1 = locktree(udev); | 1716 | return __usb_suspend_device(udev, udev->portnum); |
| 1660 | if (port1 < 0) | ||
| 1661 | return port1; | ||
| 1662 | |||
| 1663 | status = __usb_suspend_device(udev, port1); | ||
| 1664 | usb_unlock_device(udev); | ||
| 1665 | return status; | ||
| 1666 | #else | 1717 | #else |
| 1667 | /* NOTE: udev->state unchanged, it's not lying ... */ | 1718 | /* NOTE: udev->state unchanged, it's not lying ... */ |
| 1668 | udev->dev.power.power_state = PMSG_SUSPEND; | 1719 | udev->dev.power.power_state = PMSG_SUSPEND; |
| @@ -1694,13 +1745,14 @@ static int finish_device_resume(struct usb_device *udev) | |||
| 1694 | usb_set_device_state(udev, udev->actconfig | 1745 | usb_set_device_state(udev, udev->actconfig |
| 1695 | ? USB_STATE_CONFIGURED | 1746 | ? USB_STATE_CONFIGURED |
| 1696 | : USB_STATE_ADDRESS); | 1747 | : USB_STATE_ADDRESS); |
| 1748 | udev->dev.power.power_state = PMSG_ON; | ||
| 1697 | 1749 | ||
| 1698 | /* 10.5.4.5 says be sure devices in the tree are still there. | 1750 | /* 10.5.4.5 says be sure devices in the tree are still there. |
| 1699 | * For now let's assume the device didn't go crazy on resume, | 1751 | * For now let's assume the device didn't go crazy on resume, |
| 1700 | * and device drivers will know about any resume quirks. | 1752 | * and device drivers will know about any resume quirks. |
| 1701 | */ | 1753 | */ |
| 1702 | status = usb_get_status(udev, USB_RECIP_DEVICE, 0, &devstatus); | 1754 | status = usb_get_status(udev, USB_RECIP_DEVICE, 0, &devstatus); |
| 1703 | if (status < 0) | 1755 | if (status < 2) |
| 1704 | dev_dbg(&udev->dev, | 1756 | dev_dbg(&udev->dev, |
| 1705 | "gone after usb resume? status %d\n", | 1757 | "gone after usb resume? status %d\n", |
| 1706 | status); | 1758 | status); |
| @@ -1709,7 +1761,7 @@ static int finish_device_resume(struct usb_device *udev) | |||
| 1709 | int (*resume)(struct device *); | 1761 | int (*resume)(struct device *); |
| 1710 | 1762 | ||
| 1711 | le16_to_cpus(&devstatus); | 1763 | le16_to_cpus(&devstatus); |
| 1712 | if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP) | 1764 | if ((devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)) |
| 1713 | && udev->parent) { | 1765 | && udev->parent) { |
| 1714 | status = usb_control_msg(udev, | 1766 | status = usb_control_msg(udev, |
| 1715 | usb_sndctrlpipe(udev, 0), | 1767 | usb_sndctrlpipe(udev, 0), |
| @@ -1729,8 +1781,14 @@ static int finish_device_resume(struct usb_device *udev) | |||
| 1729 | * may have a child resume event to deal with soon | 1781 | * may have a child resume event to deal with soon |
| 1730 | */ | 1782 | */ |
| 1731 | resume = udev->dev.bus->resume; | 1783 | resume = udev->dev.bus->resume; |
| 1732 | for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) | 1784 | for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { |
| 1733 | (void) resume(&udev->actconfig->interface[i]->dev); | 1785 | struct device *dev = |
| 1786 | &udev->actconfig->interface[i]->dev; | ||
| 1787 | |||
| 1788 | down(&dev->sem); | ||
| 1789 | (void) resume(dev); | ||
| 1790 | up(&dev->sem); | ||
| 1791 | } | ||
| 1734 | status = 0; | 1792 | status = 0; |
| 1735 | 1793 | ||
| 1736 | } else if (udev->devnum <= 0) { | 1794 | } else if (udev->devnum <= 0) { |
| @@ -1813,11 +1871,10 @@ hub_port_resume(struct usb_hub *hub, int port1, struct usb_device *udev) | |||
| 1813 | */ | 1871 | */ |
| 1814 | int usb_resume_device(struct usb_device *udev) | 1872 | int usb_resume_device(struct usb_device *udev) |
| 1815 | { | 1873 | { |
| 1816 | int port1, status; | 1874 | int status; |
| 1817 | 1875 | ||
| 1818 | port1 = locktree(udev); | 1876 | if (udev->state == USB_STATE_NOTATTACHED) |
| 1819 | if (port1 < 0) | 1877 | return -ENODEV; |
| 1820 | return port1; | ||
| 1821 | 1878 | ||
| 1822 | #ifdef CONFIG_USB_SUSPEND | 1879 | #ifdef CONFIG_USB_SUSPEND |
| 1823 | /* selective resume of one downstream hub-to-device port */ | 1880 | /* selective resume of one downstream hub-to-device port */ |
| @@ -1826,7 +1883,7 @@ int usb_resume_device(struct usb_device *udev) | |||
| 1826 | // NOTE swsusp may bork us, device state being wrong... | 1883 | // NOTE swsusp may bork us, device state being wrong... |
| 1827 | // NOTE this fails if parent is also suspended... | 1884 | // NOTE this fails if parent is also suspended... |
| 1828 | status = hub_port_resume(hdev_to_hub(udev->parent), | 1885 | status = hub_port_resume(hdev_to_hub(udev->parent), |
| 1829 | port1, udev); | 1886 | udev->portnum, udev); |
| 1830 | } else | 1887 | } else |
| 1831 | status = 0; | 1888 | status = 0; |
| 1832 | } else | 1889 | } else |
| @@ -1836,13 +1893,11 @@ int usb_resume_device(struct usb_device *udev) | |||
| 1836 | dev_dbg(&udev->dev, "can't resume, status %d\n", | 1893 | dev_dbg(&udev->dev, "can't resume, status %d\n", |
| 1837 | status); | 1894 | status); |
| 1838 | 1895 | ||
| 1839 | usb_unlock_device(udev); | ||
| 1840 | |||
| 1841 | /* rebind drivers that had no suspend() */ | 1896 | /* rebind drivers that had no suspend() */ |
| 1842 | if (status == 0) { | 1897 | if (status == 0) { |
| 1843 | usb_lock_all_devices(); | 1898 | usb_unlock_device(udev); |
| 1844 | bus_rescan_devices(&usb_bus_type); | 1899 | bus_rescan_devices(&usb_bus_type); |
| 1845 | usb_unlock_all_devices(); | 1900 | usb_lock_device(udev); |
| 1846 | } | 1901 | } |
| 1847 | return status; | 1902 | return status; |
| 1848 | } | 1903 | } |
| @@ -1856,14 +1911,14 @@ static int remote_wakeup(struct usb_device *udev) | |||
| 1856 | /* don't repeat RESUME sequence if this device | 1911 | /* don't repeat RESUME sequence if this device |
| 1857 | * was already woken up by some other task | 1912 | * was already woken up by some other task |
| 1858 | */ | 1913 | */ |
| 1859 | down(&udev->serialize); | 1914 | usb_lock_device(udev); |
| 1860 | if (udev->state == USB_STATE_SUSPENDED) { | 1915 | if (udev->state == USB_STATE_SUSPENDED) { |
| 1861 | dev_dbg(&udev->dev, "RESUME (wakeup)\n"); | 1916 | dev_dbg(&udev->dev, "RESUME (wakeup)\n"); |
| 1862 | /* TRSMRCY = 10 msec */ | 1917 | /* TRSMRCY = 10 msec */ |
| 1863 | msleep(10); | 1918 | msleep(10); |
| 1864 | status = finish_device_resume(udev); | 1919 | status = finish_device_resume(udev); |
| 1865 | } | 1920 | } |
| 1866 | up(&udev->serialize); | 1921 | usb_unlock_device(udev); |
| 1867 | #endif | 1922 | #endif |
| 1868 | return status; | 1923 | return status; |
| 1869 | } | 1924 | } |
| @@ -1964,7 +2019,7 @@ static int hub_resume(struct usb_interface *intf) | |||
| 1964 | 2019 | ||
| 1965 | if (!udev || status < 0) | 2020 | if (!udev || status < 0) |
| 1966 | continue; | 2021 | continue; |
| 1967 | down (&udev->serialize); | 2022 | usb_lock_device(udev); |
| 1968 | if (portstat & USB_PORT_STAT_SUSPEND) | 2023 | if (portstat & USB_PORT_STAT_SUSPEND) |
| 1969 | status = hub_port_resume(hub, port1, udev); | 2024 | status = hub_port_resume(hub, port1, udev); |
| 1970 | else { | 2025 | else { |
| @@ -1975,7 +2030,7 @@ static int hub_resume(struct usb_interface *intf) | |||
| 1975 | hub_port_logical_disconnect(hub, port1); | 2030 | hub_port_logical_disconnect(hub, port1); |
| 1976 | } | 2031 | } |
| 1977 | } | 2032 | } |
| 1978 | up(&udev->serialize); | 2033 | usb_unlock_device(udev); |
| 1979 | } | 2034 | } |
| 1980 | } | 2035 | } |
| 1981 | #endif | 2036 | #endif |
| @@ -2359,39 +2414,36 @@ hub_power_remaining (struct usb_hub *hub) | |||
| 2359 | { | 2414 | { |
| 2360 | struct usb_device *hdev = hub->hdev; | 2415 | struct usb_device *hdev = hub->hdev; |
| 2361 | int remaining; | 2416 | int remaining; |
| 2362 | unsigned i; | 2417 | int port1; |
| 2363 | 2418 | ||
| 2364 | remaining = hub->power_budget; | 2419 | if (!hub->limited_power) |
| 2365 | if (!remaining) /* self-powered */ | ||
| 2366 | return 0; | 2420 | return 0; |
| 2367 | 2421 | ||
| 2368 | for (i = 0; i < hdev->maxchild; i++) { | 2422 | remaining = hdev->bus_mA - hub->descriptor->bHubContrCurrent; |
| 2369 | struct usb_device *udev = hdev->children[i]; | 2423 | for (port1 = 1; port1 <= hdev->maxchild; ++port1) { |
| 2370 | int delta, ceiling; | 2424 | struct usb_device *udev = hdev->children[port1 - 1]; |
| 2425 | int delta; | ||
| 2371 | 2426 | ||
| 2372 | if (!udev) | 2427 | if (!udev) |
| 2373 | continue; | 2428 | continue; |
| 2374 | 2429 | ||
| 2375 | /* 100mA per-port ceiling, or 8mA for OTG ports */ | 2430 | /* Unconfigured devices may not use more than 100mA, |
| 2376 | if (i != (udev->bus->otg_port - 1) || hdev->parent) | 2431 | * or 8mA for OTG ports */ |
| 2377 | ceiling = 50; | ||
| 2378 | else | ||
| 2379 | ceiling = 4; | ||
| 2380 | |||
| 2381 | if (udev->actconfig) | 2432 | if (udev->actconfig) |
| 2382 | delta = udev->actconfig->desc.bMaxPower; | 2433 | delta = udev->actconfig->desc.bMaxPower * 2; |
| 2434 | else if (port1 != udev->bus->otg_port || hdev->parent) | ||
| 2435 | delta = 100; | ||
| 2383 | else | 2436 | else |
| 2384 | delta = ceiling; | 2437 | delta = 8; |
| 2385 | // dev_dbg(&udev->dev, "budgeted %dmA\n", 2 * delta); | 2438 | if (delta > hub->mA_per_port) |
| 2386 | if (delta > ceiling) | 2439 | dev_warn(&udev->dev, "%dmA is over %umA budget " |
| 2387 | dev_warn(&udev->dev, "%dmA over %dmA budget!\n", | 2440 | "for port %d!\n", |
| 2388 | 2 * (delta - ceiling), 2 * ceiling); | 2441 | delta, hub->mA_per_port, port1); |
| 2389 | remaining -= delta; | 2442 | remaining -= delta; |
| 2390 | } | 2443 | } |
| 2391 | if (remaining < 0) { | 2444 | if (remaining < 0) { |
| 2392 | dev_warn(hub->intfdev, | 2445 | dev_warn(hub->intfdev, "%dmA over power budget!\n", |
| 2393 | "%dmA over power budget!\n", | 2446 | - remaining); |
| 2394 | -2 * remaining); | ||
| 2395 | remaining = 0; | 2447 | remaining = 0; |
| 2396 | } | 2448 | } |
| 2397 | return remaining; | 2449 | return remaining; |
| @@ -2486,7 +2538,8 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, | |||
| 2486 | 2538 | ||
| 2487 | usb_set_device_state(udev, USB_STATE_POWERED); | 2539 | usb_set_device_state(udev, USB_STATE_POWERED); |
| 2488 | udev->speed = USB_SPEED_UNKNOWN; | 2540 | udev->speed = USB_SPEED_UNKNOWN; |
| 2489 | 2541 | udev->bus_mA = hub->mA_per_port; | |
| 2542 | |||
| 2490 | /* set the address */ | 2543 | /* set the address */ |
| 2491 | choose_address(udev); | 2544 | choose_address(udev); |
| 2492 | if (udev->devnum <= 0) { | 2545 | if (udev->devnum <= 0) { |
| @@ -2506,16 +2559,16 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, | |||
| 2506 | * on the parent. | 2559 | * on the parent. |
| 2507 | */ | 2560 | */ |
| 2508 | if (udev->descriptor.bDeviceClass == USB_CLASS_HUB | 2561 | if (udev->descriptor.bDeviceClass == USB_CLASS_HUB |
| 2509 | && hub->power_budget) { | 2562 | && udev->bus_mA <= 100) { |
| 2510 | u16 devstat; | 2563 | u16 devstat; |
| 2511 | 2564 | ||
| 2512 | status = usb_get_status(udev, USB_RECIP_DEVICE, 0, | 2565 | status = usb_get_status(udev, USB_RECIP_DEVICE, 0, |
| 2513 | &devstat); | 2566 | &devstat); |
| 2514 | if (status < 0) { | 2567 | if (status < 2) { |
| 2515 | dev_dbg(&udev->dev, "get status %d ?\n", status); | 2568 | dev_dbg(&udev->dev, "get status %d ?\n", status); |
| 2516 | goto loop_disable; | 2569 | goto loop_disable; |
| 2517 | } | 2570 | } |
| 2518 | cpu_to_le16s(&devstat); | 2571 | le16_to_cpus(&devstat); |
| 2519 | if ((devstat & (1 << USB_DEVICE_SELF_POWERED)) == 0) { | 2572 | if ((devstat & (1 << USB_DEVICE_SELF_POWERED)) == 0) { |
| 2520 | dev_err(&udev->dev, | 2573 | dev_err(&udev->dev, |
| 2521 | "can't connect bus-powered hub " | 2574 | "can't connect bus-powered hub " |
| @@ -2540,7 +2593,6 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, | |||
| 2540 | * udev becomes globally accessible, although presumably | 2593 | * udev becomes globally accessible, although presumably |
| 2541 | * no one will look at it until hdev is unlocked. | 2594 | * no one will look at it until hdev is unlocked. |
| 2542 | */ | 2595 | */ |
| 2543 | down (&udev->serialize); | ||
| 2544 | status = 0; | 2596 | status = 0; |
| 2545 | 2597 | ||
| 2546 | /* We mustn't add new devices if the parent hub has | 2598 | /* We mustn't add new devices if the parent hub has |
| @@ -2564,15 +2616,12 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, | |||
| 2564 | } | 2616 | } |
| 2565 | } | 2617 | } |
| 2566 | 2618 | ||
| 2567 | up (&udev->serialize); | ||
| 2568 | if (status) | 2619 | if (status) |
| 2569 | goto loop_disable; | 2620 | goto loop_disable; |
| 2570 | 2621 | ||
| 2571 | status = hub_power_remaining(hub); | 2622 | status = hub_power_remaining(hub); |
| 2572 | if (status) | 2623 | if (status) |
| 2573 | dev_dbg(hub_dev, | 2624 | dev_dbg(hub_dev, "%dmA power budget left\n", status); |
| 2574 | "%dmA power budget left\n", | ||
| 2575 | 2 * status); | ||
| 2576 | 2625 | ||
| 2577 | return; | 2626 | return; |
| 2578 | 2627 | ||
| @@ -2648,6 +2697,8 @@ static void hub_events(void) | |||
| 2648 | if (i) { | 2697 | if (i) { |
| 2649 | dpm_runtime_resume(&hdev->dev); | 2698 | dpm_runtime_resume(&hdev->dev); |
| 2650 | dpm_runtime_resume(&intf->dev); | 2699 | dpm_runtime_resume(&intf->dev); |
| 2700 | usb_put_intf(intf); | ||
| 2701 | continue; | ||
| 2651 | } | 2702 | } |
| 2652 | 2703 | ||
| 2653 | /* Lock the device, then check to see if we were | 2704 | /* Lock the device, then check to see if we were |
| @@ -2661,7 +2712,7 @@ static void hub_events(void) | |||
| 2661 | 2712 | ||
| 2662 | /* If the hub has died, clean up after it */ | 2713 | /* If the hub has died, clean up after it */ |
| 2663 | if (hdev->state == USB_STATE_NOTATTACHED) { | 2714 | if (hdev->state == USB_STATE_NOTATTACHED) { |
| 2664 | hub_pre_reset(hub); | 2715 | hub_pre_reset(hub, 0); |
| 2665 | goto loop; | 2716 | goto loop; |
| 2666 | } | 2717 | } |
| 2667 | 2718 | ||
| @@ -2784,6 +2835,11 @@ static void hub_events(void) | |||
| 2784 | if (hubchange & HUB_CHANGE_LOCAL_POWER) { | 2835 | if (hubchange & HUB_CHANGE_LOCAL_POWER) { |
| 2785 | dev_dbg (hub_dev, "power change\n"); | 2836 | dev_dbg (hub_dev, "power change\n"); |
| 2786 | clear_hub_feature(hdev, C_HUB_LOCAL_POWER); | 2837 | clear_hub_feature(hdev, C_HUB_LOCAL_POWER); |
| 2838 | if (hubstatus & HUB_STATUS_LOCAL_POWER) | ||
| 2839 | /* FIXME: Is this always true? */ | ||
| 2840 | hub->limited_power = 0; | ||
| 2841 | else | ||
| 2842 | hub->limited_power = 1; | ||
| 2787 | } | 2843 | } |
| 2788 | if (hubchange & HUB_CHANGE_OVERCURRENT) { | 2844 | if (hubchange & HUB_CHANGE_OVERCURRENT) { |
| 2789 | dev_dbg (hub_dev, "overcurrent change\n"); | 2845 | dev_dbg (hub_dev, "overcurrent change\n"); |
| @@ -2832,7 +2888,6 @@ static struct usb_device_id hub_id_table [] = { | |||
| 2832 | MODULE_DEVICE_TABLE (usb, hub_id_table); | 2888 | MODULE_DEVICE_TABLE (usb, hub_id_table); |
| 2833 | 2889 | ||
| 2834 | static struct usb_driver hub_driver = { | 2890 | static struct usb_driver hub_driver = { |
| 2835 | .owner = THIS_MODULE, | ||
| 2836 | .name = "hub", | 2891 | .name = "hub", |
| 2837 | .probe = hub_probe, | 2892 | .probe = hub_probe, |
| 2838 | .disconnect = hub_disconnect, | 2893 | .disconnect = hub_disconnect, |
| @@ -2944,7 +2999,8 @@ int usb_reset_device(struct usb_device *udev) | |||
| 2944 | struct usb_hub *parent_hub; | 2999 | struct usb_hub *parent_hub; |
| 2945 | struct usb_device_descriptor descriptor = udev->descriptor; | 3000 | struct usb_device_descriptor descriptor = udev->descriptor; |
| 2946 | struct usb_hub *hub = NULL; | 3001 | struct usb_hub *hub = NULL; |
| 2947 | int i, ret = 0, port1 = -1; | 3002 | int i, ret = 0; |
| 3003 | int port1 = udev->portnum; | ||
| 2948 | 3004 | ||
| 2949 | if (udev->state == USB_STATE_NOTATTACHED || | 3005 | if (udev->state == USB_STATE_NOTATTACHED || |
| 2950 | udev->state == USB_STATE_SUSPENDED) { | 3006 | udev->state == USB_STATE_SUSPENDED) { |
| @@ -2958,18 +3014,6 @@ int usb_reset_device(struct usb_device *udev) | |||
| 2958 | dev_dbg(&udev->dev, "%s for root hub!\n", __FUNCTION__); | 3014 | dev_dbg(&udev->dev, "%s for root hub!\n", __FUNCTION__); |
| 2959 | return -EISDIR; | 3015 | return -EISDIR; |
| 2960 | } | 3016 | } |
| 2961 | |||
| 2962 | for (i = 0; i < parent_hdev->maxchild; i++) | ||
| 2963 | if (parent_hdev->children[i] == udev) { | ||
| 2964 | port1 = i + 1; | ||
| 2965 | break; | ||
| 2966 | } | ||
| 2967 | |||
| 2968 | if (port1 < 0) { | ||
| 2969 | /* If this ever happens, it's very bad */ | ||
| 2970 | dev_err(&udev->dev, "Can't locate device's port!\n"); | ||
| 2971 | return -ENOENT; | ||
| 2972 | } | ||
| 2973 | parent_hub = hdev_to_hub(parent_hdev); | 3017 | parent_hub = hdev_to_hub(parent_hdev); |
| 2974 | 3018 | ||
| 2975 | /* If we're resetting an active hub, take some special actions */ | 3019 | /* If we're resetting an active hub, take some special actions */ |
| @@ -2977,7 +3021,7 @@ int usb_reset_device(struct usb_device *udev) | |||
| 2977 | udev->actconfig->interface[0]->dev.driver == | 3021 | udev->actconfig->interface[0]->dev.driver == |
| 2978 | &hub_driver.driver && | 3022 | &hub_driver.driver && |
| 2979 | (hub = hdev_to_hub(udev)) != NULL) { | 3023 | (hub = hdev_to_hub(udev)) != NULL) { |
| 2980 | hub_pre_reset(hub); | 3024 | hub_pre_reset(hub, 0); |
| 2981 | } | 3025 | } |
| 2982 | 3026 | ||
| 2983 | set_bit(port1, parent_hub->busy_bits); | 3027 | set_bit(port1, parent_hub->busy_bits); |
diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h index bf23f8978024..29d5f45a8456 100644 --- a/drivers/usb/core/hub.h +++ b/drivers/usb/core/hub.h | |||
| @@ -220,8 +220,9 @@ struct usb_hub { | |||
| 220 | struct usb_hub_descriptor *descriptor; /* class descriptor */ | 220 | struct usb_hub_descriptor *descriptor; /* class descriptor */ |
| 221 | struct usb_tt tt; /* Transaction Translator */ | 221 | struct usb_tt tt; /* Transaction Translator */ |
| 222 | 222 | ||
| 223 | u8 power_budget; /* in 2mA units; or zero */ | 223 | unsigned mA_per_port; /* current for each child */ |
| 224 | 224 | ||
| 225 | unsigned limited_power:1; | ||
| 225 | unsigned quiescing:1; | 226 | unsigned quiescing:1; |
| 226 | unsigned activating:1; | 227 | unsigned activating:1; |
| 227 | unsigned resume_root_hub:1; | 228 | unsigned resume_root_hub:1; |
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index fe74f99ca5f4..319de03944e7 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
| @@ -1387,6 +1387,12 @@ free_interfaces: | |||
| 1387 | if (dev->state != USB_STATE_ADDRESS) | 1387 | if (dev->state != USB_STATE_ADDRESS) |
| 1388 | usb_disable_device (dev, 1); // Skip ep0 | 1388 | usb_disable_device (dev, 1); // Skip ep0 |
| 1389 | 1389 | ||
| 1390 | i = dev->bus_mA - cp->desc.bMaxPower * 2; | ||
| 1391 | if (i < 0) | ||
| 1392 | dev_warn(&dev->dev, "new config #%d exceeds power " | ||
| 1393 | "limit by %dmA\n", | ||
| 1394 | configuration, -i); | ||
| 1395 | |||
| 1390 | if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | 1396 | if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), |
| 1391 | USB_REQ_SET_CONFIGURATION, 0, configuration, 0, | 1397 | USB_REQ_SET_CONFIGURATION, 0, configuration, 0, |
| 1392 | NULL, 0, USB_CTRL_SET_TIMEOUT)) < 0) | 1398 | NULL, 0, USB_CTRL_SET_TIMEOUT)) < 0) |
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index e80ef9467825..56a3520863a9 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
| @@ -32,7 +32,6 @@ | |||
| 32 | #include <linux/spinlock.h> | 32 | #include <linux/spinlock.h> |
| 33 | #include <linux/errno.h> | 33 | #include <linux/errno.h> |
| 34 | #include <linux/smp_lock.h> | 34 | #include <linux/smp_lock.h> |
| 35 | #include <linux/rwsem.h> | ||
| 36 | #include <linux/usb.h> | 35 | #include <linux/usb.h> |
| 37 | 36 | ||
| 38 | #include <asm/io.h> | 37 | #include <asm/io.h> |
| @@ -47,165 +46,7 @@ | |||
| 47 | const char *usbcore_name = "usbcore"; | 46 | const char *usbcore_name = "usbcore"; |
| 48 | 47 | ||
| 49 | static int nousb; /* Disable USB when built into kernel image */ | 48 | static int nousb; /* Disable USB when built into kernel image */ |
| 50 | /* Not honored on modular build */ | ||
| 51 | 49 | ||
| 52 | static DECLARE_RWSEM(usb_all_devices_rwsem); | ||
| 53 | |||
| 54 | |||
| 55 | static int generic_probe (struct device *dev) | ||
| 56 | { | ||
| 57 | return 0; | ||
| 58 | } | ||
| 59 | static int generic_remove (struct device *dev) | ||
| 60 | { | ||
| 61 | struct usb_device *udev = to_usb_device(dev); | ||
| 62 | |||
| 63 | /* if this is only an unbind, not a physical disconnect, then | ||
| 64 | * unconfigure the device */ | ||
| 65 | if (udev->state == USB_STATE_CONFIGURED) | ||
| 66 | usb_set_configuration(udev, 0); | ||
| 67 | |||
| 68 | /* in case the call failed or the device was suspended */ | ||
| 69 | if (udev->state >= USB_STATE_CONFIGURED) | ||
| 70 | usb_disable_device(udev, 0); | ||
| 71 | return 0; | ||
| 72 | } | ||
| 73 | |||
| 74 | static struct device_driver usb_generic_driver = { | ||
| 75 | .owner = THIS_MODULE, | ||
| 76 | .name = "usb", | ||
| 77 | .bus = &usb_bus_type, | ||
| 78 | .probe = generic_probe, | ||
| 79 | .remove = generic_remove, | ||
| 80 | }; | ||
| 81 | |||
| 82 | static int usb_generic_driver_data; | ||
| 83 | |||
| 84 | /* called from driver core with usb_bus_type.subsys writelock */ | ||
| 85 | static int usb_probe_interface(struct device *dev) | ||
| 86 | { | ||
| 87 | struct usb_interface * intf = to_usb_interface(dev); | ||
| 88 | struct usb_driver * driver = to_usb_driver(dev->driver); | ||
| 89 | const struct usb_device_id *id; | ||
| 90 | int error = -ENODEV; | ||
| 91 | |||
| 92 | dev_dbg(dev, "%s\n", __FUNCTION__); | ||
| 93 | |||
| 94 | if (!driver->probe) | ||
| 95 | return error; | ||
| 96 | /* FIXME we'd much prefer to just resume it ... */ | ||
| 97 | if (interface_to_usbdev(intf)->state == USB_STATE_SUSPENDED) | ||
| 98 | return -EHOSTUNREACH; | ||
| 99 | |||
| 100 | id = usb_match_id (intf, driver->id_table); | ||
| 101 | if (id) { | ||
| 102 | dev_dbg (dev, "%s - got id\n", __FUNCTION__); | ||
| 103 | |||
| 104 | /* Interface "power state" doesn't correspond to any hardware | ||
| 105 | * state whatsoever. We use it to record when it's bound to | ||
| 106 | * a driver that may start I/0: it's not frozen/quiesced. | ||
| 107 | */ | ||
| 108 | mark_active(intf); | ||
| 109 | intf->condition = USB_INTERFACE_BINDING; | ||
| 110 | error = driver->probe (intf, id); | ||
| 111 | if (error) { | ||
| 112 | mark_quiesced(intf); | ||
| 113 | intf->condition = USB_INTERFACE_UNBOUND; | ||
| 114 | } else | ||
| 115 | intf->condition = USB_INTERFACE_BOUND; | ||
| 116 | } | ||
| 117 | |||
| 118 | return error; | ||
| 119 | } | ||
| 120 | |||
| 121 | /* called from driver core with usb_bus_type.subsys writelock */ | ||
| 122 | static int usb_unbind_interface(struct device *dev) | ||
| 123 | { | ||
| 124 | struct usb_interface *intf = to_usb_interface(dev); | ||
| 125 | struct usb_driver *driver = to_usb_driver(intf->dev.driver); | ||
| 126 | |||
| 127 | intf->condition = USB_INTERFACE_UNBINDING; | ||
| 128 | |||
| 129 | /* release all urbs for this interface */ | ||
| 130 | usb_disable_interface(interface_to_usbdev(intf), intf); | ||
| 131 | |||
| 132 | if (driver && driver->disconnect) | ||
| 133 | driver->disconnect(intf); | ||
| 134 | |||
| 135 | /* reset other interface state */ | ||
| 136 | usb_set_interface(interface_to_usbdev(intf), | ||
| 137 | intf->altsetting[0].desc.bInterfaceNumber, | ||
| 138 | 0); | ||
| 139 | usb_set_intfdata(intf, NULL); | ||
| 140 | intf->condition = USB_INTERFACE_UNBOUND; | ||
| 141 | mark_quiesced(intf); | ||
| 142 | |||
| 143 | return 0; | ||
| 144 | } | ||
| 145 | |||
| 146 | /** | ||
| 147 | * usb_register - register a USB driver | ||
| 148 | * @new_driver: USB operations for the driver | ||
| 149 | * | ||
| 150 | * Registers a USB driver with the USB core. The list of unattached | ||
| 151 | * interfaces will be rescanned whenever a new driver is added, allowing | ||
| 152 | * the new driver to attach to any recognized devices. | ||
| 153 | * Returns a negative error code on failure and 0 on success. | ||
| 154 | * | ||
| 155 | * NOTE: if you want your driver to use the USB major number, you must call | ||
| 156 | * usb_register_dev() to enable that functionality. This function no longer | ||
| 157 | * takes care of that. | ||
| 158 | */ | ||
| 159 | int usb_register(struct usb_driver *new_driver) | ||
| 160 | { | ||
| 161 | int retval = 0; | ||
| 162 | |||
| 163 | if (nousb) | ||
| 164 | return -ENODEV; | ||
| 165 | |||
| 166 | new_driver->driver.name = (char *)new_driver->name; | ||
| 167 | new_driver->driver.bus = &usb_bus_type; | ||
| 168 | new_driver->driver.probe = usb_probe_interface; | ||
| 169 | new_driver->driver.remove = usb_unbind_interface; | ||
| 170 | new_driver->driver.owner = new_driver->owner; | ||
| 171 | |||
| 172 | usb_lock_all_devices(); | ||
| 173 | retval = driver_register(&new_driver->driver); | ||
| 174 | usb_unlock_all_devices(); | ||
| 175 | |||
| 176 | if (!retval) { | ||
| 177 | pr_info("%s: registered new driver %s\n", | ||
| 178 | usbcore_name, new_driver->name); | ||
| 179 | usbfs_update_special(); | ||
| 180 | } else { | ||
| 181 | printk(KERN_ERR "%s: error %d registering driver %s\n", | ||
| 182 | usbcore_name, retval, new_driver->name); | ||
| 183 | } | ||
| 184 | |||
| 185 | return retval; | ||
| 186 | } | ||
| 187 | |||
| 188 | /** | ||
| 189 | * usb_deregister - unregister a USB driver | ||
| 190 | * @driver: USB operations of the driver to unregister | ||
| 191 | * Context: must be able to sleep | ||
| 192 | * | ||
| 193 | * Unlinks the specified driver from the internal USB driver list. | ||
| 194 | * | ||
| 195 | * NOTE: If you called usb_register_dev(), you still need to call | ||
| 196 | * usb_deregister_dev() to clean up your driver's allocated minor numbers, | ||
| 197 | * this * call will no longer do it for you. | ||
| 198 | */ | ||
| 199 | void usb_deregister(struct usb_driver *driver) | ||
| 200 | { | ||
| 201 | pr_info("%s: deregistering driver %s\n", usbcore_name, driver->name); | ||
| 202 | |||
| 203 | usb_lock_all_devices(); | ||
| 204 | driver_unregister (&driver->driver); | ||
| 205 | usb_unlock_all_devices(); | ||
| 206 | |||
| 207 | usbfs_update_special(); | ||
| 208 | } | ||
| 209 | 50 | ||
| 210 | /** | 51 | /** |
| 211 | * usb_ifnum_to_if - get the interface object with a given interface number | 52 | * usb_ifnum_to_if - get the interface object with a given interface number |
| @@ -351,152 +192,23 @@ void usb_driver_release_interface(struct usb_driver *driver, | |||
| 351 | iface->condition = USB_INTERFACE_UNBOUND; | 192 | iface->condition = USB_INTERFACE_UNBOUND; |
| 352 | mark_quiesced(iface); | 193 | mark_quiesced(iface); |
| 353 | } | 194 | } |
| 354 | 195 | struct find_interface_arg { | |
| 355 | /** | 196 | int minor; |
| 356 | * usb_match_id - find first usb_device_id matching device or interface | 197 | struct usb_interface *interface; |
| 357 | * @interface: the interface of interest | 198 | }; |
| 358 | * @id: array of usb_device_id structures, terminated by zero entry | ||
| 359 | * | ||
| 360 | * usb_match_id searches an array of usb_device_id's and returns | ||
| 361 | * the first one matching the device or interface, or null. | ||
| 362 | * This is used when binding (or rebinding) a driver to an interface. | ||
| 363 | * Most USB device drivers will use this indirectly, through the usb core, | ||
| 364 | * but some layered driver frameworks use it directly. | ||
| 365 | * These device tables are exported with MODULE_DEVICE_TABLE, through | ||
| 366 | * modutils and "modules.usbmap", to support the driver loading | ||
| 367 | * functionality of USB hotplugging. | ||
| 368 | * | ||
| 369 | * What Matches: | ||
| 370 | * | ||
| 371 | * The "match_flags" element in a usb_device_id controls which | ||
| 372 | * members are used. If the corresponding bit is set, the | ||
| 373 | * value in the device_id must match its corresponding member | ||
| 374 | * in the device or interface descriptor, or else the device_id | ||
| 375 | * does not match. | ||
| 376 | * | ||
| 377 | * "driver_info" is normally used only by device drivers, | ||
| 378 | * but you can create a wildcard "matches anything" usb_device_id | ||
| 379 | * as a driver's "modules.usbmap" entry if you provide an id with | ||
| 380 | * only a nonzero "driver_info" field. If you do this, the USB device | ||
| 381 | * driver's probe() routine should use additional intelligence to | ||
| 382 | * decide whether to bind to the specified interface. | ||
| 383 | * | ||
| 384 | * What Makes Good usb_device_id Tables: | ||
| 385 | * | ||
| 386 | * The match algorithm is very simple, so that intelligence in | ||
| 387 | * driver selection must come from smart driver id records. | ||
| 388 | * Unless you have good reasons to use another selection policy, | ||
| 389 | * provide match elements only in related groups, and order match | ||
| 390 | * specifiers from specific to general. Use the macros provided | ||
| 391 | * for that purpose if you can. | ||
| 392 | * | ||
| 393 | * The most specific match specifiers use device descriptor | ||
| 394 | * data. These are commonly used with product-specific matches; | ||
| 395 | * the USB_DEVICE macro lets you provide vendor and product IDs, | ||
| 396 | * and you can also match against ranges of product revisions. | ||
| 397 | * These are widely used for devices with application or vendor | ||
| 398 | * specific bDeviceClass values. | ||
| 399 | * | ||
| 400 | * Matches based on device class/subclass/protocol specifications | ||
| 401 | * are slightly more general; use the USB_DEVICE_INFO macro, or | ||
| 402 | * its siblings. These are used with single-function devices | ||
| 403 | * where bDeviceClass doesn't specify that each interface has | ||
| 404 | * its own class. | ||
| 405 | * | ||
| 406 | * Matches based on interface class/subclass/protocol are the | ||
| 407 | * most general; they let drivers bind to any interface on a | ||
| 408 | * multiple-function device. Use the USB_INTERFACE_INFO | ||
| 409 | * macro, or its siblings, to match class-per-interface style | ||
| 410 | * devices (as recorded in bDeviceClass). | ||
| 411 | * | ||
| 412 | * Within those groups, remember that not all combinations are | ||
| 413 | * meaningful. For example, don't give a product version range | ||
| 414 | * without vendor and product IDs; or specify a protocol without | ||
| 415 | * its associated class and subclass. | ||
| 416 | */ | ||
| 417 | const struct usb_device_id * | ||
| 418 | usb_match_id(struct usb_interface *interface, const struct usb_device_id *id) | ||
| 419 | { | ||
| 420 | struct usb_host_interface *intf; | ||
| 421 | struct usb_device *dev; | ||
| 422 | |||
| 423 | /* proc_connectinfo in devio.c may call us with id == NULL. */ | ||
| 424 | if (id == NULL) | ||
| 425 | return NULL; | ||
| 426 | |||
| 427 | intf = interface->cur_altsetting; | ||
| 428 | dev = interface_to_usbdev(interface); | ||
| 429 | |||
| 430 | /* It is important to check that id->driver_info is nonzero, | ||
| 431 | since an entry that is all zeroes except for a nonzero | ||
| 432 | id->driver_info is the way to create an entry that | ||
| 433 | indicates that the driver want to examine every | ||
| 434 | device and interface. */ | ||
| 435 | for (; id->idVendor || id->bDeviceClass || id->bInterfaceClass || | ||
| 436 | id->driver_info; id++) { | ||
| 437 | |||
| 438 | if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) && | ||
| 439 | id->idVendor != le16_to_cpu(dev->descriptor.idVendor)) | ||
| 440 | continue; | ||
| 441 | |||
| 442 | if ((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) && | ||
| 443 | id->idProduct != le16_to_cpu(dev->descriptor.idProduct)) | ||
| 444 | continue; | ||
| 445 | |||
| 446 | /* No need to test id->bcdDevice_lo != 0, since 0 is never | ||
| 447 | greater than any unsigned number. */ | ||
| 448 | if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_LO) && | ||
| 449 | (id->bcdDevice_lo > le16_to_cpu(dev->descriptor.bcdDevice))) | ||
| 450 | continue; | ||
| 451 | |||
| 452 | if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI) && | ||
| 453 | (id->bcdDevice_hi < le16_to_cpu(dev->descriptor.bcdDevice))) | ||
| 454 | continue; | ||
| 455 | |||
| 456 | if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS) && | ||
| 457 | (id->bDeviceClass != dev->descriptor.bDeviceClass)) | ||
| 458 | continue; | ||
| 459 | |||
| 460 | if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS) && | ||
| 461 | (id->bDeviceSubClass!= dev->descriptor.bDeviceSubClass)) | ||
| 462 | continue; | ||
| 463 | |||
| 464 | if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL) && | ||
| 465 | (id->bDeviceProtocol != dev->descriptor.bDeviceProtocol)) | ||
| 466 | continue; | ||
| 467 | |||
| 468 | if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) && | ||
| 469 | (id->bInterfaceClass != intf->desc.bInterfaceClass)) | ||
| 470 | continue; | ||
| 471 | |||
| 472 | if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_SUBCLASS) && | ||
| 473 | (id->bInterfaceSubClass != intf->desc.bInterfaceSubClass)) | ||
| 474 | continue; | ||
| 475 | |||
| 476 | if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_PROTOCOL) && | ||
| 477 | (id->bInterfaceProtocol != intf->desc.bInterfaceProtocol)) | ||
| 478 | continue; | ||
| 479 | |||
| 480 | return id; | ||
| 481 | } | ||
| 482 | |||
| 483 | return NULL; | ||
| 484 | } | ||
| 485 | |||
| 486 | 199 | ||
| 487 | static int __find_interface(struct device * dev, void * data) | 200 | static int __find_interface(struct device * dev, void * data) |
| 488 | { | 201 | { |
| 489 | struct usb_interface ** ret = (struct usb_interface **)data; | 202 | struct find_interface_arg *arg = data; |
| 490 | struct usb_interface * intf = *ret; | 203 | struct usb_interface *intf; |
| 491 | int *minor = (int *)data; | ||
| 492 | 204 | ||
| 493 | /* can't look at usb devices, only interfaces */ | 205 | /* can't look at usb devices, only interfaces */ |
| 494 | if (dev->driver == &usb_generic_driver) | 206 | if (dev->driver == &usb_generic_driver) |
| 495 | return 0; | 207 | return 0; |
| 496 | 208 | ||
| 497 | intf = to_usb_interface(dev); | 209 | intf = to_usb_interface(dev); |
| 498 | if (intf->minor != -1 && intf->minor == *minor) { | 210 | if (intf->minor != -1 && intf->minor == arg->minor) { |
| 499 | *ret = intf; | 211 | arg->interface = intf; |
| 500 | return 1; | 212 | return 1; |
| 501 | } | 213 | } |
| 502 | return 0; | 214 | return 0; |
| @@ -513,35 +225,14 @@ static int __find_interface(struct device * dev, void * data) | |||
| 513 | */ | 225 | */ |
| 514 | struct usb_interface *usb_find_interface(struct usb_driver *drv, int minor) | 226 | struct usb_interface *usb_find_interface(struct usb_driver *drv, int minor) |
| 515 | { | 227 | { |
| 516 | struct usb_interface *intf = (struct usb_interface *)(long)minor; | 228 | struct find_interface_arg argb; |
| 517 | int ret; | ||
| 518 | |||
| 519 | ret = driver_for_each_device(&drv->driver, NULL, &intf, __find_interface); | ||
| 520 | |||
| 521 | return ret ? intf : NULL; | ||
| 522 | } | ||
| 523 | |||
| 524 | static int usb_device_match (struct device *dev, struct device_driver *drv) | ||
| 525 | { | ||
| 526 | struct usb_interface *intf; | ||
| 527 | struct usb_driver *usb_drv; | ||
| 528 | const struct usb_device_id *id; | ||
| 529 | |||
| 530 | /* check for generic driver, which we don't match any device with */ | ||
| 531 | if (drv == &usb_generic_driver) | ||
| 532 | return 0; | ||
| 533 | |||
| 534 | intf = to_usb_interface(dev); | ||
| 535 | usb_drv = to_usb_driver(drv); | ||
| 536 | |||
| 537 | id = usb_match_id (intf, usb_drv->id_table); | ||
| 538 | if (id) | ||
| 539 | return 1; | ||
| 540 | 229 | ||
| 541 | return 0; | 230 | argb.minor = minor; |
| 231 | argb.interface = NULL; | ||
| 232 | driver_for_each_device(&drv->driver, NULL, &argb, __find_interface); | ||
| 233 | return argb.interface; | ||
| 542 | } | 234 | } |
| 543 | 235 | ||
| 544 | |||
| 545 | #ifdef CONFIG_HOTPLUG | 236 | #ifdef CONFIG_HOTPLUG |
| 546 | 237 | ||
| 547 | /* | 238 | /* |
| @@ -750,12 +441,11 @@ usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1) | |||
| 750 | /* hub driver sets up TT records */ | 441 | /* hub driver sets up TT records */ |
| 751 | } | 442 | } |
| 752 | 443 | ||
| 444 | dev->portnum = port1; | ||
| 753 | dev->bus = bus; | 445 | dev->bus = bus; |
| 754 | dev->parent = parent; | 446 | dev->parent = parent; |
| 755 | INIT_LIST_HEAD(&dev->filelist); | 447 | INIT_LIST_HEAD(&dev->filelist); |
| 756 | 448 | ||
| 757 | init_MUTEX(&dev->serialize); | ||
| 758 | |||
| 759 | return dev; | 449 | return dev; |
| 760 | } | 450 | } |
| 761 | 451 | ||
| @@ -828,76 +518,21 @@ void usb_put_intf(struct usb_interface *intf) | |||
| 828 | 518 | ||
| 829 | /* USB device locking | 519 | /* USB device locking |
| 830 | * | 520 | * |
| 831 | * Although locking USB devices should be straightforward, it is | 521 | * USB devices and interfaces are locked using the semaphore in their |
| 832 | * complicated by the way the driver-model core works. When a new USB | 522 | * embedded struct device. The hub driver guarantees that whenever a |
| 833 | * driver is registered or unregistered, the core will automatically | 523 | * device is connected or disconnected, drivers are called with the |
| 834 | * probe or disconnect all matching interfaces on all USB devices while | 524 | * USB device locked as well as their particular interface. |
| 835 | * holding the USB subsystem writelock. There's no good way for us to | ||
| 836 | * tell which devices will be used or to lock them beforehand; our only | ||
| 837 | * option is to effectively lock all the USB devices. | ||
| 838 | * | ||
| 839 | * We do that by using a private rw-semaphore, usb_all_devices_rwsem. | ||
| 840 | * When locking an individual device you must first acquire the rwsem's | ||
| 841 | * readlock. When a driver is registered or unregistered the writelock | ||
| 842 | * must be held. These actions are encapsulated in the subroutines | ||
| 843 | * below, so all a driver needs to do is call usb_lock_device() and | ||
| 844 | * usb_unlock_device(). | ||
| 845 | * | 525 | * |
| 846 | * Complications arise when several devices are to be locked at the same | 526 | * Complications arise when several devices are to be locked at the same |
| 847 | * time. Only hub-aware drivers that are part of usbcore ever have to | 527 | * time. Only hub-aware drivers that are part of usbcore ever have to |
| 848 | * do this; nobody else needs to worry about it. The problem is that | 528 | * do this; nobody else needs to worry about it. The rule for locking |
| 849 | * usb_lock_device() must not be called to lock a second device since it | 529 | * is simple: |
| 850 | * would acquire the rwsem's readlock reentrantly, leading to deadlock if | ||
| 851 | * another thread was waiting for the writelock. The solution is simple: | ||
| 852 | * | ||
| 853 | * When locking more than one device, call usb_lock_device() | ||
| 854 | * to lock the first one. Lock the others by calling | ||
| 855 | * down(&udev->serialize) directly. | ||
| 856 | * | ||
| 857 | * When unlocking multiple devices, use up(&udev->serialize) | ||
| 858 | * to unlock all but the last one. Unlock the last one by | ||
| 859 | * calling usb_unlock_device(). | ||
| 860 | * | 530 | * |
| 861 | * When locking both a device and its parent, always lock the | 531 | * When locking both a device and its parent, always lock the |
| 862 | * the parent first. | 532 | * the parent first. |
| 863 | */ | 533 | */ |
| 864 | 534 | ||
| 865 | /** | 535 | /** |
| 866 | * usb_lock_device - acquire the lock for a usb device structure | ||
| 867 | * @udev: device that's being locked | ||
| 868 | * | ||
| 869 | * Use this routine when you don't hold any other device locks; | ||
| 870 | * to acquire nested inner locks call down(&udev->serialize) directly. | ||
| 871 | * This is necessary for proper interaction with usb_lock_all_devices(). | ||
| 872 | */ | ||
| 873 | void usb_lock_device(struct usb_device *udev) | ||
| 874 | { | ||
| 875 | down_read(&usb_all_devices_rwsem); | ||
| 876 | down(&udev->serialize); | ||
| 877 | } | ||
| 878 | |||
| 879 | /** | ||
| 880 | * usb_trylock_device - attempt to acquire the lock for a usb device structure | ||
| 881 | * @udev: device that's being locked | ||
| 882 | * | ||
| 883 | * Don't use this routine if you already hold a device lock; | ||
| 884 | * use down_trylock(&udev->serialize) instead. | ||
| 885 | * This is necessary for proper interaction with usb_lock_all_devices(). | ||
| 886 | * | ||
| 887 | * Returns 1 if successful, 0 if contention. | ||
| 888 | */ | ||
| 889 | int usb_trylock_device(struct usb_device *udev) | ||
| 890 | { | ||
| 891 | if (!down_read_trylock(&usb_all_devices_rwsem)) | ||
| 892 | return 0; | ||
| 893 | if (down_trylock(&udev->serialize)) { | ||
| 894 | up_read(&usb_all_devices_rwsem); | ||
| 895 | return 0; | ||
| 896 | } | ||
| 897 | return 1; | ||
| 898 | } | ||
| 899 | |||
| 900 | /** | ||
| 901 | * usb_lock_device_for_reset - cautiously acquire the lock for a | 536 | * usb_lock_device_for_reset - cautiously acquire the lock for a |
| 902 | * usb device structure | 537 | * usb device structure |
| 903 | * @udev: device that's being locked | 538 | * @udev: device that's being locked |
| @@ -935,7 +570,7 @@ int usb_lock_device_for_reset(struct usb_device *udev, | |||
| 935 | } | 570 | } |
| 936 | } | 571 | } |
| 937 | 572 | ||
| 938 | while (!usb_trylock_device(udev)) { | 573 | while (usb_trylock_device(udev) != 0) { |
| 939 | 574 | ||
| 940 | /* If we can't acquire the lock after waiting one second, | 575 | /* If we can't acquire the lock after waiting one second, |
| 941 | * we're probably deadlocked */ | 576 | * we're probably deadlocked */ |
| @@ -953,39 +588,6 @@ int usb_lock_device_for_reset(struct usb_device *udev, | |||
| 953 | return 1; | 588 | return 1; |
| 954 | } | 589 | } |
| 955 | 590 | ||
| 956 | /** | ||
| 957 | * usb_unlock_device - release the lock for a usb device structure | ||
| 958 | * @udev: device that's being unlocked | ||
| 959 | * | ||
| 960 | * Use this routine when releasing the only device lock you hold; | ||
| 961 | * to release inner nested locks call up(&udev->serialize) directly. | ||
| 962 | * This is necessary for proper interaction with usb_lock_all_devices(). | ||
| 963 | */ | ||
| 964 | void usb_unlock_device(struct usb_device *udev) | ||
| 965 | { | ||
| 966 | up(&udev->serialize); | ||
| 967 | up_read(&usb_all_devices_rwsem); | ||
| 968 | } | ||
| 969 | |||
| 970 | /** | ||
| 971 | * usb_lock_all_devices - acquire the lock for all usb device structures | ||
| 972 | * | ||
| 973 | * This is necessary when registering a new driver or probing a bus, | ||
| 974 | * since the driver-model core may try to use any usb_device. | ||
| 975 | */ | ||
| 976 | void usb_lock_all_devices(void) | ||
| 977 | { | ||
| 978 | down_write(&usb_all_devices_rwsem); | ||
| 979 | } | ||
| 980 | |||
| 981 | /** | ||
| 982 | * usb_unlock_all_devices - release the lock for all usb device structures | ||
| 983 | */ | ||
| 984 | void usb_unlock_all_devices(void) | ||
| 985 | { | ||
| 986 | up_write(&usb_all_devices_rwsem); | ||
| 987 | } | ||
| 988 | |||
| 989 | 591 | ||
| 990 | static struct usb_device *match_device(struct usb_device *dev, | 592 | static struct usb_device *match_device(struct usb_device *dev, |
| 991 | u16 vendor_id, u16 product_id) | 593 | u16 vendor_id, u16 product_id) |
| @@ -1008,10 +610,10 @@ static struct usb_device *match_device(struct usb_device *dev, | |||
| 1008 | /* look through all of the children of this device */ | 610 | /* look through all of the children of this device */ |
| 1009 | for (child = 0; child < dev->maxchild; ++child) { | 611 | for (child = 0; child < dev->maxchild; ++child) { |
| 1010 | if (dev->children[child]) { | 612 | if (dev->children[child]) { |
| 1011 | down(&dev->children[child]->serialize); | 613 | usb_lock_device(dev->children[child]); |
| 1012 | ret_dev = match_device(dev->children[child], | 614 | ret_dev = match_device(dev->children[child], |
| 1013 | vendor_id, product_id); | 615 | vendor_id, product_id); |
| 1014 | up(&dev->children[child]->serialize); | 616 | usb_unlock_device(dev->children[child]); |
| 1015 | if (ret_dev) | 617 | if (ret_dev) |
| 1016 | goto exit; | 618 | goto exit; |
| 1017 | } | 619 | } |
| @@ -1496,18 +1098,8 @@ struct bus_type usb_bus_type = { | |||
| 1496 | .resume = usb_generic_resume, | 1098 | .resume = usb_generic_resume, |
| 1497 | }; | 1099 | }; |
| 1498 | 1100 | ||
| 1499 | #ifndef MODULE | ||
| 1500 | |||
| 1501 | static int __init usb_setup_disable(char *str) | ||
| 1502 | { | ||
| 1503 | nousb = 1; | ||
| 1504 | return 1; | ||
| 1505 | } | ||
| 1506 | |||
| 1507 | /* format to disable USB on kernel command line is: nousb */ | 1101 | /* format to disable USB on kernel command line is: nousb */ |
| 1508 | __setup("nousb", usb_setup_disable); | 1102 | __module_param_call("", nousb, param_set_bool, param_get_bool, &nousb, 0444); |
| 1509 | |||
| 1510 | #endif | ||
| 1511 | 1103 | ||
| 1512 | /* | 1104 | /* |
| 1513 | * for external read access to <nousb> | 1105 | * for external read access to <nousb> |
| @@ -1598,8 +1190,6 @@ module_exit(usb_exit); | |||
| 1598 | * driver modules to use. | 1190 | * driver modules to use. |
| 1599 | */ | 1191 | */ |
| 1600 | 1192 | ||
| 1601 | EXPORT_SYMBOL(usb_register); | ||
| 1602 | EXPORT_SYMBOL(usb_deregister); | ||
| 1603 | EXPORT_SYMBOL(usb_disabled); | 1193 | EXPORT_SYMBOL(usb_disabled); |
| 1604 | 1194 | ||
| 1605 | EXPORT_SYMBOL_GPL(usb_get_intf); | 1195 | EXPORT_SYMBOL_GPL(usb_get_intf); |
| @@ -1610,14 +1200,10 @@ EXPORT_SYMBOL(usb_put_dev); | |||
| 1610 | EXPORT_SYMBOL(usb_get_dev); | 1200 | EXPORT_SYMBOL(usb_get_dev); |
| 1611 | EXPORT_SYMBOL(usb_hub_tt_clear_buffer); | 1201 | EXPORT_SYMBOL(usb_hub_tt_clear_buffer); |
| 1612 | 1202 | ||
| 1613 | EXPORT_SYMBOL(usb_lock_device); | ||
| 1614 | EXPORT_SYMBOL(usb_trylock_device); | ||
| 1615 | EXPORT_SYMBOL(usb_lock_device_for_reset); | 1203 | EXPORT_SYMBOL(usb_lock_device_for_reset); |
| 1616 | EXPORT_SYMBOL(usb_unlock_device); | ||
| 1617 | 1204 | ||
| 1618 | EXPORT_SYMBOL(usb_driver_claim_interface); | 1205 | EXPORT_SYMBOL(usb_driver_claim_interface); |
| 1619 | EXPORT_SYMBOL(usb_driver_release_interface); | 1206 | EXPORT_SYMBOL(usb_driver_release_interface); |
| 1620 | EXPORT_SYMBOL(usb_match_id); | ||
| 1621 | EXPORT_SYMBOL(usb_find_interface); | 1207 | EXPORT_SYMBOL(usb_find_interface); |
| 1622 | EXPORT_SYMBOL(usb_ifnum_to_if); | 1208 | EXPORT_SYMBOL(usb_ifnum_to_if); |
| 1623 | EXPORT_SYMBOL(usb_altnum_to_altsetting); | 1209 | EXPORT_SYMBOL(usb_altnum_to_altsetting); |
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 1c4a68499dce..4647e1ebc68d 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h | |||
| @@ -16,9 +16,6 @@ extern int usb_get_device_descriptor(struct usb_device *dev, | |||
| 16 | extern char *usb_cache_string(struct usb_device *udev, int index); | 16 | extern char *usb_cache_string(struct usb_device *udev, int index); |
| 17 | extern int usb_set_configuration(struct usb_device *dev, int configuration); | 17 | extern int usb_set_configuration(struct usb_device *dev, int configuration); |
| 18 | 18 | ||
| 19 | extern void usb_lock_all_devices(void); | ||
| 20 | extern void usb_unlock_all_devices(void); | ||
| 21 | |||
| 22 | extern void usb_kick_khubd(struct usb_device *dev); | 19 | extern void usb_kick_khubd(struct usb_device *dev); |
| 23 | extern void usb_suspend_root_hub(struct usb_device *hdev); | 20 | extern void usb_suspend_root_hub(struct usb_device *hdev); |
| 24 | extern void usb_resume_root_hub(struct usb_device *dev); | 21 | extern void usb_resume_root_hub(struct usb_device *dev); |
| @@ -33,6 +30,9 @@ extern void usb_host_cleanup(void); | |||
| 33 | extern int usb_suspend_device(struct usb_device *dev); | 30 | extern int usb_suspend_device(struct usb_device *dev); |
| 34 | extern int usb_resume_device(struct usb_device *dev); | 31 | extern int usb_resume_device(struct usb_device *dev); |
| 35 | 32 | ||
| 33 | extern struct device_driver usb_generic_driver; | ||
| 34 | extern int usb_generic_driver_data; | ||
| 35 | extern int usb_device_match(struct device *dev, struct device_driver *drv); | ||
| 36 | 36 | ||
| 37 | /* Interfaces and their "power state" are owned by usbcore */ | 37 | /* Interfaces and their "power state" are owned by usbcore */ |
| 38 | 38 | ||
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index c655d46c8aed..9734cb76dd6c 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c | |||
| @@ -138,7 +138,7 @@ static const char *const ep_name [] = { | |||
| 138 | /* or like sa1100: two fixed function endpoints */ | 138 | /* or like sa1100: two fixed function endpoints */ |
| 139 | "ep1out-bulk", "ep2in-bulk", | 139 | "ep1out-bulk", "ep2in-bulk", |
| 140 | }; | 140 | }; |
| 141 | #define DUMMY_ENDPOINTS (sizeof(ep_name)/sizeof(char *)) | 141 | #define DUMMY_ENDPOINTS ARRAY_SIZE(ep_name) |
| 142 | 142 | ||
| 143 | /*-------------------------------------------------------------------------*/ | 143 | /*-------------------------------------------------------------------------*/ |
| 144 | 144 | ||
| @@ -896,7 +896,7 @@ dummy_gadget_release (struct device *dev) | |||
| 896 | #endif | 896 | #endif |
| 897 | } | 897 | } |
| 898 | 898 | ||
| 899 | static int dummy_udc_probe (struct platform_device *dev) | 899 | static int dummy_udc_probe (struct platform_device *pdev) |
| 900 | { | 900 | { |
| 901 | struct dummy *dum = the_controller; | 901 | struct dummy *dum = the_controller; |
| 902 | int rc; | 902 | int rc; |
| @@ -909,7 +909,7 @@ static int dummy_udc_probe (struct platform_device *dev) | |||
| 909 | dum->gadget.is_otg = (dummy_to_hcd(dum)->self.otg_port != 0); | 909 | dum->gadget.is_otg = (dummy_to_hcd(dum)->self.otg_port != 0); |
| 910 | 910 | ||
| 911 | strcpy (dum->gadget.dev.bus_id, "gadget"); | 911 | strcpy (dum->gadget.dev.bus_id, "gadget"); |
| 912 | dum->gadget.dev.parent = &dev->dev; | 912 | dum->gadget.dev.parent = &pdev->dev; |
| 913 | dum->gadget.dev.release = dummy_gadget_release; | 913 | dum->gadget.dev.release = dummy_gadget_release; |
| 914 | rc = device_register (&dum->gadget.dev); | 914 | rc = device_register (&dum->gadget.dev); |
| 915 | if (rc < 0) | 915 | if (rc < 0) |
| @@ -919,47 +919,47 @@ static int dummy_udc_probe (struct platform_device *dev) | |||
| 919 | usb_bus_get (&dummy_to_hcd (dum)->self); | 919 | usb_bus_get (&dummy_to_hcd (dum)->self); |
| 920 | #endif | 920 | #endif |
| 921 | 921 | ||
| 922 | platform_set_drvdata (dev, dum); | 922 | platform_set_drvdata (pdev, dum); |
| 923 | device_create_file (&dum->gadget.dev, &dev_attr_function); | 923 | device_create_file (&dum->gadget.dev, &dev_attr_function); |
| 924 | return rc; | 924 | return rc; |
| 925 | } | 925 | } |
| 926 | 926 | ||
| 927 | static int dummy_udc_remove (struct platform_device *dev) | 927 | static int dummy_udc_remove (struct platform_device *pdev) |
| 928 | { | 928 | { |
| 929 | struct dummy *dum = platform_get_drvdata (dev); | 929 | struct dummy *dum = platform_get_drvdata (pdev); |
| 930 | 930 | ||
| 931 | platform_set_drvdata (dev, NULL); | 931 | platform_set_drvdata (pdev, NULL); |
| 932 | device_remove_file (&dum->gadget.dev, &dev_attr_function); | 932 | device_remove_file (&dum->gadget.dev, &dev_attr_function); |
| 933 | device_unregister (&dum->gadget.dev); | 933 | device_unregister (&dum->gadget.dev); |
| 934 | return 0; | 934 | return 0; |
| 935 | } | 935 | } |
| 936 | 936 | ||
| 937 | static int dummy_udc_suspend (struct platform_device *dev, pm_message_t state) | 937 | static int dummy_udc_suspend (struct platform_device *pdev, pm_message_t state) |
| 938 | { | 938 | { |
| 939 | struct dummy *dum = platform_get_drvdata(dev); | 939 | struct dummy *dum = platform_get_drvdata(pdev); |
| 940 | 940 | ||
| 941 | dev_dbg (&dev->dev, "%s\n", __FUNCTION__); | 941 | dev_dbg (&pdev->dev, "%s\n", __FUNCTION__); |
| 942 | spin_lock_irq (&dum->lock); | 942 | spin_lock_irq (&dum->lock); |
| 943 | dum->udc_suspended = 1; | 943 | dum->udc_suspended = 1; |
| 944 | set_link_state (dum); | 944 | set_link_state (dum); |
| 945 | spin_unlock_irq (&dum->lock); | 945 | spin_unlock_irq (&dum->lock); |
| 946 | 946 | ||
| 947 | dev->dev.power.power_state = state; | 947 | pdev->dev.power.power_state = state; |
| 948 | usb_hcd_poll_rh_status (dummy_to_hcd (dum)); | 948 | usb_hcd_poll_rh_status (dummy_to_hcd (dum)); |
| 949 | return 0; | 949 | return 0; |
| 950 | } | 950 | } |
| 951 | 951 | ||
| 952 | static int dummy_udc_resume (struct platform_device *dev) | 952 | static int dummy_udc_resume (struct platform_device *pdev) |
| 953 | { | 953 | { |
| 954 | struct dummy *dum = platform_get_drvdata(dev); | 954 | struct dummy *dum = platform_get_drvdata(pdev); |
| 955 | 955 | ||
| 956 | dev_dbg (&dev->dev, "%s\n", __FUNCTION__); | 956 | dev_dbg (&pdev->dev, "%s\n", __FUNCTION__); |
| 957 | spin_lock_irq (&dum->lock); | 957 | spin_lock_irq (&dum->lock); |
| 958 | dum->udc_suspended = 0; | 958 | dum->udc_suspended = 0; |
| 959 | set_link_state (dum); | 959 | set_link_state (dum); |
| 960 | spin_unlock_irq (&dum->lock); | 960 | spin_unlock_irq (&dum->lock); |
| 961 | 961 | ||
| 962 | dev->dev.power.power_state = PMSG_ON; | 962 | pdev->dev.power.power_state = PMSG_ON; |
| 963 | usb_hcd_poll_rh_status (dummy_to_hcd (dum)); | 963 | usb_hcd_poll_rh_status (dummy_to_hcd (dum)); |
| 964 | return 0; | 964 | return 0; |
| 965 | } | 965 | } |
| @@ -1576,7 +1576,7 @@ static int dummy_hub_status (struct usb_hcd *hcd, char *buf) | |||
| 1576 | dum = hcd_to_dummy (hcd); | 1576 | dum = hcd_to_dummy (hcd); |
| 1577 | 1577 | ||
| 1578 | spin_lock_irqsave (&dum->lock, flags); | 1578 | spin_lock_irqsave (&dum->lock, flags); |
| 1579 | if (hcd->state != HC_STATE_RUNNING) | 1579 | if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) |
| 1580 | goto done; | 1580 | goto done; |
| 1581 | 1581 | ||
| 1582 | if (dum->resuming && time_after_eq (jiffies, dum->re_timeout)) { | 1582 | if (dum->resuming && time_after_eq (jiffies, dum->re_timeout)) { |
| @@ -1623,7 +1623,7 @@ static int dummy_hub_control ( | |||
| 1623 | int retval = 0; | 1623 | int retval = 0; |
| 1624 | unsigned long flags; | 1624 | unsigned long flags; |
| 1625 | 1625 | ||
| 1626 | if (hcd->state != HC_STATE_RUNNING) | 1626 | if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) |
| 1627 | return -ETIMEDOUT; | 1627 | return -ETIMEDOUT; |
| 1628 | 1628 | ||
| 1629 | dum = hcd_to_dummy (hcd); | 1629 | dum = hcd_to_dummy (hcd); |
| @@ -1756,9 +1756,12 @@ static int dummy_bus_suspend (struct usb_hcd *hcd) | |||
| 1756 | { | 1756 | { |
| 1757 | struct dummy *dum = hcd_to_dummy (hcd); | 1757 | struct dummy *dum = hcd_to_dummy (hcd); |
| 1758 | 1758 | ||
| 1759 | dev_dbg (&hcd->self.root_hub->dev, "%s\n", __FUNCTION__); | ||
| 1760 | |||
| 1759 | spin_lock_irq (&dum->lock); | 1761 | spin_lock_irq (&dum->lock); |
| 1760 | dum->rh_state = DUMMY_RH_SUSPENDED; | 1762 | dum->rh_state = DUMMY_RH_SUSPENDED; |
| 1761 | set_link_state (dum); | 1763 | set_link_state (dum); |
| 1764 | hcd->state = HC_STATE_SUSPENDED; | ||
| 1762 | spin_unlock_irq (&dum->lock); | 1765 | spin_unlock_irq (&dum->lock); |
| 1763 | return 0; | 1766 | return 0; |
| 1764 | } | 1767 | } |
| @@ -1766,14 +1769,23 @@ static int dummy_bus_suspend (struct usb_hcd *hcd) | |||
| 1766 | static int dummy_bus_resume (struct usb_hcd *hcd) | 1769 | static int dummy_bus_resume (struct usb_hcd *hcd) |
| 1767 | { | 1770 | { |
| 1768 | struct dummy *dum = hcd_to_dummy (hcd); | 1771 | struct dummy *dum = hcd_to_dummy (hcd); |
| 1772 | int rc = 0; | ||
| 1773 | |||
| 1774 | dev_dbg (&hcd->self.root_hub->dev, "%s\n", __FUNCTION__); | ||
| 1769 | 1775 | ||
| 1770 | spin_lock_irq (&dum->lock); | 1776 | spin_lock_irq (&dum->lock); |
| 1771 | dum->rh_state = DUMMY_RH_RUNNING; | 1777 | if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) { |
| 1772 | set_link_state (dum); | 1778 | dev_warn (&hcd->self.root_hub->dev, "HC isn't running!\n"); |
| 1773 | if (!list_empty(&dum->urbp_list)) | 1779 | rc = -ENODEV; |
| 1774 | mod_timer (&dum->timer, jiffies); | 1780 | } else { |
| 1781 | dum->rh_state = DUMMY_RH_RUNNING; | ||
| 1782 | set_link_state (dum); | ||
| 1783 | if (!list_empty(&dum->urbp_list)) | ||
| 1784 | mod_timer (&dum->timer, jiffies); | ||
| 1785 | hcd->state = HC_STATE_RUNNING; | ||
| 1786 | } | ||
| 1775 | spin_unlock_irq (&dum->lock); | 1787 | spin_unlock_irq (&dum->lock); |
| 1776 | return 0; | 1788 | return rc; |
| 1777 | } | 1789 | } |
| 1778 | 1790 | ||
| 1779 | /*-------------------------------------------------------------------------*/ | 1791 | /*-------------------------------------------------------------------------*/ |
| @@ -1899,14 +1911,14 @@ static const struct hc_driver dummy_hcd = { | |||
| 1899 | .bus_resume = dummy_bus_resume, | 1911 | .bus_resume = dummy_bus_resume, |
| 1900 | }; | 1912 | }; |
| 1901 | 1913 | ||
| 1902 | static int dummy_hcd_probe (struct platform_device *dev) | 1914 | static int dummy_hcd_probe(struct platform_device *pdev) |
| 1903 | { | 1915 | { |
| 1904 | struct usb_hcd *hcd; | 1916 | struct usb_hcd *hcd; |
| 1905 | int retval; | 1917 | int retval; |
| 1906 | 1918 | ||
| 1907 | dev_info(&dev->dev, "%s, driver " DRIVER_VERSION "\n", driver_desc); | 1919 | dev_info(&pdev->dev, "%s, driver " DRIVER_VERSION "\n", driver_desc); |
| 1908 | 1920 | ||
| 1909 | hcd = usb_create_hcd (&dummy_hcd, &dev->dev, dev->dev.bus_id); | 1921 | hcd = usb_create_hcd(&dummy_hcd, &pdev->dev, pdev->dev.bus_id); |
| 1910 | if (!hcd) | 1922 | if (!hcd) |
| 1911 | return -ENOMEM; | 1923 | return -ENOMEM; |
| 1912 | the_controller = hcd_to_dummy (hcd); | 1924 | the_controller = hcd_to_dummy (hcd); |
| @@ -1919,36 +1931,43 @@ static int dummy_hcd_probe (struct platform_device *dev) | |||
| 1919 | return retval; | 1931 | return retval; |
| 1920 | } | 1932 | } |
| 1921 | 1933 | ||
| 1922 | static int dummy_hcd_remove (struct platform_device *dev) | 1934 | static int dummy_hcd_remove (struct platform_device *pdev) |
| 1923 | { | 1935 | { |
| 1924 | struct usb_hcd *hcd; | 1936 | struct usb_hcd *hcd; |
| 1925 | 1937 | ||
| 1926 | hcd = platform_get_drvdata (dev); | 1938 | hcd = platform_get_drvdata (pdev); |
| 1927 | usb_remove_hcd (hcd); | 1939 | usb_remove_hcd (hcd); |
| 1928 | usb_put_hcd (hcd); | 1940 | usb_put_hcd (hcd); |
| 1929 | the_controller = NULL; | 1941 | the_controller = NULL; |
| 1930 | return 0; | 1942 | return 0; |
| 1931 | } | 1943 | } |
| 1932 | 1944 | ||
| 1933 | static int dummy_hcd_suspend (struct platform_device *dev, pm_message_t state) | 1945 | static int dummy_hcd_suspend (struct platform_device *pdev, pm_message_t state) |
| 1934 | { | 1946 | { |
| 1935 | struct usb_hcd *hcd; | 1947 | struct usb_hcd *hcd; |
| 1948 | struct dummy *dum; | ||
| 1949 | int rc = 0; | ||
| 1936 | 1950 | ||
| 1937 | dev_dbg (&dev->dev, "%s\n", __FUNCTION__); | 1951 | dev_dbg (&pdev->dev, "%s\n", __FUNCTION__); |
| 1938 | hcd = platform_get_drvdata (dev); | ||
| 1939 | 1952 | ||
| 1940 | hcd->state = HC_STATE_SUSPENDED; | 1953 | hcd = platform_get_drvdata (pdev); |
| 1941 | return 0; | 1954 | dum = hcd_to_dummy (hcd); |
| 1955 | if (dum->rh_state == DUMMY_RH_RUNNING) { | ||
| 1956 | dev_warn(&pdev->dev, "Root hub isn't suspended!\n"); | ||
| 1957 | rc = -EBUSY; | ||
| 1958 | } else | ||
| 1959 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | ||
| 1960 | return rc; | ||
| 1942 | } | 1961 | } |
| 1943 | 1962 | ||
| 1944 | static int dummy_hcd_resume (struct platform_device *dev) | 1963 | static int dummy_hcd_resume (struct platform_device *pdev) |
| 1945 | { | 1964 | { |
| 1946 | struct usb_hcd *hcd; | 1965 | struct usb_hcd *hcd; |
| 1947 | 1966 | ||
| 1948 | dev_dbg (&dev->dev, "%s\n", __FUNCTION__); | 1967 | dev_dbg (&pdev->dev, "%s\n", __FUNCTION__); |
| 1949 | hcd = platform_get_drvdata (dev); | ||
| 1950 | hcd->state = HC_STATE_RUNNING; | ||
| 1951 | 1968 | ||
| 1969 | hcd = platform_get_drvdata (pdev); | ||
| 1970 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | ||
| 1952 | usb_hcd_poll_rh_status (hcd); | 1971 | usb_hcd_poll_rh_status (hcd); |
| 1953 | return 0; | 1972 | return 0; |
| 1954 | } | 1973 | } |
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index ea09aaa3cab6..0cea9782d7d4 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c | |||
| @@ -224,6 +224,7 @@ | |||
| 224 | #include <linux/fs.h> | 224 | #include <linux/fs.h> |
| 225 | #include <linux/init.h> | 225 | #include <linux/init.h> |
| 226 | #include <linux/kernel.h> | 226 | #include <linux/kernel.h> |
| 227 | #include <linux/kref.h> | ||
| 227 | #include <linux/kthread.h> | 228 | #include <linux/kthread.h> |
| 228 | #include <linux/limits.h> | 229 | #include <linux/limits.h> |
| 229 | #include <linux/list.h> | 230 | #include <linux/list.h> |
| @@ -238,7 +239,6 @@ | |||
| 238 | #include <linux/string.h> | 239 | #include <linux/string.h> |
| 239 | #include <linux/suspend.h> | 240 | #include <linux/suspend.h> |
| 240 | #include <linux/utsname.h> | 241 | #include <linux/utsname.h> |
| 241 | #include <linux/wait.h> | ||
| 242 | 242 | ||
| 243 | #include <linux/usb_ch9.h> | 243 | #include <linux/usb_ch9.h> |
| 244 | #include <linux/usb_gadget.h> | 244 | #include <linux/usb_gadget.h> |
| @@ -250,7 +250,7 @@ | |||
| 250 | 250 | ||
| 251 | #define DRIVER_DESC "File-backed Storage Gadget" | 251 | #define DRIVER_DESC "File-backed Storage Gadget" |
| 252 | #define DRIVER_NAME "g_file_storage" | 252 | #define DRIVER_NAME "g_file_storage" |
| 253 | #define DRIVER_VERSION "20 October 2004" | 253 | #define DRIVER_VERSION "28 November 2005" |
| 254 | 254 | ||
| 255 | static const char longname[] = DRIVER_DESC; | 255 | static const char longname[] = DRIVER_DESC; |
| 256 | static const char shortname[] = DRIVER_NAME; | 256 | static const char shortname[] = DRIVER_NAME; |
| @@ -335,8 +335,8 @@ MODULE_LICENSE("Dual BSD/GPL"); | |||
| 335 | #define MAX_LUNS 8 | 335 | #define MAX_LUNS 8 |
| 336 | 336 | ||
| 337 | /* Arggh! There should be a module_param_array_named macro! */ | 337 | /* Arggh! There should be a module_param_array_named macro! */ |
| 338 | static char *file[MAX_LUNS] = {NULL, }; | 338 | static char *file[MAX_LUNS]; |
| 339 | static int ro[MAX_LUNS] = {0, }; | 339 | static int ro[MAX_LUNS]; |
| 340 | 340 | ||
| 341 | static struct { | 341 | static struct { |
| 342 | int num_filenames; | 342 | int num_filenames; |
| @@ -587,7 +587,7 @@ enum fsg_buffer_state { | |||
| 587 | struct fsg_buffhd { | 587 | struct fsg_buffhd { |
| 588 | void *buf; | 588 | void *buf; |
| 589 | dma_addr_t dma; | 589 | dma_addr_t dma; |
| 590 | volatile enum fsg_buffer_state state; | 590 | enum fsg_buffer_state state; |
| 591 | struct fsg_buffhd *next; | 591 | struct fsg_buffhd *next; |
| 592 | 592 | ||
| 593 | /* The NetChip 2280 is faster, and handles some protocol faults | 593 | /* The NetChip 2280 is faster, and handles some protocol faults |
| @@ -596,9 +596,9 @@ struct fsg_buffhd { | |||
| 596 | unsigned int bulk_out_intended_length; | 596 | unsigned int bulk_out_intended_length; |
| 597 | 597 | ||
| 598 | struct usb_request *inreq; | 598 | struct usb_request *inreq; |
| 599 | volatile int inreq_busy; | 599 | int inreq_busy; |
| 600 | struct usb_request *outreq; | 600 | struct usb_request *outreq; |
| 601 | volatile int outreq_busy; | 601 | int outreq_busy; |
| 602 | }; | 602 | }; |
| 603 | 603 | ||
| 604 | enum fsg_state { | 604 | enum fsg_state { |
| @@ -631,13 +631,16 @@ struct fsg_dev { | |||
| 631 | /* filesem protects: backing files in use */ | 631 | /* filesem protects: backing files in use */ |
| 632 | struct rw_semaphore filesem; | 632 | struct rw_semaphore filesem; |
| 633 | 633 | ||
| 634 | /* reference counting: wait until all LUNs are released */ | ||
| 635 | struct kref ref; | ||
| 636 | |||
| 634 | struct usb_ep *ep0; // Handy copy of gadget->ep0 | 637 | struct usb_ep *ep0; // Handy copy of gadget->ep0 |
| 635 | struct usb_request *ep0req; // For control responses | 638 | struct usb_request *ep0req; // For control responses |
| 636 | volatile unsigned int ep0_req_tag; | 639 | unsigned int ep0_req_tag; |
| 637 | const char *ep0req_name; | 640 | const char *ep0req_name; |
| 638 | 641 | ||
| 639 | struct usb_request *intreq; // For interrupt responses | 642 | struct usb_request *intreq; // For interrupt responses |
| 640 | volatile int intreq_busy; | 643 | int intreq_busy; |
| 641 | struct fsg_buffhd *intr_buffhd; | 644 | struct fsg_buffhd *intr_buffhd; |
| 642 | 645 | ||
| 643 | unsigned int bulk_out_maxpacket; | 646 | unsigned int bulk_out_maxpacket; |
| @@ -667,7 +670,6 @@ struct fsg_dev { | |||
| 667 | struct fsg_buffhd *next_buffhd_to_drain; | 670 | struct fsg_buffhd *next_buffhd_to_drain; |
| 668 | struct fsg_buffhd buffhds[NUM_BUFFERS]; | 671 | struct fsg_buffhd buffhds[NUM_BUFFERS]; |
| 669 | 672 | ||
| 670 | wait_queue_head_t thread_wqh; | ||
| 671 | int thread_wakeup_needed; | 673 | int thread_wakeup_needed; |
| 672 | struct completion thread_notifier; | 674 | struct completion thread_notifier; |
| 673 | struct task_struct *thread_task; | 675 | struct task_struct *thread_task; |
| @@ -694,7 +696,6 @@ struct fsg_dev { | |||
| 694 | unsigned int nluns; | 696 | unsigned int nluns; |
| 695 | struct lun *luns; | 697 | struct lun *luns; |
| 696 | struct lun *curlun; | 698 | struct lun *curlun; |
| 697 | struct completion lun_released; | ||
| 698 | }; | 699 | }; |
| 699 | 700 | ||
| 700 | typedef void (*fsg_routine_t)(struct fsg_dev *); | 701 | typedef void (*fsg_routine_t)(struct fsg_dev *); |
| @@ -1073,11 +1074,13 @@ static int populate_config_buf(struct usb_gadget *gadget, | |||
| 1073 | 1074 | ||
| 1074 | /* These routines may be called in process context or in_irq */ | 1075 | /* These routines may be called in process context or in_irq */ |
| 1075 | 1076 | ||
| 1077 | /* Caller must hold fsg->lock */ | ||
| 1076 | static void wakeup_thread(struct fsg_dev *fsg) | 1078 | static void wakeup_thread(struct fsg_dev *fsg) |
| 1077 | { | 1079 | { |
| 1078 | /* Tell the main thread that something has happened */ | 1080 | /* Tell the main thread that something has happened */ |
| 1079 | fsg->thread_wakeup_needed = 1; | 1081 | fsg->thread_wakeup_needed = 1; |
| 1080 | wake_up_all(&fsg->thread_wqh); | 1082 | if (fsg->thread_task) |
| 1083 | wake_up_process(fsg->thread_task); | ||
| 1081 | } | 1084 | } |
| 1082 | 1085 | ||
| 1083 | 1086 | ||
| @@ -1164,11 +1167,12 @@ static void bulk_in_complete(struct usb_ep *ep, struct usb_request *req) | |||
| 1164 | usb_ep_fifo_flush(ep); | 1167 | usb_ep_fifo_flush(ep); |
| 1165 | 1168 | ||
| 1166 | /* Hold the lock while we update the request and buffer states */ | 1169 | /* Hold the lock while we update the request and buffer states */ |
| 1170 | smp_wmb(); | ||
| 1167 | spin_lock(&fsg->lock); | 1171 | spin_lock(&fsg->lock); |
| 1168 | bh->inreq_busy = 0; | 1172 | bh->inreq_busy = 0; |
| 1169 | bh->state = BUF_STATE_EMPTY; | 1173 | bh->state = BUF_STATE_EMPTY; |
| 1170 | spin_unlock(&fsg->lock); | ||
| 1171 | wakeup_thread(fsg); | 1174 | wakeup_thread(fsg); |
| 1175 | spin_unlock(&fsg->lock); | ||
| 1172 | } | 1176 | } |
| 1173 | 1177 | ||
| 1174 | static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req) | 1178 | static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req) |
| @@ -1185,11 +1189,12 @@ static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req) | |||
| 1185 | usb_ep_fifo_flush(ep); | 1189 | usb_ep_fifo_flush(ep); |
| 1186 | 1190 | ||
| 1187 | /* Hold the lock while we update the request and buffer states */ | 1191 | /* Hold the lock while we update the request and buffer states */ |
| 1192 | smp_wmb(); | ||
| 1188 | spin_lock(&fsg->lock); | 1193 | spin_lock(&fsg->lock); |
| 1189 | bh->outreq_busy = 0; | 1194 | bh->outreq_busy = 0; |
| 1190 | bh->state = BUF_STATE_FULL; | 1195 | bh->state = BUF_STATE_FULL; |
| 1191 | spin_unlock(&fsg->lock); | ||
| 1192 | wakeup_thread(fsg); | 1196 | wakeup_thread(fsg); |
| 1197 | spin_unlock(&fsg->lock); | ||
| 1193 | } | 1198 | } |
| 1194 | 1199 | ||
| 1195 | 1200 | ||
| @@ -1206,11 +1211,12 @@ static void intr_in_complete(struct usb_ep *ep, struct usb_request *req) | |||
| 1206 | usb_ep_fifo_flush(ep); | 1211 | usb_ep_fifo_flush(ep); |
| 1207 | 1212 | ||
| 1208 | /* Hold the lock while we update the request and buffer states */ | 1213 | /* Hold the lock while we update the request and buffer states */ |
| 1214 | smp_wmb(); | ||
| 1209 | spin_lock(&fsg->lock); | 1215 | spin_lock(&fsg->lock); |
| 1210 | fsg->intreq_busy = 0; | 1216 | fsg->intreq_busy = 0; |
| 1211 | bh->state = BUF_STATE_EMPTY; | 1217 | bh->state = BUF_STATE_EMPTY; |
| 1212 | spin_unlock(&fsg->lock); | ||
| 1213 | wakeup_thread(fsg); | 1218 | wakeup_thread(fsg); |
| 1219 | spin_unlock(&fsg->lock); | ||
| 1214 | } | 1220 | } |
| 1215 | 1221 | ||
| 1216 | #else | 1222 | #else |
| @@ -1261,8 +1267,8 @@ static void received_cbi_adsc(struct fsg_dev *fsg, struct fsg_buffhd *bh) | |||
| 1261 | fsg->cbbuf_cmnd_size = req->actual; | 1267 | fsg->cbbuf_cmnd_size = req->actual; |
| 1262 | memcpy(fsg->cbbuf_cmnd, req->buf, fsg->cbbuf_cmnd_size); | 1268 | memcpy(fsg->cbbuf_cmnd, req->buf, fsg->cbbuf_cmnd_size); |
| 1263 | 1269 | ||
| 1264 | spin_unlock(&fsg->lock); | ||
| 1265 | wakeup_thread(fsg); | 1270 | wakeup_thread(fsg); |
| 1271 | spin_unlock(&fsg->lock); | ||
| 1266 | } | 1272 | } |
| 1267 | 1273 | ||
| 1268 | #else | 1274 | #else |
| @@ -1514,8 +1520,8 @@ static int fsg_setup(struct usb_gadget *gadget, | |||
| 1514 | 1520 | ||
| 1515 | /* Use this for bulk or interrupt transfers, not ep0 */ | 1521 | /* Use this for bulk or interrupt transfers, not ep0 */ |
| 1516 | static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep, | 1522 | static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep, |
| 1517 | struct usb_request *req, volatile int *pbusy, | 1523 | struct usb_request *req, int *pbusy, |
| 1518 | volatile enum fsg_buffer_state *state) | 1524 | enum fsg_buffer_state *state) |
| 1519 | { | 1525 | { |
| 1520 | int rc; | 1526 | int rc; |
| 1521 | 1527 | ||
| @@ -1523,8 +1529,11 @@ static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep, | |||
| 1523 | dump_msg(fsg, "bulk-in", req->buf, req->length); | 1529 | dump_msg(fsg, "bulk-in", req->buf, req->length); |
| 1524 | else if (ep == fsg->intr_in) | 1530 | else if (ep == fsg->intr_in) |
| 1525 | dump_msg(fsg, "intr-in", req->buf, req->length); | 1531 | dump_msg(fsg, "intr-in", req->buf, req->length); |
| 1532 | |||
| 1533 | spin_lock_irq(&fsg->lock); | ||
| 1526 | *pbusy = 1; | 1534 | *pbusy = 1; |
| 1527 | *state = BUF_STATE_BUSY; | 1535 | *state = BUF_STATE_BUSY; |
| 1536 | spin_unlock_irq(&fsg->lock); | ||
| 1528 | rc = usb_ep_queue(ep, req, GFP_KERNEL); | 1537 | rc = usb_ep_queue(ep, req, GFP_KERNEL); |
| 1529 | if (rc != 0) { | 1538 | if (rc != 0) { |
| 1530 | *pbusy = 0; | 1539 | *pbusy = 0; |
| @@ -1544,14 +1553,23 @@ static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep, | |||
| 1544 | 1553 | ||
| 1545 | static int sleep_thread(struct fsg_dev *fsg) | 1554 | static int sleep_thread(struct fsg_dev *fsg) |
| 1546 | { | 1555 | { |
| 1547 | int rc; | 1556 | int rc = 0; |
| 1548 | 1557 | ||
| 1549 | /* Wait until a signal arrives or we are woken up */ | 1558 | /* Wait until a signal arrives or we are woken up */ |
| 1550 | rc = wait_event_interruptible(fsg->thread_wqh, | 1559 | for (;;) { |
| 1551 | fsg->thread_wakeup_needed); | 1560 | try_to_freeze(); |
| 1561 | set_current_state(TASK_INTERRUPTIBLE); | ||
| 1562 | if (signal_pending(current)) { | ||
| 1563 | rc = -EINTR; | ||
| 1564 | break; | ||
| 1565 | } | ||
| 1566 | if (fsg->thread_wakeup_needed) | ||
| 1567 | break; | ||
| 1568 | schedule(); | ||
| 1569 | } | ||
| 1570 | __set_current_state(TASK_RUNNING); | ||
| 1552 | fsg->thread_wakeup_needed = 0; | 1571 | fsg->thread_wakeup_needed = 0; |
| 1553 | try_to_freeze(); | 1572 | return rc; |
| 1554 | return (rc ? -EINTR : 0); | ||
| 1555 | } | 1573 | } |
| 1556 | 1574 | ||
| 1557 | 1575 | ||
| @@ -1788,6 +1806,7 @@ static int do_write(struct fsg_dev *fsg) | |||
| 1788 | if (bh->state == BUF_STATE_EMPTY && !get_some_more) | 1806 | if (bh->state == BUF_STATE_EMPTY && !get_some_more) |
| 1789 | break; // We stopped early | 1807 | break; // We stopped early |
| 1790 | if (bh->state == BUF_STATE_FULL) { | 1808 | if (bh->state == BUF_STATE_FULL) { |
| 1809 | smp_rmb(); | ||
| 1791 | fsg->next_buffhd_to_drain = bh->next; | 1810 | fsg->next_buffhd_to_drain = bh->next; |
| 1792 | bh->state = BUF_STATE_EMPTY; | 1811 | bh->state = BUF_STATE_EMPTY; |
| 1793 | 1812 | ||
| @@ -2356,6 +2375,7 @@ static int throw_away_data(struct fsg_dev *fsg) | |||
| 2356 | 2375 | ||
| 2357 | /* Throw away the data in a filled buffer */ | 2376 | /* Throw away the data in a filled buffer */ |
| 2358 | if (bh->state == BUF_STATE_FULL) { | 2377 | if (bh->state == BUF_STATE_FULL) { |
| 2378 | smp_rmb(); | ||
| 2359 | bh->state = BUF_STATE_EMPTY; | 2379 | bh->state = BUF_STATE_EMPTY; |
| 2360 | fsg->next_buffhd_to_drain = bh->next; | 2380 | fsg->next_buffhd_to_drain = bh->next; |
| 2361 | 2381 | ||
| @@ -3021,6 +3041,7 @@ static int get_next_command(struct fsg_dev *fsg) | |||
| 3021 | if ((rc = sleep_thread(fsg)) != 0) | 3041 | if ((rc = sleep_thread(fsg)) != 0) |
| 3022 | return rc; | 3042 | return rc; |
| 3023 | } | 3043 | } |
| 3044 | smp_rmb(); | ||
| 3024 | rc = received_cbw(fsg, bh); | 3045 | rc = received_cbw(fsg, bh); |
| 3025 | bh->state = BUF_STATE_EMPTY; | 3046 | bh->state = BUF_STATE_EMPTY; |
| 3026 | 3047 | ||
| @@ -3642,11 +3663,19 @@ static DEVICE_ATTR(file, 0444, show_file, NULL); | |||
| 3642 | 3663 | ||
| 3643 | /*-------------------------------------------------------------------------*/ | 3664 | /*-------------------------------------------------------------------------*/ |
| 3644 | 3665 | ||
| 3666 | static void fsg_release(struct kref *ref) | ||
| 3667 | { | ||
| 3668 | struct fsg_dev *fsg = container_of(ref, struct fsg_dev, ref); | ||
| 3669 | |||
| 3670 | kfree(fsg->luns); | ||
| 3671 | kfree(fsg); | ||
| 3672 | } | ||
| 3673 | |||
| 3645 | static void lun_release(struct device *dev) | 3674 | static void lun_release(struct device *dev) |
| 3646 | { | 3675 | { |
| 3647 | struct fsg_dev *fsg = (struct fsg_dev *) dev_get_drvdata(dev); | 3676 | struct fsg_dev *fsg = (struct fsg_dev *) dev_get_drvdata(dev); |
| 3648 | 3677 | ||
| 3649 | complete(&fsg->lun_released); | 3678 | kref_put(&fsg->ref, fsg_release); |
| 3650 | } | 3679 | } |
| 3651 | 3680 | ||
| 3652 | static void fsg_unbind(struct usb_gadget *gadget) | 3681 | static void fsg_unbind(struct usb_gadget *gadget) |
| @@ -3660,14 +3689,12 @@ static void fsg_unbind(struct usb_gadget *gadget) | |||
| 3660 | clear_bit(REGISTERED, &fsg->atomic_bitflags); | 3689 | clear_bit(REGISTERED, &fsg->atomic_bitflags); |
| 3661 | 3690 | ||
| 3662 | /* Unregister the sysfs attribute files and the LUNs */ | 3691 | /* Unregister the sysfs attribute files and the LUNs */ |
| 3663 | init_completion(&fsg->lun_released); | ||
| 3664 | for (i = 0; i < fsg->nluns; ++i) { | 3692 | for (i = 0; i < fsg->nluns; ++i) { |
| 3665 | curlun = &fsg->luns[i]; | 3693 | curlun = &fsg->luns[i]; |
| 3666 | if (curlun->registered) { | 3694 | if (curlun->registered) { |
| 3667 | device_remove_file(&curlun->dev, &dev_attr_ro); | 3695 | device_remove_file(&curlun->dev, &dev_attr_ro); |
| 3668 | device_remove_file(&curlun->dev, &dev_attr_file); | 3696 | device_remove_file(&curlun->dev, &dev_attr_file); |
| 3669 | device_unregister(&curlun->dev); | 3697 | device_unregister(&curlun->dev); |
| 3670 | wait_for_completion(&fsg->lun_released); | ||
| 3671 | curlun->registered = 0; | 3698 | curlun->registered = 0; |
| 3672 | } | 3699 | } |
| 3673 | } | 3700 | } |
| @@ -3846,6 +3873,7 @@ static int __init fsg_bind(struct usb_gadget *gadget) | |||
| 3846 | curlun->dev.release = lun_release; | 3873 | curlun->dev.release = lun_release; |
| 3847 | device_create_file(&curlun->dev, &dev_attr_ro); | 3874 | device_create_file(&curlun->dev, &dev_attr_ro); |
| 3848 | device_create_file(&curlun->dev, &dev_attr_file); | 3875 | device_create_file(&curlun->dev, &dev_attr_file); |
| 3876 | kref_get(&fsg->ref); | ||
| 3849 | } | 3877 | } |
| 3850 | 3878 | ||
| 3851 | if (file[i] && *file[i]) { | 3879 | if (file[i] && *file[i]) { |
| @@ -4061,7 +4089,7 @@ static int __init fsg_alloc(void) | |||
| 4061 | return -ENOMEM; | 4089 | return -ENOMEM; |
| 4062 | spin_lock_init(&fsg->lock); | 4090 | spin_lock_init(&fsg->lock); |
| 4063 | init_rwsem(&fsg->filesem); | 4091 | init_rwsem(&fsg->filesem); |
| 4064 | init_waitqueue_head(&fsg->thread_wqh); | 4092 | kref_init(&fsg->ref); |
| 4065 | init_completion(&fsg->thread_notifier); | 4093 | init_completion(&fsg->thread_notifier); |
| 4066 | 4094 | ||
| 4067 | the_fsg = fsg; | 4095 | the_fsg = fsg; |
| @@ -4069,13 +4097,6 @@ static int __init fsg_alloc(void) | |||
| 4069 | } | 4097 | } |
| 4070 | 4098 | ||
| 4071 | 4099 | ||
| 4072 | static void fsg_free(struct fsg_dev *fsg) | ||
| 4073 | { | ||
| 4074 | kfree(fsg->luns); | ||
| 4075 | kfree(fsg); | ||
| 4076 | } | ||
| 4077 | |||
| 4078 | |||
| 4079 | static int __init fsg_init(void) | 4100 | static int __init fsg_init(void) |
| 4080 | { | 4101 | { |
| 4081 | int rc; | 4102 | int rc; |
| @@ -4085,7 +4106,7 @@ static int __init fsg_init(void) | |||
| 4085 | return rc; | 4106 | return rc; |
| 4086 | fsg = the_fsg; | 4107 | fsg = the_fsg; |
| 4087 | if ((rc = usb_gadget_register_driver(&fsg_driver)) != 0) | 4108 | if ((rc = usb_gadget_register_driver(&fsg_driver)) != 0) |
| 4088 | fsg_free(fsg); | 4109 | kref_put(&fsg->ref, fsg_release); |
| 4089 | return rc; | 4110 | return rc; |
| 4090 | } | 4111 | } |
| 4091 | module_init(fsg_init); | 4112 | module_init(fsg_init); |
| @@ -4103,6 +4124,6 @@ static void __exit fsg_cleanup(void) | |||
| 4103 | wait_for_completion(&fsg->thread_notifier); | 4124 | wait_for_completion(&fsg->thread_notifier); |
| 4104 | 4125 | ||
| 4105 | close_all_backing_files(fsg); | 4126 | close_all_backing_files(fsg); |
| 4106 | fsg_free(fsg); | 4127 | kref_put(&fsg->ref, fsg_release); |
| 4107 | } | 4128 | } |
| 4108 | module_exit(fsg_cleanup); | 4129 | module_exit(fsg_cleanup); |
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index b35ac6d334f8..65e084a2c87e 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c | |||
| @@ -890,10 +890,12 @@ static void gs_close(struct tty_struct *tty, struct file *file) | |||
| 890 | /* wait for write buffer to drain, or */ | 890 | /* wait for write buffer to drain, or */ |
| 891 | /* at most GS_CLOSE_TIMEOUT seconds */ | 891 | /* at most GS_CLOSE_TIMEOUT seconds */ |
| 892 | if (gs_buf_data_avail(port->port_write_buf) > 0) { | 892 | if (gs_buf_data_avail(port->port_write_buf) > 0) { |
| 893 | spin_unlock_irqrestore(&port->port_lock, flags); | ||
| 893 | wait_cond_interruptible_timeout(port->port_write_wait, | 894 | wait_cond_interruptible_timeout(port->port_write_wait, |
| 894 | port->port_dev == NULL | 895 | port->port_dev == NULL |
| 895 | || gs_buf_data_avail(port->port_write_buf) == 0, | 896 | || gs_buf_data_avail(port->port_write_buf) == 0, |
| 896 | &port->port_lock, flags, GS_CLOSE_TIMEOUT * HZ); | 897 | &port->port_lock, flags, GS_CLOSE_TIMEOUT * HZ); |
| 898 | spin_lock_irqsave(&port->port_lock, flags); | ||
| 897 | } | 899 | } |
| 898 | 900 | ||
| 899 | /* free disconnected port on final close */ | 901 | /* free disconnected port on final close */ |
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 58321d3f314c..e3020f4b17be 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile | |||
| @@ -2,6 +2,10 @@ | |||
| 2 | # Makefile for USB Host Controller Drivers | 2 | # Makefile for USB Host Controller Drivers |
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | ifeq ($(CONFIG_USB_DEBUG),y) | ||
| 6 | EXTRA_CFLAGS += -DDEBUG | ||
| 7 | endif | ||
| 8 | |||
| 5 | obj-$(CONFIG_PCI) += pci-quirks.o | 9 | obj-$(CONFIG_PCI) += pci-quirks.o |
| 6 | 10 | ||
| 7 | obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o | 11 | obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o |
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 29f52a44b928..9dd3d14c64f3 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
| @@ -17,13 +17,6 @@ | |||
| 17 | */ | 17 | */ |
| 18 | 18 | ||
| 19 | #include <linux/config.h> | 19 | #include <linux/config.h> |
| 20 | |||
| 21 | #ifdef CONFIG_USB_DEBUG | ||
| 22 | #define DEBUG | ||
| 23 | #else | ||
| 24 | #undef DEBUG | ||
| 25 | #endif | ||
| 26 | |||
| 27 | #include <linux/module.h> | 20 | #include <linux/module.h> |
| 28 | #include <linux/pci.h> | 21 | #include <linux/pci.h> |
| 29 | #include <linux/dmapool.h> | 22 | #include <linux/dmapool.h> |
| @@ -624,7 +617,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd, struct pt_regs *regs) | |||
| 624 | } | 617 | } |
| 625 | 618 | ||
| 626 | /* remote wakeup [4.3.1] */ | 619 | /* remote wakeup [4.3.1] */ |
| 627 | if ((status & STS_PCD) && hcd->remote_wakeup) { | 620 | if (status & STS_PCD) { |
| 628 | unsigned i = HCS_N_PORTS (ehci->hcs_params); | 621 | unsigned i = HCS_N_PORTS (ehci->hcs_params); |
| 629 | 622 | ||
| 630 | /* resume root hub? */ | 623 | /* resume root hub? */ |
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 82caf336e9b6..69b0b9be7a64 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c | |||
| @@ -59,7 +59,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) | |||
| 59 | 59 | ||
| 60 | if ((t1 & PORT_PE) && !(t1 & PORT_OWNER)) | 60 | if ((t1 & PORT_PE) && !(t1 & PORT_OWNER)) |
| 61 | t2 |= PORT_SUSPEND; | 61 | t2 |= PORT_SUSPEND; |
| 62 | if (hcd->remote_wakeup) | 62 | if (device_may_wakeup(&hcd->self.root_hub->dev)) |
| 63 | t2 |= PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E; | 63 | t2 |= PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E; |
| 64 | else | 64 | else |
| 65 | t2 &= ~(PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E); | 65 | t2 &= ~(PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E); |
| @@ -517,7 +517,7 @@ static int ehci_hub_control ( | |||
| 517 | if ((temp & PORT_PE) == 0 | 517 | if ((temp & PORT_PE) == 0 |
| 518 | || (temp & PORT_RESET) != 0) | 518 | || (temp & PORT_RESET) != 0) |
| 519 | goto error; | 519 | goto error; |
| 520 | if (hcd->remote_wakeup) | 520 | if (device_may_wakeup(&hcd->self.root_hub->dev)) |
| 521 | temp |= PORT_WAKE_BITS; | 521 | temp |= PORT_WAKE_BITS; |
| 522 | writel (temp | PORT_SUSPEND, | 522 | writel (temp | PORT_SUSPEND, |
| 523 | &ehci->regs->port_status [wIndex]); | 523 | &ehci->regs->port_status [wIndex]); |
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 13f73a836e45..08ca0f849dab 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c | |||
| @@ -210,7 +210,16 @@ static int ehci_pci_setup(struct usb_hcd *hcd) | |||
| 210 | /* Serial Bus Release Number is at PCI 0x60 offset */ | 210 | /* Serial Bus Release Number is at PCI 0x60 offset */ |
| 211 | pci_read_config_byte(pdev, 0x60, &ehci->sbrn); | 211 | pci_read_config_byte(pdev, 0x60, &ehci->sbrn); |
| 212 | 212 | ||
| 213 | /* REVISIT: per-port wake capability (PCI 0x62) currently unused */ | 213 | /* Workaround current PCI init glitch: wakeup bits aren't |
| 214 | * being set from PCI PM capability. | ||
| 215 | */ | ||
| 216 | if (!device_can_wakeup(&pdev->dev)) { | ||
| 217 | u16 port_wake; | ||
| 218 | |||
| 219 | pci_read_config_word(pdev, 0x62, &port_wake); | ||
| 220 | if (port_wake & 0x0001) | ||
| 221 | device_init_wakeup(&pdev->dev, 1); | ||
| 222 | } | ||
| 214 | 223 | ||
| 215 | retval = ehci_pci_reinit(ehci, pdev); | 224 | retval = ehci_pci_reinit(ehci, pdev); |
| 216 | done: | 225 | done: |
| @@ -269,7 +278,6 @@ static int ehci_pci_resume(struct usb_hcd *hcd) | |||
| 269 | { | 278 | { |
| 270 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | 279 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); |
| 271 | unsigned port; | 280 | unsigned port; |
| 272 | struct usb_device *root = hcd->self.root_hub; | ||
| 273 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); | 281 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); |
| 274 | int retval = -EINVAL; | 282 | int retval = -EINVAL; |
| 275 | 283 | ||
| @@ -303,13 +311,7 @@ static int ehci_pci_resume(struct usb_hcd *hcd) | |||
| 303 | 311 | ||
| 304 | restart: | 312 | restart: |
| 305 | ehci_dbg(ehci, "lost power, restarting\n"); | 313 | ehci_dbg(ehci, "lost power, restarting\n"); |
| 306 | for (port = HCS_N_PORTS(ehci->hcs_params); port > 0; ) { | 314 | usb_root_hub_lost_power(hcd->self.root_hub); |
| 307 | port--; | ||
| 308 | if (!root->children [port]) | ||
| 309 | continue; | ||
| 310 | usb_set_device_state(root->children[port], | ||
| 311 | USB_STATE_NOTATTACHED); | ||
| 312 | } | ||
| 313 | 315 | ||
| 314 | /* Else reset, to cope with power loss or flush-to-storage | 316 | /* Else reset, to cope with power loss or flush-to-storage |
| 315 | * style "resume" having let BIOS kick in during reboot. | 317 | * style "resume" having let BIOS kick in during reboot. |
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index bf03ec0d8ee2..9b13bf2fa98d 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c | |||
| @@ -514,18 +514,18 @@ qh_urb_transaction ( | |||
| 514 | qtd->urb = urb; | 514 | qtd->urb = urb; |
| 515 | qtd_prev->hw_next = QTD_NEXT (qtd->qtd_dma); | 515 | qtd_prev->hw_next = QTD_NEXT (qtd->qtd_dma); |
| 516 | list_add_tail (&qtd->qtd_list, head); | 516 | list_add_tail (&qtd->qtd_list, head); |
| 517 | |||
| 518 | /* for zero length DATA stages, STATUS is always IN */ | ||
| 519 | if (len == 0) | ||
| 520 | token |= (1 /* "in" */ << 8); | ||
| 517 | } | 521 | } |
| 518 | 522 | ||
| 519 | /* | 523 | /* |
| 520 | * data transfer stage: buffer setup | 524 | * data transfer stage: buffer setup |
| 521 | */ | 525 | */ |
| 522 | if (likely (len > 0)) | 526 | buf = urb->transfer_dma; |
| 523 | buf = urb->transfer_dma; | ||
| 524 | else | ||
| 525 | buf = 0; | ||
| 526 | 527 | ||
| 527 | /* for zero length DATA stages, STATUS is always IN */ | 528 | if (is_input) |
| 528 | if (!buf || is_input) | ||
| 529 | token |= (1 /* "in" */ << 8); | 529 | token |= (1 /* "in" */ << 8); |
| 530 | /* else it's already initted to "out" pid (0 << 8) */ | 530 | /* else it's already initted to "out" pid (0 << 8) */ |
| 531 | 531 | ||
| @@ -572,7 +572,7 @@ qh_urb_transaction ( | |||
| 572 | * control requests may need a terminating data "status" ack; | 572 | * control requests may need a terminating data "status" ack; |
| 573 | * bulk ones may need a terminating short packet (zero length). | 573 | * bulk ones may need a terminating short packet (zero length). |
| 574 | */ | 574 | */ |
| 575 | if (likely (buf != 0)) { | 575 | if (likely (urb->transfer_buffer_length != 0)) { |
| 576 | int one_more = 0; | 576 | int one_more = 0; |
| 577 | 577 | ||
| 578 | if (usb_pipecontrol (urb->pipe)) { | 578 | if (usb_pipecontrol (urb->pipe)) { |
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index 82f64986bc22..584b8dc65119 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c | |||
| @@ -55,19 +55,13 @@ | |||
| 55 | /* enqueuing/finishing log of urbs */ | 55 | /* enqueuing/finishing log of urbs */ |
| 56 | //#define URB_TRACE | 56 | //#define URB_TRACE |
| 57 | 57 | ||
| 58 | #include <linux/config.h> | ||
| 59 | #include <linux/module.h> | 58 | #include <linux/module.h> |
| 60 | #include <linux/moduleparam.h> | ||
| 61 | #include <linux/kernel.h> | ||
| 62 | #include <linux/delay.h> | 59 | #include <linux/delay.h> |
| 63 | #include <linux/ioport.h> | 60 | #include <linux/debugfs.h> |
| 64 | #include <linux/sched.h> | 61 | #include <linux/seq_file.h> |
| 65 | #include <linux/slab.h> | ||
| 66 | #include <linux/smp_lock.h> | ||
| 67 | #include <linux/errno.h> | 62 | #include <linux/errno.h> |
| 68 | #include <linux/init.h> | 63 | #include <linux/init.h> |
| 69 | #include <linux/list.h> | 64 | #include <linux/list.h> |
| 70 | #include <linux/interrupt.h> | ||
| 71 | #include <linux/usb.h> | 65 | #include <linux/usb.h> |
| 72 | #include <linux/usb_isp116x.h> | 66 | #include <linux/usb_isp116x.h> |
| 73 | #include <linux/platform_device.h> | 67 | #include <linux/platform_device.h> |
| @@ -77,14 +71,10 @@ | |||
| 77 | #include <asm/system.h> | 71 | #include <asm/system.h> |
| 78 | #include <asm/byteorder.h> | 72 | #include <asm/byteorder.h> |
| 79 | 73 | ||
| 80 | #ifndef DEBUG | ||
| 81 | # define STUB_DEBUG_FILE | ||
| 82 | #endif | ||
| 83 | |||
| 84 | #include "../core/hcd.h" | 74 | #include "../core/hcd.h" |
| 85 | #include "isp116x.h" | 75 | #include "isp116x.h" |
| 86 | 76 | ||
| 87 | #define DRIVER_VERSION "05 Aug 2005" | 77 | #define DRIVER_VERSION "03 Nov 2005" |
| 88 | #define DRIVER_DESC "ISP116x USB Host Controller Driver" | 78 | #define DRIVER_DESC "ISP116x USB Host Controller Driver" |
| 89 | 79 | ||
| 90 | MODULE_DESCRIPTION(DRIVER_DESC); | 80 | MODULE_DESCRIPTION(DRIVER_DESC); |
| @@ -164,13 +154,11 @@ static void pack_fifo(struct isp116x *isp116x) | |||
| 164 | struct ptd *ptd; | 154 | struct ptd *ptd; |
| 165 | int buflen = isp116x->atl_last_dir == PTD_DIR_IN | 155 | int buflen = isp116x->atl_last_dir == PTD_DIR_IN |
| 166 | ? isp116x->atl_bufshrt : isp116x->atl_buflen; | 156 | ? isp116x->atl_bufshrt : isp116x->atl_buflen; |
| 167 | int ptd_count = 0; | ||
| 168 | 157 | ||
| 169 | isp116x_write_reg16(isp116x, HCuPINT, HCuPINT_AIIEOT); | 158 | isp116x_write_reg16(isp116x, HCuPINT, HCuPINT_AIIEOT); |
| 170 | isp116x_write_reg16(isp116x, HCXFERCTR, buflen); | 159 | isp116x_write_reg16(isp116x, HCXFERCTR, buflen); |
| 171 | isp116x_write_addr(isp116x, HCATLPORT | ISP116x_WRITE_OFFSET); | 160 | isp116x_write_addr(isp116x, HCATLPORT | ISP116x_WRITE_OFFSET); |
| 172 | for (ep = isp116x->atl_active; ep; ep = ep->active) { | 161 | for (ep = isp116x->atl_active; ep; ep = ep->active) { |
| 173 | ++ptd_count; | ||
| 174 | ptd = &ep->ptd; | 162 | ptd = &ep->ptd; |
| 175 | dump_ptd(ptd); | 163 | dump_ptd(ptd); |
| 176 | dump_ptd_out_data(ptd, ep->data); | 164 | dump_ptd_out_data(ptd, ep->data); |
| @@ -305,9 +293,8 @@ static void postproc_atl_queue(struct isp116x *isp116x) | |||
| 305 | udev = urb->dev; | 293 | udev = urb->dev; |
| 306 | ptd = &ep->ptd; | 294 | ptd = &ep->ptd; |
| 307 | cc = PTD_GET_CC(ptd); | 295 | cc = PTD_GET_CC(ptd); |
| 308 | |||
| 309 | spin_lock(&urb->lock); | ||
| 310 | short_not_ok = 1; | 296 | short_not_ok = 1; |
| 297 | spin_lock(&urb->lock); | ||
| 311 | 298 | ||
| 312 | /* Data underrun is special. For allowed underrun | 299 | /* Data underrun is special. For allowed underrun |
| 313 | we clear the error and continue as normal. For | 300 | we clear the error and continue as normal. For |
| @@ -420,7 +407,7 @@ static void postproc_atl_queue(struct isp116x *isp116x) | |||
| 420 | ep->nextpid = 0; | 407 | ep->nextpid = 0; |
| 421 | break; | 408 | break; |
| 422 | default: | 409 | default: |
| 423 | BUG_ON(1); | 410 | BUG(); |
| 424 | } | 411 | } |
| 425 | spin_unlock(&urb->lock); | 412 | spin_unlock(&urb->lock); |
| 426 | } | 413 | } |
| @@ -628,8 +615,12 @@ static irqreturn_t isp116x_irq(struct usb_hcd *hcd, struct pt_regs *regs) | |||
| 628 | u32 intstat = isp116x_read_reg32(isp116x, HCINTSTAT); | 615 | u32 intstat = isp116x_read_reg32(isp116x, HCINTSTAT); |
| 629 | isp116x_write_reg32(isp116x, HCINTSTAT, intstat); | 616 | isp116x_write_reg32(isp116x, HCINTSTAT, intstat); |
| 630 | if (intstat & HCINT_UE) { | 617 | if (intstat & HCINT_UE) { |
| 631 | ERR("Unrecoverable error\n"); | 618 | ERR("Unrecoverable error, HC is dead!\n"); |
| 632 | /* What should we do here? Reset? */ | 619 | /* IRQ's are off, we do no DMA, |
| 620 | perfectly ready to die ... */ | ||
| 621 | hcd->state = HC_STATE_HALT; | ||
| 622 | ret = IRQ_HANDLED; | ||
| 623 | goto done; | ||
| 633 | } | 624 | } |
| 634 | if (intstat & HCINT_RHSC) | 625 | if (intstat & HCINT_RHSC) |
| 635 | /* When root hub or any of its ports is going | 626 | /* When root hub or any of its ports is going |
| @@ -640,7 +631,6 @@ static irqreturn_t isp116x_irq(struct usb_hcd *hcd, struct pt_regs *regs) | |||
| 640 | if (intstat & HCINT_RD) { | 631 | if (intstat & HCINT_RD) { |
| 641 | DBG("---- remote wakeup\n"); | 632 | DBG("---- remote wakeup\n"); |
| 642 | usb_hcd_resume_root_hub(hcd); | 633 | usb_hcd_resume_root_hub(hcd); |
| 643 | ret = IRQ_HANDLED; | ||
| 644 | } | 634 | } |
| 645 | irqstat &= ~HCuPINT_OPR; | 635 | irqstat &= ~HCuPINT_OPR; |
| 646 | ret = IRQ_HANDLED; | 636 | ret = IRQ_HANDLED; |
| @@ -651,6 +641,7 @@ static irqreturn_t isp116x_irq(struct usb_hcd *hcd, struct pt_regs *regs) | |||
| 651 | } | 641 | } |
| 652 | 642 | ||
| 653 | isp116x_write_reg16(isp116x, HCuPINTENB, isp116x->irqenb); | 643 | isp116x_write_reg16(isp116x, HCuPINTENB, isp116x->irqenb); |
| 644 | done: | ||
| 654 | spin_unlock(&isp116x->lock); | 645 | spin_unlock(&isp116x->lock); |
| 655 | return ret; | 646 | return ret; |
| 656 | } | 647 | } |
| @@ -724,6 +715,7 @@ static int isp116x_urb_enqueue(struct usb_hcd *hcd, | |||
| 724 | 715 | ||
| 725 | spin_lock_irqsave(&isp116x->lock, flags); | 716 | spin_lock_irqsave(&isp116x->lock, flags); |
| 726 | if (!HC_IS_RUNNING(hcd->state)) { | 717 | if (!HC_IS_RUNNING(hcd->state)) { |
| 718 | kfree(ep); | ||
| 727 | ret = -ENODEV; | 719 | ret = -ENODEV; |
| 728 | goto fail; | 720 | goto fail; |
| 729 | } | 721 | } |
| @@ -888,7 +880,7 @@ static void isp116x_endpoint_disable(struct usb_hcd *hcd, | |||
| 888 | struct usb_host_endpoint *hep) | 880 | struct usb_host_endpoint *hep) |
| 889 | { | 881 | { |
| 890 | int i; | 882 | int i; |
| 891 | struct isp116x_ep *ep = hep->hcpriv;; | 883 | struct isp116x_ep *ep = hep->hcpriv; |
| 892 | 884 | ||
| 893 | if (!ep) | 885 | if (!ep) |
| 894 | return; | 886 | return; |
| @@ -916,8 +908,6 @@ static int isp116x_get_frame(struct usb_hcd *hcd) | |||
| 916 | return (int)fmnum; | 908 | return (int)fmnum; |
| 917 | } | 909 | } |
| 918 | 910 | ||
| 919 | /*----------------------------------------------------------------*/ | ||
| 920 | |||
| 921 | /* | 911 | /* |
| 922 | Adapted from ohci-hub.c. Currently we don't support autosuspend. | 912 | Adapted from ohci-hub.c. Currently we don't support autosuspend. |
| 923 | */ | 913 | */ |
| @@ -968,11 +958,10 @@ static void isp116x_hub_descriptor(struct isp116x *isp116x, | |||
| 968 | desc->bHubContrCurrent = 0; | 958 | desc->bHubContrCurrent = 0; |
| 969 | desc->bNbrPorts = (u8) (reg & 0x3); | 959 | desc->bNbrPorts = (u8) (reg & 0x3); |
| 970 | /* Power switching, device type, overcurrent. */ | 960 | /* Power switching, device type, overcurrent. */ |
| 971 | desc->wHubCharacteristics = | 961 | desc->wHubCharacteristics = cpu_to_le16((u16) ((reg >> 8) & 0x1f)); |
| 972 | (__force __u16) cpu_to_le16((u16) ((reg >> 8) & 0x1f)); | ||
| 973 | desc->bPwrOn2PwrGood = (u8) ((reg >> 24) & 0xff); | 962 | desc->bPwrOn2PwrGood = (u8) ((reg >> 24) & 0xff); |
| 974 | /* two bitmaps: ports removable, and legacy PortPwrCtrlMask */ | 963 | /* two bitmaps: ports removable, and legacy PortPwrCtrlMask */ |
| 975 | desc->bitmap[0] = desc->bNbrPorts == 1 ? 1 << 1 : 3 << 1; | 964 | desc->bitmap[0] = 0; |
| 976 | desc->bitmap[1] = ~0; | 965 | desc->bitmap[1] = ~0; |
| 977 | } | 966 | } |
| 978 | 967 | ||
| @@ -1159,135 +1148,9 @@ static int isp116x_hub_control(struct usb_hcd *hcd, | |||
| 1159 | return ret; | 1148 | return ret; |
| 1160 | } | 1149 | } |
| 1161 | 1150 | ||
| 1162 | #ifdef CONFIG_PM | ||
| 1163 | |||
| 1164 | static int isp116x_bus_suspend(struct usb_hcd *hcd) | ||
| 1165 | { | ||
| 1166 | struct isp116x *isp116x = hcd_to_isp116x(hcd); | ||
| 1167 | unsigned long flags; | ||
| 1168 | u32 val; | ||
| 1169 | int ret = 0; | ||
| 1170 | |||
| 1171 | spin_lock_irqsave(&isp116x->lock, flags); | ||
| 1172 | |||
| 1173 | val = isp116x_read_reg32(isp116x, HCCONTROL); | ||
| 1174 | switch (val & HCCONTROL_HCFS) { | ||
| 1175 | case HCCONTROL_USB_OPER: | ||
| 1176 | hcd->state = HC_STATE_QUIESCING; | ||
| 1177 | val &= (~HCCONTROL_HCFS & ~HCCONTROL_RWE); | ||
| 1178 | val |= HCCONTROL_USB_SUSPEND; | ||
| 1179 | if (hcd->remote_wakeup) | ||
| 1180 | val |= HCCONTROL_RWE; | ||
| 1181 | /* Wait for usb transfers to finish */ | ||
| 1182 | mdelay(2); | ||
| 1183 | isp116x_write_reg32(isp116x, HCCONTROL, val); | ||
| 1184 | hcd->state = HC_STATE_SUSPENDED; | ||
| 1185 | /* Wait for devices to suspend */ | ||
| 1186 | mdelay(5); | ||
| 1187 | case HCCONTROL_USB_SUSPEND: | ||
| 1188 | break; | ||
| 1189 | case HCCONTROL_USB_RESUME: | ||
| 1190 | isp116x_write_reg32(isp116x, HCCONTROL, | ||
| 1191 | (val & ~HCCONTROL_HCFS) | | ||
| 1192 | HCCONTROL_USB_RESET); | ||
| 1193 | case HCCONTROL_USB_RESET: | ||
| 1194 | ret = -EBUSY; | ||
| 1195 | break; | ||
| 1196 | default: | ||
| 1197 | ret = -EINVAL; | ||
| 1198 | } | ||
| 1199 | |||
| 1200 | spin_unlock_irqrestore(&isp116x->lock, flags); | ||
| 1201 | return ret; | ||
| 1202 | } | ||
| 1203 | |||
| 1204 | static int isp116x_bus_resume(struct usb_hcd *hcd) | ||
| 1205 | { | ||
| 1206 | struct isp116x *isp116x = hcd_to_isp116x(hcd); | ||
| 1207 | u32 val; | ||
| 1208 | int ret = -EINPROGRESS; | ||
| 1209 | |||
| 1210 | msleep(5); | ||
| 1211 | spin_lock_irq(&isp116x->lock); | ||
| 1212 | |||
| 1213 | val = isp116x_read_reg32(isp116x, HCCONTROL); | ||
| 1214 | switch (val & HCCONTROL_HCFS) { | ||
| 1215 | case HCCONTROL_USB_SUSPEND: | ||
| 1216 | val &= ~HCCONTROL_HCFS; | ||
| 1217 | val |= HCCONTROL_USB_RESUME; | ||
| 1218 | isp116x_write_reg32(isp116x, HCCONTROL, val); | ||
| 1219 | case HCCONTROL_USB_RESUME: | ||
| 1220 | break; | ||
| 1221 | case HCCONTROL_USB_OPER: | ||
| 1222 | /* Without setting power_state here the | ||
| 1223 | SUSPENDED state won't be removed from | ||
| 1224 | sysfs/usbN/power.state as a response to remote | ||
| 1225 | wakeup. Maybe in the future. */ | ||
| 1226 | hcd->self.root_hub->dev.power.power_state = PMSG_ON; | ||
| 1227 | ret = 0; | ||
| 1228 | break; | ||
| 1229 | default: | ||
| 1230 | ret = -EBUSY; | ||
| 1231 | } | ||
| 1232 | |||
| 1233 | if (ret != -EINPROGRESS) { | ||
| 1234 | spin_unlock_irq(&isp116x->lock); | ||
| 1235 | return ret; | ||
| 1236 | } | ||
| 1237 | |||
| 1238 | val = isp116x->rhdesca & RH_A_NDP; | ||
| 1239 | while (val--) { | ||
| 1240 | u32 stat = | ||
| 1241 | isp116x_read_reg32(isp116x, val ? HCRHPORT2 : HCRHPORT1); | ||
| 1242 | /* force global, not selective, resume */ | ||
| 1243 | if (!(stat & RH_PS_PSS)) | ||
| 1244 | continue; | ||
| 1245 | DBG("%s: Resuming port %d\n", __func__, val); | ||
| 1246 | isp116x_write_reg32(isp116x, RH_PS_POCI, val | ||
| 1247 | ? HCRHPORT2 : HCRHPORT1); | ||
| 1248 | } | ||
| 1249 | spin_unlock_irq(&isp116x->lock); | ||
| 1250 | |||
| 1251 | hcd->state = HC_STATE_RESUMING; | ||
| 1252 | mdelay(20); | ||
| 1253 | |||
| 1254 | /* Go operational */ | ||
| 1255 | spin_lock_irq(&isp116x->lock); | ||
| 1256 | val = isp116x_read_reg32(isp116x, HCCONTROL); | ||
| 1257 | isp116x_write_reg32(isp116x, HCCONTROL, | ||
| 1258 | (val & ~HCCONTROL_HCFS) | HCCONTROL_USB_OPER); | ||
| 1259 | spin_unlock_irq(&isp116x->lock); | ||
| 1260 | /* see analogous comment above */ | ||
| 1261 | hcd->self.root_hub->dev.power.power_state = PMSG_ON; | ||
| 1262 | hcd->state = HC_STATE_RUNNING; | ||
| 1263 | |||
| 1264 | return 0; | ||
| 1265 | } | ||
| 1266 | |||
| 1267 | |||
| 1268 | #else | ||
| 1269 | |||
| 1270 | #define isp116x_bus_suspend NULL | ||
| 1271 | #define isp116x_bus_resume NULL | ||
| 1272 | |||
| 1273 | #endif | ||
| 1274 | |||
| 1275 | /*-----------------------------------------------------------------*/ | 1151 | /*-----------------------------------------------------------------*/ |
| 1276 | 1152 | ||
| 1277 | #ifdef STUB_DEBUG_FILE | 1153 | #ifdef CONFIG_DEBUG_FS |
| 1278 | |||
| 1279 | static inline void create_debug_file(struct isp116x *isp116x) | ||
| 1280 | { | ||
| 1281 | } | ||
| 1282 | |||
| 1283 | static inline void remove_debug_file(struct isp116x *isp116x) | ||
| 1284 | { | ||
| 1285 | } | ||
| 1286 | |||
| 1287 | #else | ||
| 1288 | |||
| 1289 | #include <linux/proc_fs.h> | ||
| 1290 | #include <linux/seq_file.h> | ||
| 1291 | 1154 | ||
| 1292 | static void dump_irq(struct seq_file *s, char *label, u16 mask) | 1155 | static void dump_irq(struct seq_file *s, char *label, u16 mask) |
| 1293 | { | 1156 | { |
| @@ -1311,13 +1174,9 @@ static void dump_int(struct seq_file *s, char *label, u32 mask) | |||
| 1311 | mask & HCINT_SF ? " sof" : "", mask & HCINT_SO ? " so" : ""); | 1174 | mask & HCINT_SF ? " sof" : "", mask & HCINT_SO ? " so" : ""); |
| 1312 | } | 1175 | } |
| 1313 | 1176 | ||
| 1314 | static int proc_isp116x_show(struct seq_file *s, void *unused) | 1177 | static int isp116x_show_dbg(struct seq_file *s, void *unused) |
| 1315 | { | 1178 | { |
| 1316 | struct isp116x *isp116x = s->private; | 1179 | struct isp116x *isp116x = s->private; |
| 1317 | struct isp116x_ep *ep; | ||
| 1318 | struct urb *urb; | ||
| 1319 | unsigned i; | ||
| 1320 | char *str; | ||
| 1321 | 1180 | ||
| 1322 | seq_printf(s, "%s\n%s version %s\n", | 1181 | seq_printf(s, "%s\n%s version %s\n", |
| 1323 | isp116x_to_hcd(isp116x)->product_desc, hcd_name, | 1182 | isp116x_to_hcd(isp116x)->product_desc, hcd_name, |
| @@ -1333,105 +1192,50 @@ static int proc_isp116x_show(struct seq_file *s, void *unused) | |||
| 1333 | } | 1192 | } |
| 1334 | 1193 | ||
| 1335 | spin_lock_irq(&isp116x->lock); | 1194 | spin_lock_irq(&isp116x->lock); |
| 1336 | |||
| 1337 | dump_irq(s, "hc_irq_enable", isp116x_read_reg16(isp116x, HCuPINTENB)); | 1195 | dump_irq(s, "hc_irq_enable", isp116x_read_reg16(isp116x, HCuPINTENB)); |
| 1338 | dump_irq(s, "hc_irq_status", isp116x_read_reg16(isp116x, HCuPINT)); | 1196 | dump_irq(s, "hc_irq_status", isp116x_read_reg16(isp116x, HCuPINT)); |
| 1339 | dump_int(s, "hc_int_enable", isp116x_read_reg32(isp116x, HCINTENB)); | 1197 | dump_int(s, "hc_int_enable", isp116x_read_reg32(isp116x, HCINTENB)); |
| 1340 | dump_int(s, "hc_int_status", isp116x_read_reg32(isp116x, HCINTSTAT)); | 1198 | dump_int(s, "hc_int_status", isp116x_read_reg32(isp116x, HCINTSTAT)); |
| 1341 | 1199 | isp116x_show_regs_seq(isp116x, s); | |
| 1342 | list_for_each_entry(ep, &isp116x->async, schedule) { | ||
| 1343 | |||
| 1344 | switch (ep->nextpid) { | ||
| 1345 | case USB_PID_IN: | ||
| 1346 | str = "in"; | ||
| 1347 | break; | ||
| 1348 | case USB_PID_OUT: | ||
| 1349 | str = "out"; | ||
| 1350 | break; | ||
| 1351 | case USB_PID_SETUP: | ||
| 1352 | str = "setup"; | ||
| 1353 | break; | ||
| 1354 | case USB_PID_ACK: | ||
| 1355 | str = "status"; | ||
| 1356 | break; | ||
| 1357 | default: | ||
| 1358 | str = "?"; | ||
| 1359 | break; | ||
| 1360 | }; | ||
| 1361 | seq_printf(s, "%p, ep%d%s, maxpacket %d:\n", ep, | ||
| 1362 | ep->epnum, str, ep->maxpacket); | ||
| 1363 | list_for_each_entry(urb, &ep->hep->urb_list, urb_list) { | ||
| 1364 | seq_printf(s, " urb%p, %d/%d\n", urb, | ||
| 1365 | urb->actual_length, | ||
| 1366 | urb->transfer_buffer_length); | ||
| 1367 | } | ||
| 1368 | } | ||
| 1369 | if (!list_empty(&isp116x->async)) | ||
| 1370 | seq_printf(s, "\n"); | ||
| 1371 | |||
| 1372 | seq_printf(s, "periodic size= %d\n", PERIODIC_SIZE); | ||
| 1373 | |||
| 1374 | for (i = 0; i < PERIODIC_SIZE; i++) { | ||
| 1375 | ep = isp116x->periodic[i]; | ||
| 1376 | if (!ep) | ||
| 1377 | continue; | ||
| 1378 | seq_printf(s, "%2d [%3d]:\n", i, isp116x->load[i]); | ||
| 1379 | |||
| 1380 | /* DUMB: prints shared entries multiple times */ | ||
| 1381 | do { | ||
| 1382 | seq_printf(s, " %d/%p (%sdev%d ep%d%s max %d)\n", | ||
| 1383 | ep->period, ep, | ||
| 1384 | (ep->udev->speed == | ||
| 1385 | USB_SPEED_FULL) ? "" : "ls ", | ||
| 1386 | ep->udev->devnum, ep->epnum, | ||
| 1387 | (ep->epnum == | ||
| 1388 | 0) ? "" : ((ep->nextpid == | ||
| 1389 | USB_PID_IN) ? "in" : "out"), | ||
| 1390 | ep->maxpacket); | ||
| 1391 | ep = ep->next; | ||
| 1392 | } while (ep); | ||
| 1393 | } | ||
| 1394 | spin_unlock_irq(&isp116x->lock); | 1200 | spin_unlock_irq(&isp116x->lock); |
| 1395 | seq_printf(s, "\n"); | 1201 | seq_printf(s, "\n"); |
| 1396 | 1202 | ||
| 1397 | return 0; | 1203 | return 0; |
| 1398 | } | 1204 | } |
| 1399 | 1205 | ||
| 1400 | static int proc_isp116x_open(struct inode *inode, struct file *file) | 1206 | static int isp116x_open_seq(struct inode *inode, struct file *file) |
| 1401 | { | 1207 | { |
| 1402 | return single_open(file, proc_isp116x_show, PDE(inode)->data); | 1208 | return single_open(file, isp116x_show_dbg, inode->u.generic_ip); |
| 1403 | } | 1209 | } |
| 1404 | 1210 | ||
| 1405 | static struct file_operations proc_ops = { | 1211 | static struct file_operations isp116x_debug_fops = { |
| 1406 | .open = proc_isp116x_open, | 1212 | .open = isp116x_open_seq, |
| 1407 | .read = seq_read, | 1213 | .read = seq_read, |
| 1408 | .llseek = seq_lseek, | 1214 | .llseek = seq_lseek, |
| 1409 | .release = single_release, | 1215 | .release = single_release, |
| 1410 | }; | 1216 | }; |
| 1411 | 1217 | ||
| 1412 | /* expect just one isp116x per system */ | 1218 | static int create_debug_file(struct isp116x *isp116x) |
| 1413 | static const char proc_filename[] = "driver/isp116x"; | ||
| 1414 | |||
| 1415 | static void create_debug_file(struct isp116x *isp116x) | ||
| 1416 | { | 1219 | { |
| 1417 | struct proc_dir_entry *pde; | 1220 | isp116x->dentry = debugfs_create_file(hcd_name, |
| 1418 | 1221 | S_IRUGO, NULL, isp116x, | |
| 1419 | pde = create_proc_entry(proc_filename, 0, NULL); | 1222 | &isp116x_debug_fops); |
| 1420 | if (pde == NULL) | 1223 | if (!isp116x->dentry) |
| 1421 | return; | 1224 | return -ENOMEM; |
| 1422 | 1225 | return 0; | |
| 1423 | pde->proc_fops = &proc_ops; | ||
| 1424 | pde->data = isp116x; | ||
| 1425 | isp116x->pde = pde; | ||
| 1426 | } | 1226 | } |
| 1427 | 1227 | ||
| 1428 | static void remove_debug_file(struct isp116x *isp116x) | 1228 | static void remove_debug_file(struct isp116x *isp116x) |
| 1429 | { | 1229 | { |
| 1430 | if (isp116x->pde) | 1230 | debugfs_remove(isp116x->dentry); |
| 1431 | remove_proc_entry(proc_filename, NULL); | ||
| 1432 | } | 1231 | } |
| 1433 | 1232 | ||
| 1434 | #endif | 1233 | #else |
| 1234 | |||
| 1235 | #define create_debug_file(d) 0 | ||
| 1236 | #define remove_debug_file(d) do{}while(0) | ||
| 1237 | |||
| 1238 | #endif /* CONFIG_DEBUG_FS */ | ||
| 1435 | 1239 | ||
| 1436 | /*-----------------------------------------------------------------*/ | 1240 | /*-----------------------------------------------------------------*/ |
| 1437 | 1241 | ||
| @@ -1466,7 +1270,7 @@ static int isp116x_reset(struct usb_hcd *hcd) | |||
| 1466 | struct isp116x *isp116x = hcd_to_isp116x(hcd); | 1270 | struct isp116x *isp116x = hcd_to_isp116x(hcd); |
| 1467 | unsigned long t; | 1271 | unsigned long t; |
| 1468 | u16 clkrdy = 0; | 1272 | u16 clkrdy = 0; |
| 1469 | int ret = 0, timeout = 15 /* ms */ ; | 1273 | int ret, timeout = 15 /* ms */ ; |
| 1470 | 1274 | ||
| 1471 | ret = isp116x_sw_reset(isp116x); | 1275 | ret = isp116x_sw_reset(isp116x); |
| 1472 | if (ret) | 1276 | if (ret) |
| @@ -1482,7 +1286,7 @@ static int isp116x_reset(struct usb_hcd *hcd) | |||
| 1482 | break; | 1286 | break; |
| 1483 | } | 1287 | } |
| 1484 | if (!clkrdy) { | 1288 | if (!clkrdy) { |
| 1485 | ERR("Clock not ready after 20ms\n"); | 1289 | ERR("Clock not ready after %dms\n", timeout); |
| 1486 | /* After sw_reset the clock won't report to be ready, if | 1290 | /* After sw_reset the clock won't report to be ready, if |
| 1487 | H_WAKEUP pin is high. */ | 1291 | H_WAKEUP pin is high. */ |
| 1488 | ERR("Please make sure that the H_WAKEUP pin is pulled low!\n"); | 1292 | ERR("Please make sure that the H_WAKEUP pin is pulled low!\n"); |
| @@ -1572,7 +1376,8 @@ static int isp116x_start(struct usb_hcd *hcd) | |||
| 1572 | 1376 | ||
| 1573 | val = 0; | 1377 | val = 0; |
| 1574 | if (board->remote_wakeup_enable) { | 1378 | if (board->remote_wakeup_enable) { |
| 1575 | hcd->can_wakeup = 1; | 1379 | if (!device_can_wakeup(hcd->self.controller)) |
| 1380 | device_init_wakeup(hcd->self.controller, 1); | ||
| 1576 | val |= RH_HS_DRWE; | 1381 | val |= RH_HS_DRWE; |
| 1577 | } | 1382 | } |
| 1578 | isp116x_write_reg32(isp116x, HCRHSTATUS, val); | 1383 | isp116x_write_reg32(isp116x, HCRHSTATUS, val); |
| @@ -1600,12 +1405,126 @@ static int isp116x_start(struct usb_hcd *hcd) | |||
| 1600 | isp116x_write_reg32(isp116x, HCRHPORT1, RH_PS_CCS); | 1405 | isp116x_write_reg32(isp116x, HCRHPORT1, RH_PS_CCS); |
| 1601 | isp116x_write_reg32(isp116x, HCRHPORT2, RH_PS_CCS); | 1406 | isp116x_write_reg32(isp116x, HCRHPORT2, RH_PS_CCS); |
| 1602 | 1407 | ||
| 1603 | isp116x_show_regs(isp116x); | 1408 | isp116x_show_regs_log(isp116x); |
| 1604 | spin_unlock_irqrestore(&isp116x->lock, flags); | 1409 | spin_unlock_irqrestore(&isp116x->lock, flags); |
| 1605 | return 0; | 1410 | return 0; |
| 1606 | } | 1411 | } |
| 1607 | 1412 | ||
| 1608 | /*-----------------------------------------------------------------*/ | 1413 | #ifdef CONFIG_PM |
| 1414 | |||
| 1415 | static int isp116x_bus_suspend(struct usb_hcd *hcd) | ||
| 1416 | { | ||
| 1417 | struct isp116x *isp116x = hcd_to_isp116x(hcd); | ||
| 1418 | unsigned long flags; | ||
| 1419 | u32 val; | ||
| 1420 | int ret = 0; | ||
| 1421 | |||
| 1422 | spin_lock_irqsave(&isp116x->lock, flags); | ||
| 1423 | |||
| 1424 | val = isp116x_read_reg32(isp116x, HCCONTROL); | ||
| 1425 | switch (val & HCCONTROL_HCFS) { | ||
| 1426 | case HCCONTROL_USB_OPER: | ||
| 1427 | val &= (~HCCONTROL_HCFS & ~HCCONTROL_RWE); | ||
| 1428 | val |= HCCONTROL_USB_SUSPEND; | ||
| 1429 | if (device_may_wakeup(&hcd->self.root_hub->dev)) | ||
| 1430 | val |= HCCONTROL_RWE; | ||
| 1431 | /* Wait for usb transfers to finish */ | ||
| 1432 | mdelay(2); | ||
| 1433 | isp116x_write_reg32(isp116x, HCCONTROL, val); | ||
| 1434 | /* Wait for devices to suspend */ | ||
| 1435 | mdelay(5); | ||
| 1436 | case HCCONTROL_USB_SUSPEND: | ||
| 1437 | break; | ||
| 1438 | case HCCONTROL_USB_RESUME: | ||
| 1439 | isp116x_write_reg32(isp116x, HCCONTROL, | ||
| 1440 | (val & ~HCCONTROL_HCFS) | | ||
| 1441 | HCCONTROL_USB_RESET); | ||
| 1442 | case HCCONTROL_USB_RESET: | ||
| 1443 | ret = -EBUSY; | ||
| 1444 | break; | ||
| 1445 | default: | ||
| 1446 | ret = -EINVAL; | ||
| 1447 | } | ||
| 1448 | |||
| 1449 | spin_unlock_irqrestore(&isp116x->lock, flags); | ||
| 1450 | return ret; | ||
| 1451 | } | ||
| 1452 | |||
| 1453 | static int isp116x_bus_resume(struct usb_hcd *hcd) | ||
| 1454 | { | ||
| 1455 | struct isp116x *isp116x = hcd_to_isp116x(hcd); | ||
| 1456 | u32 val; | ||
| 1457 | |||
| 1458 | msleep(5); | ||
| 1459 | spin_lock_irq(&isp116x->lock); | ||
| 1460 | |||
| 1461 | val = isp116x_read_reg32(isp116x, HCCONTROL); | ||
| 1462 | switch (val & HCCONTROL_HCFS) { | ||
| 1463 | case HCCONTROL_USB_SUSPEND: | ||
| 1464 | val &= ~HCCONTROL_HCFS; | ||
| 1465 | val |= HCCONTROL_USB_RESUME; | ||
| 1466 | isp116x_write_reg32(isp116x, HCCONTROL, val); | ||
| 1467 | case HCCONTROL_USB_RESUME: | ||
| 1468 | break; | ||
| 1469 | case HCCONTROL_USB_OPER: | ||
| 1470 | spin_unlock_irq(&isp116x->lock); | ||
| 1471 | /* Without setting power_state here the | ||
| 1472 | SUSPENDED state won't be removed from | ||
| 1473 | sysfs/usbN/power.state as a response to remote | ||
| 1474 | wakeup. Maybe in the future. */ | ||
| 1475 | hcd->self.root_hub->dev.power.power_state = PMSG_ON; | ||
| 1476 | return 0; | ||
| 1477 | default: | ||
| 1478 | /* HCCONTROL_USB_RESET: this may happen, when during | ||
| 1479 | suspension the HC lost power. Reinitialize completely */ | ||
| 1480 | spin_unlock_irq(&isp116x->lock); | ||
| 1481 | DBG("Chip has been reset while suspended. Reinit from scratch.\n"); | ||
| 1482 | isp116x_reset(hcd); | ||
| 1483 | isp116x_start(hcd); | ||
| 1484 | isp116x_hub_control(hcd, SetPortFeature, | ||
| 1485 | USB_PORT_FEAT_POWER, 1, NULL, 0); | ||
| 1486 | if ((isp116x->rhdesca & RH_A_NDP) == 2) | ||
| 1487 | isp116x_hub_control(hcd, SetPortFeature, | ||
| 1488 | USB_PORT_FEAT_POWER, 2, NULL, 0); | ||
| 1489 | hcd->self.root_hub->dev.power.power_state = PMSG_ON; | ||
| 1490 | return 0; | ||
| 1491 | } | ||
| 1492 | |||
| 1493 | val = isp116x->rhdesca & RH_A_NDP; | ||
| 1494 | while (val--) { | ||
| 1495 | u32 stat = | ||
| 1496 | isp116x_read_reg32(isp116x, val ? HCRHPORT2 : HCRHPORT1); | ||
| 1497 | /* force global, not selective, resume */ | ||
| 1498 | if (!(stat & RH_PS_PSS)) | ||
| 1499 | continue; | ||
| 1500 | DBG("%s: Resuming port %d\n", __func__, val); | ||
| 1501 | isp116x_write_reg32(isp116x, RH_PS_POCI, val | ||
| 1502 | ? HCRHPORT2 : HCRHPORT1); | ||
| 1503 | } | ||
| 1504 | spin_unlock_irq(&isp116x->lock); | ||
| 1505 | |||
| 1506 | hcd->state = HC_STATE_RESUMING; | ||
| 1507 | msleep(20); | ||
| 1508 | |||
| 1509 | /* Go operational */ | ||
| 1510 | spin_lock_irq(&isp116x->lock); | ||
| 1511 | val = isp116x_read_reg32(isp116x, HCCONTROL); | ||
| 1512 | isp116x_write_reg32(isp116x, HCCONTROL, | ||
| 1513 | (val & ~HCCONTROL_HCFS) | HCCONTROL_USB_OPER); | ||
| 1514 | spin_unlock_irq(&isp116x->lock); | ||
| 1515 | /* see analogous comment above */ | ||
| 1516 | hcd->self.root_hub->dev.power.power_state = PMSG_ON; | ||
| 1517 | hcd->state = HC_STATE_RUNNING; | ||
| 1518 | |||
| 1519 | return 0; | ||
| 1520 | } | ||
| 1521 | |||
| 1522 | #else | ||
| 1523 | |||
| 1524 | #define isp116x_bus_suspend NULL | ||
| 1525 | #define isp116x_bus_resume NULL | ||
| 1526 | |||
| 1527 | #endif | ||
| 1609 | 1528 | ||
| 1610 | static struct hc_driver isp116x_hc_driver = { | 1529 | static struct hc_driver isp116x_hc_driver = { |
| 1611 | .description = hcd_name, | 1530 | .description = hcd_name, |
| @@ -1735,12 +1654,19 @@ static int __init isp116x_probe(struct platform_device *pdev) | |||
| 1735 | } | 1654 | } |
| 1736 | 1655 | ||
| 1737 | ret = usb_add_hcd(hcd, irq, SA_INTERRUPT); | 1656 | ret = usb_add_hcd(hcd, irq, SA_INTERRUPT); |
| 1738 | if (ret != 0) | 1657 | if (ret) |
| 1739 | goto err6; | 1658 | goto err6; |
| 1740 | 1659 | ||
| 1741 | create_debug_file(isp116x); | 1660 | ret = create_debug_file(isp116x); |
| 1661 | if (ret) { | ||
| 1662 | ERR("Couldn't create debugfs entry\n"); | ||
| 1663 | goto err7; | ||
| 1664 | } | ||
| 1665 | |||
| 1742 | return 0; | 1666 | return 0; |
| 1743 | 1667 | ||
| 1668 | err7: | ||
| 1669 | usb_remove_hcd(hcd); | ||
| 1744 | err6: | 1670 | err6: |
| 1745 | usb_put_hcd(hcd); | 1671 | usb_put_hcd(hcd); |
| 1746 | err5: | 1672 | err5: |
| @@ -1762,13 +1688,9 @@ static int __init isp116x_probe(struct platform_device *pdev) | |||
| 1762 | */ | 1688 | */ |
| 1763 | static int isp116x_suspend(struct platform_device *dev, pm_message_t state) | 1689 | static int isp116x_suspend(struct platform_device *dev, pm_message_t state) |
| 1764 | { | 1690 | { |
| 1765 | int ret = 0; | 1691 | VDBG("%s: state %x\n", __func__, state.event); |
| 1766 | |||
| 1767 | VDBG("%s: state %x\n", __func__, state); | ||
| 1768 | |||
| 1769 | dev->dev.power.power_state = state; | 1692 | dev->dev.power.power_state = state; |
| 1770 | 1693 | return 0; | |
| 1771 | return ret; | ||
| 1772 | } | 1694 | } |
| 1773 | 1695 | ||
| 1774 | /* | 1696 | /* |
| @@ -1776,13 +1698,9 @@ static int isp116x_suspend(struct platform_device *dev, pm_message_t state) | |||
| 1776 | */ | 1698 | */ |
| 1777 | static int isp116x_resume(struct platform_device *dev) | 1699 | static int isp116x_resume(struct platform_device *dev) |
| 1778 | { | 1700 | { |
| 1779 | int ret = 0; | 1701 | VDBG("%s: state %x\n", __func__, dev->power.power_state.event); |
| 1780 | |||
| 1781 | VDBG("%s: state %x\n", __func__, dev->dev.power.power_state); | ||
| 1782 | |||
| 1783 | dev->dev.power.power_state = PMSG_ON; | 1702 | dev->dev.power.power_state = PMSG_ON; |
| 1784 | 1703 | return 0; | |
| 1785 | return ret; | ||
| 1786 | } | 1704 | } |
| 1787 | 1705 | ||
| 1788 | #else | 1706 | #else |
diff --git a/drivers/usb/host/isp116x.h b/drivers/usb/host/isp116x.h index c6fec96785fe..a1b7c3813d3a 100644 --- a/drivers/usb/host/isp116x.h +++ b/drivers/usb/host/isp116x.h | |||
| @@ -259,7 +259,7 @@ struct isp116x { | |||
| 259 | 259 | ||
| 260 | struct isp116x_platform_data *board; | 260 | struct isp116x_platform_data *board; |
| 261 | 261 | ||
| 262 | struct proc_dir_entry *pde; | 262 | struct dentry *dentry; |
| 263 | unsigned long stat1, stat2, stat4, stat8, stat16; | 263 | unsigned long stat1, stat2, stat4, stat8, stat16; |
| 264 | 264 | ||
| 265 | /* HC registers */ | 265 | /* HC registers */ |
| @@ -450,7 +450,7 @@ static void isp116x_write_reg32(struct isp116x *isp116x, unsigned reg, | |||
| 450 | isp116x_write_data32(isp116x, (u32) val); | 450 | isp116x_write_data32(isp116x, (u32) val); |
| 451 | } | 451 | } |
| 452 | 452 | ||
| 453 | #define isp116x_show_reg(d,r) { \ | 453 | #define isp116x_show_reg_log(d,r,s) { \ |
| 454 | if ((r) < 0x20) { \ | 454 | if ((r) < 0x20) { \ |
| 455 | DBG("%-12s[%02x]: %08x\n", #r, \ | 455 | DBG("%-12s[%02x]: %08x\n", #r, \ |
| 456 | r, isp116x_read_reg32(d, r)); \ | 456 | r, isp116x_read_reg32(d, r)); \ |
| @@ -459,35 +459,60 @@ static void isp116x_write_reg32(struct isp116x *isp116x, unsigned reg, | |||
| 459 | r, isp116x_read_reg16(d, r)); \ | 459 | r, isp116x_read_reg16(d, r)); \ |
| 460 | } \ | 460 | } \ |
| 461 | } | 461 | } |
| 462 | #define isp116x_show_reg_seq(d,r,s) { \ | ||
| 463 | if ((r) < 0x20) { \ | ||
| 464 | seq_printf(s, "%-12s[%02x]: %08x\n", #r, \ | ||
| 465 | r, isp116x_read_reg32(d, r)); \ | ||
| 466 | } else { \ | ||
| 467 | seq_printf(s, "%-12s[%02x]: %04x\n", #r, \ | ||
| 468 | r, isp116x_read_reg16(d, r)); \ | ||
| 469 | } \ | ||
| 470 | } | ||
| 462 | 471 | ||
| 463 | static inline void isp116x_show_regs(struct isp116x *isp116x) | 472 | #define isp116x_show_regs(d,type,s) { \ |
| 473 | isp116x_show_reg_##type(d, HCREVISION, s); \ | ||
| 474 | isp116x_show_reg_##type(d, HCCONTROL, s); \ | ||
| 475 | isp116x_show_reg_##type(d, HCCMDSTAT, s); \ | ||
| 476 | isp116x_show_reg_##type(d, HCINTSTAT, s); \ | ||
| 477 | isp116x_show_reg_##type(d, HCINTENB, s); \ | ||
| 478 | isp116x_show_reg_##type(d, HCFMINTVL, s); \ | ||
| 479 | isp116x_show_reg_##type(d, HCFMREM, s); \ | ||
| 480 | isp116x_show_reg_##type(d, HCFMNUM, s); \ | ||
| 481 | isp116x_show_reg_##type(d, HCLSTHRESH, s); \ | ||
| 482 | isp116x_show_reg_##type(d, HCRHDESCA, s); \ | ||
| 483 | isp116x_show_reg_##type(d, HCRHDESCB, s); \ | ||
| 484 | isp116x_show_reg_##type(d, HCRHSTATUS, s); \ | ||
| 485 | isp116x_show_reg_##type(d, HCRHPORT1, s); \ | ||
| 486 | isp116x_show_reg_##type(d, HCRHPORT2, s); \ | ||
| 487 | isp116x_show_reg_##type(d, HCHWCFG, s); \ | ||
| 488 | isp116x_show_reg_##type(d, HCDMACFG, s); \ | ||
| 489 | isp116x_show_reg_##type(d, HCXFERCTR, s); \ | ||
| 490 | isp116x_show_reg_##type(d, HCuPINT, s); \ | ||
| 491 | isp116x_show_reg_##type(d, HCuPINTENB, s); \ | ||
| 492 | isp116x_show_reg_##type(d, HCCHIPID, s); \ | ||
| 493 | isp116x_show_reg_##type(d, HCSCRATCH, s); \ | ||
| 494 | isp116x_show_reg_##type(d, HCITLBUFLEN, s); \ | ||
| 495 | isp116x_show_reg_##type(d, HCATLBUFLEN, s); \ | ||
| 496 | isp116x_show_reg_##type(d, HCBUFSTAT, s); \ | ||
| 497 | isp116x_show_reg_##type(d, HCRDITL0LEN, s); \ | ||
| 498 | isp116x_show_reg_##type(d, HCRDITL1LEN, s); \ | ||
| 499 | } | ||
| 500 | |||
| 501 | /* | ||
| 502 | Dump registers for debugfs. | ||
| 503 | */ | ||
| 504 | static inline void isp116x_show_regs_seq(struct isp116x *isp116x, | ||
| 505 | struct seq_file *s) | ||
| 506 | { | ||
| 507 | isp116x_show_regs(isp116x, seq, s); | ||
| 508 | } | ||
| 509 | |||
| 510 | /* | ||
| 511 | Dump registers to syslog. | ||
| 512 | */ | ||
| 513 | static inline void isp116x_show_regs_log(struct isp116x *isp116x) | ||
| 464 | { | 514 | { |
| 465 | isp116x_show_reg(isp116x, HCREVISION); | 515 | isp116x_show_regs(isp116x, log, NULL); |
| 466 | isp116x_show_reg(isp116x, HCCONTROL); | ||
| 467 | isp116x_show_reg(isp116x, HCCMDSTAT); | ||
| 468 | isp116x_show_reg(isp116x, HCINTSTAT); | ||
| 469 | isp116x_show_reg(isp116x, HCINTENB); | ||
| 470 | isp116x_show_reg(isp116x, HCFMINTVL); | ||
| 471 | isp116x_show_reg(isp116x, HCFMREM); | ||
| 472 | isp116x_show_reg(isp116x, HCFMNUM); | ||
| 473 | isp116x_show_reg(isp116x, HCLSTHRESH); | ||
| 474 | isp116x_show_reg(isp116x, HCRHDESCA); | ||
| 475 | isp116x_show_reg(isp116x, HCRHDESCB); | ||
| 476 | isp116x_show_reg(isp116x, HCRHSTATUS); | ||
| 477 | isp116x_show_reg(isp116x, HCRHPORT1); | ||
| 478 | isp116x_show_reg(isp116x, HCRHPORT2); | ||
| 479 | isp116x_show_reg(isp116x, HCHWCFG); | ||
| 480 | isp116x_show_reg(isp116x, HCDMACFG); | ||
| 481 | isp116x_show_reg(isp116x, HCXFERCTR); | ||
| 482 | isp116x_show_reg(isp116x, HCuPINT); | ||
| 483 | isp116x_show_reg(isp116x, HCuPINTENB); | ||
| 484 | isp116x_show_reg(isp116x, HCCHIPID); | ||
| 485 | isp116x_show_reg(isp116x, HCSCRATCH); | ||
| 486 | isp116x_show_reg(isp116x, HCITLBUFLEN); | ||
| 487 | isp116x_show_reg(isp116x, HCATLBUFLEN); | ||
| 488 | isp116x_show_reg(isp116x, HCBUFSTAT); | ||
| 489 | isp116x_show_reg(isp116x, HCRDITL0LEN); | ||
| 490 | isp116x_show_reg(isp116x, HCRDITL1LEN); | ||
| 491 | } | 516 | } |
| 492 | 517 | ||
| 493 | #if defined(URB_TRACE) | 518 | #if defined(URB_TRACE) |
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index bf1d9abc07ac..a4b12404ae08 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
| @@ -75,13 +75,6 @@ | |||
| 75 | */ | 75 | */ |
| 76 | 76 | ||
| 77 | #include <linux/config.h> | 77 | #include <linux/config.h> |
| 78 | |||
| 79 | #ifdef CONFIG_USB_DEBUG | ||
| 80 | # define DEBUG | ||
| 81 | #else | ||
| 82 | # undef DEBUG | ||
| 83 | #endif | ||
| 84 | |||
| 85 | #include <linux/module.h> | 78 | #include <linux/module.h> |
| 86 | #include <linux/moduleparam.h> | 79 | #include <linux/moduleparam.h> |
| 87 | #include <linux/pci.h> | 80 | #include <linux/pci.h> |
| @@ -802,7 +795,6 @@ static int ohci_restart (struct ohci_hcd *ohci) | |||
| 802 | int temp; | 795 | int temp; |
| 803 | int i; | 796 | int i; |
| 804 | struct urb_priv *priv; | 797 | struct urb_priv *priv; |
| 805 | struct usb_device *root = ohci_to_hcd(ohci)->self.root_hub; | ||
| 806 | 798 | ||
| 807 | /* mark any devices gone, so they do nothing till khubd disconnects. | 799 | /* mark any devices gone, so they do nothing till khubd disconnects. |
| 808 | * recycle any "live" eds/tds (and urbs) right away. | 800 | * recycle any "live" eds/tds (and urbs) right away. |
| @@ -811,11 +803,7 @@ static int ohci_restart (struct ohci_hcd *ohci) | |||
| 811 | */ | 803 | */ |
| 812 | spin_lock_irq(&ohci->lock); | 804 | spin_lock_irq(&ohci->lock); |
| 813 | disable (ohci); | 805 | disable (ohci); |
| 814 | for (i = 0; i < root->maxchild; i++) { | 806 | usb_root_hub_lost_power(ohci_to_hcd(ohci)->self.root_hub); |
| 815 | if (root->children [i]) | ||
| 816 | usb_set_device_state (root->children[i], | ||
| 817 | USB_STATE_NOTATTACHED); | ||
| 818 | } | ||
| 819 | if (!list_empty (&ohci->pending)) | 807 | if (!list_empty (&ohci->pending)) |
| 820 | ohci_dbg(ohci, "abort schedule...\n"); | 808 | ohci_dbg(ohci, "abort schedule...\n"); |
| 821 | list_for_each_entry (priv, &ohci->pending, pending) { | 809 | list_for_each_entry (priv, &ohci->pending, pending) { |
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index 72e3b12a1926..4b2226d77b34 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c | |||
| @@ -372,7 +372,7 @@ done: | |||
| 372 | & ohci->hc_control) | 372 | & ohci->hc_control) |
| 373 | == OHCI_USB_OPER | 373 | == OHCI_USB_OPER |
| 374 | && time_after (jiffies, ohci->next_statechange) | 374 | && time_after (jiffies, ohci->next_statechange) |
| 375 | && usb_trylock_device (hcd->self.root_hub) | 375 | && usb_trylock_device (hcd->self.root_hub) == 0 |
| 376 | ) { | 376 | ) { |
| 377 | ohci_vdbg (ohci, "autosuspend\n"); | 377 | ohci_vdbg (ohci, "autosuspend\n"); |
| 378 | (void) ohci_bus_suspend (hcd); | 378 | (void) ohci_bus_suspend (hcd); |
diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index 9d65ec307990..acde8868da21 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c | |||
| @@ -26,18 +26,12 @@ | |||
| 26 | #include <asm/mach-types.h> | 26 | #include <asm/mach-types.h> |
| 27 | #include <asm/hardware.h> | 27 | #include <asm/hardware.h> |
| 28 | #include <asm/arch/pxa-regs.h> | 28 | #include <asm/arch/pxa-regs.h> |
| 29 | 29 | #include <asm/arch/ohci.h> | |
| 30 | |||
| 31 | #define PMM_NPS_MODE 1 | ||
| 32 | #define PMM_GLOBAL_MODE 2 | ||
| 33 | #define PMM_PERPORT_MODE 3 | ||
| 34 | 30 | ||
| 35 | #define PXA_UHC_MAX_PORTNUM 3 | 31 | #define PXA_UHC_MAX_PORTNUM 3 |
| 36 | 32 | ||
| 37 | #define UHCRHPS(x) __REG2( 0x4C000050, (x)<<2 ) | 33 | #define UHCRHPS(x) __REG2( 0x4C000050, (x)<<2 ) |
| 38 | 34 | ||
| 39 | static int pxa27x_ohci_pmm_state; | ||
| 40 | |||
| 41 | /* | 35 | /* |
| 42 | PMM_NPS_MODE -- PMM Non-power switching mode | 36 | PMM_NPS_MODE -- PMM Non-power switching mode |
| 43 | Ports are powered continuously. | 37 | Ports are powered continuously. |
| @@ -50,8 +44,6 @@ static int pxa27x_ohci_pmm_state; | |||
| 50 | */ | 44 | */ |
| 51 | static int pxa27x_ohci_select_pmm( int mode ) | 45 | static int pxa27x_ohci_select_pmm( int mode ) |
| 52 | { | 46 | { |
| 53 | pxa27x_ohci_pmm_state = mode; | ||
| 54 | |||
| 55 | switch ( mode ) { | 47 | switch ( mode ) { |
| 56 | case PMM_NPS_MODE: | 48 | case PMM_NPS_MODE: |
| 57 | UHCRHDA |= RH_A_NPS; | 49 | UHCRHDA |= RH_A_NPS; |
| @@ -71,7 +63,6 @@ static int pxa27x_ohci_select_pmm( int mode ) | |||
| 71 | "Invalid mode %d, set to non-power switch mode.\n", | 63 | "Invalid mode %d, set to non-power switch mode.\n", |
| 72 | mode ); | 64 | mode ); |
| 73 | 65 | ||
| 74 | pxa27x_ohci_pmm_state = PMM_NPS_MODE; | ||
| 75 | UHCRHDA |= RH_A_NPS; | 66 | UHCRHDA |= RH_A_NPS; |
| 76 | } | 67 | } |
| 77 | 68 | ||
| @@ -82,8 +73,13 @@ extern int usb_disabled(void); | |||
| 82 | 73 | ||
| 83 | /*-------------------------------------------------------------------------*/ | 74 | /*-------------------------------------------------------------------------*/ |
| 84 | 75 | ||
| 85 | static void pxa27x_start_hc(struct platform_device *dev) | 76 | static int pxa27x_start_hc(struct device *dev) |
| 86 | { | 77 | { |
| 78 | int retval = 0; | ||
| 79 | struct pxaohci_platform_data *inf; | ||
| 80 | |||
| 81 | inf = dev->platform_data; | ||
| 82 | |||
| 87 | pxa_set_cken(CKEN10_USBHOST, 1); | 83 | pxa_set_cken(CKEN10_USBHOST, 1); |
| 88 | 84 | ||
| 89 | UHCHR |= UHCHR_FHR; | 85 | UHCHR |= UHCHR_FHR; |
| @@ -94,21 +90,11 @@ static void pxa27x_start_hc(struct platform_device *dev) | |||
| 94 | while (UHCHR & UHCHR_FSBIR) | 90 | while (UHCHR & UHCHR_FSBIR) |
| 95 | cpu_relax(); | 91 | cpu_relax(); |
| 96 | 92 | ||
| 97 | /* This could be properly abstracted away through the | 93 | if (inf->init) |
| 98 | device data the day more machines are supported and | 94 | retval = inf->init(dev); |
| 99 | their differences can be figured out correctly. */ | ||
| 100 | if (machine_is_mainstone()) { | ||
| 101 | /* setup Port1 GPIO pin. */ | ||
| 102 | pxa_gpio_mode( 88 | GPIO_ALT_FN_1_IN); /* USBHPWR1 */ | ||
| 103 | pxa_gpio_mode( 89 | GPIO_ALT_FN_2_OUT); /* USBHPEN1 */ | ||
| 104 | |||
| 105 | /* Set the Power Control Polarity Low and Power Sense | ||
| 106 | Polarity Low to active low. Supply power to USB ports. */ | ||
| 107 | UHCHR = (UHCHR | UHCHR_PCPL | UHCHR_PSPL) & | ||
| 108 | ~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE); | ||
| 109 | 95 | ||
| 110 | pxa27x_ohci_pmm_state = PMM_PERPORT_MODE; | 96 | if (retval < 0) |
| 111 | } | 97 | return retval; |
| 112 | 98 | ||
| 113 | UHCHR &= ~UHCHR_SSE; | 99 | UHCHR &= ~UHCHR_SSE; |
| 114 | 100 | ||
| @@ -117,10 +103,19 @@ static void pxa27x_start_hc(struct platform_device *dev) | |||
| 117 | /* Clear any OTG Pin Hold */ | 103 | /* Clear any OTG Pin Hold */ |
| 118 | if (PSSR & PSSR_OTGPH) | 104 | if (PSSR & PSSR_OTGPH) |
| 119 | PSSR |= PSSR_OTGPH; | 105 | PSSR |= PSSR_OTGPH; |
| 106 | |||
| 107 | return 0; | ||
| 120 | } | 108 | } |
| 121 | 109 | ||
| 122 | static void pxa27x_stop_hc(struct platform_device *dev) | 110 | static void pxa27x_stop_hc(struct device *dev) |
| 123 | { | 111 | { |
| 112 | struct pxaohci_platform_data *inf; | ||
| 113 | |||
| 114 | inf = dev->platform_data; | ||
| 115 | |||
| 116 | if (inf->exit) | ||
| 117 | inf->exit(dev); | ||
| 118 | |||
| 124 | UHCHR |= UHCHR_FHR; | 119 | UHCHR |= UHCHR_FHR; |
| 125 | udelay(11); | 120 | udelay(11); |
| 126 | UHCHR &= ~UHCHR_FHR; | 121 | UHCHR &= ~UHCHR_FHR; |
| @@ -147,22 +142,27 @@ static void pxa27x_stop_hc(struct platform_device *dev) | |||
| 147 | * through the hotplug entry's driver_data. | 142 | * through the hotplug entry's driver_data. |
| 148 | * | 143 | * |
| 149 | */ | 144 | */ |
| 150 | int usb_hcd_pxa27x_probe (const struct hc_driver *driver, | 145 | int usb_hcd_pxa27x_probe (const struct hc_driver *driver, struct platform_device *pdev) |
| 151 | struct platform_device *dev) | ||
| 152 | { | 146 | { |
| 153 | int retval; | 147 | int retval; |
| 154 | struct usb_hcd *hcd; | 148 | struct usb_hcd *hcd; |
| 149 | struct pxaohci_platform_data *inf; | ||
| 155 | 150 | ||
| 156 | if (dev->resource[1].flags != IORESOURCE_IRQ) { | 151 | inf = pdev->dev.platform_data; |
| 152 | |||
| 153 | if (!inf) | ||
| 154 | return -ENODEV; | ||
| 155 | |||
| 156 | if (pdev->resource[1].flags != IORESOURCE_IRQ) { | ||
| 157 | pr_debug ("resource[1] is not IORESOURCE_IRQ"); | 157 | pr_debug ("resource[1] is not IORESOURCE_IRQ"); |
| 158 | return -ENOMEM; | 158 | return -ENOMEM; |
| 159 | } | 159 | } |
| 160 | 160 | ||
| 161 | hcd = usb_create_hcd (driver, &dev->dev, "pxa27x"); | 161 | hcd = usb_create_hcd (driver, &pdev->dev, "pxa27x"); |
| 162 | if (!hcd) | 162 | if (!hcd) |
| 163 | return -ENOMEM; | 163 | return -ENOMEM; |
| 164 | hcd->rsrc_start = dev->resource[0].start; | 164 | hcd->rsrc_start = pdev->resource[0].start; |
| 165 | hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1; | 165 | hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1; |
| 166 | 166 | ||
| 167 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { | 167 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { |
| 168 | pr_debug("request_mem_region failed"); | 168 | pr_debug("request_mem_region failed"); |
| @@ -177,18 +177,22 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver, | |||
| 177 | goto err2; | 177 | goto err2; |
| 178 | } | 178 | } |
| 179 | 179 | ||
| 180 | pxa27x_start_hc(dev); | 180 | if ((retval = pxa27x_start_hc(&pdev->dev)) < 0) { |
| 181 | pr_debug("pxa27x_start_hc failed"); | ||
| 182 | goto err3; | ||
| 183 | } | ||
| 181 | 184 | ||
| 182 | /* Select Power Management Mode */ | 185 | /* Select Power Management Mode */ |
| 183 | pxa27x_ohci_select_pmm(pxa27x_ohci_pmm_state); | 186 | pxa27x_ohci_select_pmm(inf->port_mode); |
| 184 | 187 | ||
| 185 | ohci_hcd_init(hcd_to_ohci(hcd)); | 188 | ohci_hcd_init(hcd_to_ohci(hcd)); |
| 186 | 189 | ||
| 187 | retval = usb_add_hcd(hcd, dev->resource[1].start, SA_INTERRUPT); | 190 | retval = usb_add_hcd(hcd, pdev->resource[1].start, SA_INTERRUPT); |
| 188 | if (retval == 0) | 191 | if (retval == 0) |
| 189 | return retval; | 192 | return retval; |
| 190 | 193 | ||
| 191 | pxa27x_stop_hc(dev); | 194 | pxa27x_stop_hc(&pdev->dev); |
| 195 | err3: | ||
| 192 | iounmap(hcd->regs); | 196 | iounmap(hcd->regs); |
| 193 | err2: | 197 | err2: |
| 194 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | 198 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); |
| @@ -211,10 +215,10 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver, | |||
| 211 | * context, normally "rmmod", "apmd", or something similar. | 215 | * context, normally "rmmod", "apmd", or something similar. |
| 212 | * | 216 | * |
| 213 | */ | 217 | */ |
| 214 | void usb_hcd_pxa27x_remove (struct usb_hcd *hcd, struct platform_device *dev) | 218 | void usb_hcd_pxa27x_remove (struct usb_hcd *hcd, struct platform_device *pdev) |
| 215 | { | 219 | { |
| 216 | usb_remove_hcd(hcd); | 220 | usb_remove_hcd(hcd); |
| 217 | pxa27x_stop_hc(dev); | 221 | pxa27x_stop_hc(&pdev->dev); |
| 218 | iounmap(hcd->regs); | 222 | iounmap(hcd->regs); |
| 219 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | 223 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); |
| 220 | usb_put_hcd(hcd); | 224 | usb_put_hcd(hcd); |
| @@ -292,15 +296,12 @@ static const struct hc_driver ohci_pxa27x_hc_driver = { | |||
| 292 | 296 | ||
| 293 | static int ohci_hcd_pxa27x_drv_probe(struct platform_device *pdev) | 297 | static int ohci_hcd_pxa27x_drv_probe(struct platform_device *pdev) |
| 294 | { | 298 | { |
| 295 | int ret; | ||
| 296 | |||
| 297 | pr_debug ("In ohci_hcd_pxa27x_drv_probe"); | 299 | pr_debug ("In ohci_hcd_pxa27x_drv_probe"); |
| 298 | 300 | ||
| 299 | if (usb_disabled()) | 301 | if (usb_disabled()) |
| 300 | return -ENODEV; | 302 | return -ENODEV; |
| 301 | 303 | ||
| 302 | ret = usb_hcd_pxa27x_probe(&ohci_pxa27x_hc_driver, pdev); | 304 | return usb_hcd_pxa27x_probe(&ohci_pxa27x_hc_driver, pdev); |
| 303 | return ret; | ||
| 304 | } | 305 | } |
| 305 | 306 | ||
| 306 | static int ohci_hcd_pxa27x_drv_remove(struct platform_device *pdev) | 307 | static int ohci_hcd_pxa27x_drv_remove(struct platform_device *pdev) |
| @@ -308,31 +309,55 @@ static int ohci_hcd_pxa27x_drv_remove(struct platform_device *pdev) | |||
| 308 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | 309 | struct usb_hcd *hcd = platform_get_drvdata(pdev); |
| 309 | 310 | ||
| 310 | usb_hcd_pxa27x_remove(hcd, pdev); | 311 | usb_hcd_pxa27x_remove(hcd, pdev); |
| 312 | platform_set_drvdata(pdev, NULL); | ||
| 311 | return 0; | 313 | return 0; |
| 312 | } | 314 | } |
| 313 | 315 | ||
| 314 | static int ohci_hcd_pxa27x_drv_suspend(struct platform_device *dev, pm_message_t state) | 316 | #ifdef CONFIG_PM |
| 317 | static int ohci_hcd_pxa27x_drv_suspend(struct platform_device *pdev, pm_message_t state) | ||
| 315 | { | 318 | { |
| 316 | // struct usb_hcd *hcd = platform_get_drvdata(dev); | 319 | struct usb_hcd *hcd = platform_get_drvdata(pdev); |
| 317 | printk("%s: not implemented yet\n", __FUNCTION__); | 320 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); |
| 321 | |||
| 322 | if (time_before(jiffies, ohci->next_statechange)) | ||
| 323 | msleep(5); | ||
| 324 | ohci->next_statechange = jiffies; | ||
| 325 | |||
| 326 | pxa27x_stop_hc(&pdev->dev); | ||
| 327 | hcd->state = HC_STATE_SUSPENDED; | ||
| 328 | pdev->dev.power.power_state = PMSG_SUSPEND; | ||
| 318 | 329 | ||
| 319 | return 0; | 330 | return 0; |
| 320 | } | 331 | } |
| 321 | 332 | ||
| 322 | static int ohci_hcd_pxa27x_drv_resume(struct platform_device *dev) | 333 | static int ohci_hcd_pxa27x_drv_resume(struct platform_device *pdev) |
| 323 | { | 334 | { |
| 324 | // struct usb_hcd *hcd = platform_get_drvdata(dev); | 335 | struct usb_hcd *hcd = platform_get_drvdata(pdev); |
| 325 | printk("%s: not implemented yet\n", __FUNCTION__); | 336 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); |
| 337 | int status; | ||
| 338 | |||
| 339 | if (time_before(jiffies, ohci->next_statechange)) | ||
| 340 | msleep(5); | ||
| 341 | ohci->next_statechange = jiffies; | ||
| 342 | |||
| 343 | if ((status = pxa27x_start_hc(&pdev->dev)) < 0) | ||
| 344 | return status; | ||
| 345 | |||
| 346 | pdev->dev.power.power_state = PMSG_ON; | ||
| 347 | usb_hcd_resume_root_hub(hcd); | ||
| 326 | 348 | ||
| 327 | return 0; | 349 | return 0; |
| 328 | } | 350 | } |
| 351 | #endif | ||
| 329 | 352 | ||
| 330 | 353 | ||
| 331 | static struct platform_driver ohci_hcd_pxa27x_driver = { | 354 | static struct platform_driver ohci_hcd_pxa27x_driver = { |
| 332 | .probe = ohci_hcd_pxa27x_drv_probe, | 355 | .probe = ohci_hcd_pxa27x_drv_probe, |
| 333 | .remove = ohci_hcd_pxa27x_drv_remove, | 356 | .remove = ohci_hcd_pxa27x_drv_remove, |
| 357 | #ifdef CONFIG_PM | ||
| 334 | .suspend = ohci_hcd_pxa27x_drv_suspend, | 358 | .suspend = ohci_hcd_pxa27x_drv_suspend, |
| 335 | .resume = ohci_hcd_pxa27x_drv_resume, | 359 | .resume = ohci_hcd_pxa27x_drv_resume, |
| 360 | #endif | ||
| 336 | .driver = { | 361 | .driver = { |
| 337 | .name = "pxa27x-ohci", | 362 | .name = "pxa27x-ohci", |
| 338 | }, | 363 | }, |
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index e46528c825bf..3ef2c0cdf1db 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c | |||
| @@ -9,12 +9,6 @@ | |||
| 9 | */ | 9 | */ |
| 10 | 10 | ||
| 11 | #include <linux/config.h> | 11 | #include <linux/config.h> |
| 12 | #ifdef CONFIG_USB_DEBUG | ||
| 13 | #define DEBUG | ||
| 14 | #else | ||
| 15 | #undef DEBUG | ||
| 16 | #endif | ||
| 17 | |||
| 18 | #include <linux/types.h> | 12 | #include <linux/types.h> |
| 19 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
| 20 | #include <linux/pci.h> | 14 | #include <linux/pci.h> |
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index a7722a6a5a5b..517360b77d8e 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c | |||
| @@ -32,13 +32,6 @@ | |||
| 32 | #undef PACKET_TRACE | 32 | #undef PACKET_TRACE |
| 33 | 33 | ||
| 34 | #include <linux/config.h> | 34 | #include <linux/config.h> |
| 35 | |||
| 36 | #ifdef CONFIG_USB_DEBUG | ||
| 37 | # define DEBUG | ||
| 38 | #else | ||
| 39 | # undef DEBUG | ||
| 40 | #endif | ||
| 41 | |||
| 42 | #include <linux/module.h> | 35 | #include <linux/module.h> |
| 43 | #include <linux/moduleparam.h> | 36 | #include <linux/moduleparam.h> |
| 44 | #include <linux/kernel.h> | 37 | #include <linux/kernel.h> |
| @@ -1581,7 +1574,9 @@ sl811h_start(struct usb_hcd *hcd) | |||
| 1581 | hcd->state = HC_STATE_RUNNING; | 1574 | hcd->state = HC_STATE_RUNNING; |
| 1582 | 1575 | ||
| 1583 | if (sl811->board) { | 1576 | if (sl811->board) { |
| 1584 | hcd->can_wakeup = sl811->board->can_wakeup; | 1577 | if (!device_can_wakeup(hcd->self.controller)) |
| 1578 | device_init_wakeup(hcd->self.controller, | ||
| 1579 | sl811->board->can_wakeup); | ||
| 1585 | hcd->power_budget = sl811->board->power * 2; | 1580 | hcd->power_budget = sl811->board->power * 2; |
| 1586 | } | 1581 | } |
| 1587 | 1582 | ||
| @@ -1805,9 +1800,10 @@ sl811h_resume(struct platform_device *dev) | |||
| 1805 | * let's assume it'd only be powered to enable remote wakeup. | 1800 | * let's assume it'd only be powered to enable remote wakeup. |
| 1806 | */ | 1801 | */ |
| 1807 | if (dev->dev.power.power_state.event == PM_EVENT_SUSPEND | 1802 | if (dev->dev.power.power_state.event == PM_EVENT_SUSPEND |
| 1808 | || !hcd->can_wakeup) { | 1803 | || !device_can_wakeup(&hcd->self.root_hub->dev)) { |
| 1809 | sl811->port1 = 0; | 1804 | sl811->port1 = 0; |
| 1810 | port_power(sl811, 1); | 1805 | port_power(sl811, 1); |
| 1806 | usb_root_hub_lost_power(hcd->self.root_hub); | ||
| 1811 | return 0; | 1807 | return 0; |
| 1812 | } | 1808 | } |
| 1813 | 1809 | ||
diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c index e73faf831b24..5056b7459994 100644 --- a/drivers/usb/host/sl811_cs.c +++ b/drivers/usb/host/sl811_cs.c | |||
| @@ -38,7 +38,7 @@ MODULE_LICENSE("GPL"); | |||
| 38 | /* MACROS */ | 38 | /* MACROS */ |
| 39 | /*====================================================================*/ | 39 | /*====================================================================*/ |
| 40 | 40 | ||
| 41 | #if defined(DEBUG) || defined(CONFIG_USB_DEBUG) || defined(PCMCIA_DEBUG) | 41 | #if defined(DEBUG) || defined(PCMCIA_DEBUG) |
| 42 | 42 | ||
| 43 | static int pc_debug = 0; | 43 | static int pc_debug = 0; |
| 44 | module_param(pc_debug, int, 0644); | 44 | module_param(pc_debug, int, 0644); |
| @@ -129,7 +129,8 @@ static int sl811_hc_init(struct device *parent, ioaddr_t base_addr, int irq) | |||
| 129 | resources[2].end = base_addr + 1; | 129 | resources[2].end = base_addr + 1; |
| 130 | 130 | ||
| 131 | /* The driver core will probe for us. We know sl811-hcd has been | 131 | /* The driver core will probe for us. We know sl811-hcd has been |
| 132 | * initialized already because of the link order dependency. | 132 | * initialized already because of the link order dependency created |
| 133 | * by referencing "sl811h_driver". | ||
| 133 | */ | 134 | */ |
| 134 | platform_dev.name = sl811h_driver.name; | 135 | platform_dev.name = sl811h_driver.name; |
| 135 | return platform_device_register(&platform_dev); | 136 | return platform_device_register(&platform_dev); |
diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c index 151154df37fa..5832953086f8 100644 --- a/drivers/usb/host/uhci-debug.c +++ b/drivers/usb/host/uhci-debug.c | |||
| @@ -2,8 +2,8 @@ | |||
| 2 | * UHCI-specific debugging code. Invaluable when something | 2 | * UHCI-specific debugging code. Invaluable when something |
| 3 | * goes wrong, but don't get in my face. | 3 | * goes wrong, but don't get in my face. |
| 4 | * | 4 | * |
| 5 | * Kernel visible pointers are surrounded in []'s and bus | 5 | * Kernel visible pointers are surrounded in []s and bus |
| 6 | * visible pointers are surrounded in ()'s | 6 | * visible pointers are surrounded in ()s |
| 7 | * | 7 | * |
| 8 | * (C) Copyright 1999 Linus Torvalds | 8 | * (C) Copyright 1999 Linus Torvalds |
| 9 | * (C) Copyright 1999-2001 Johannes Erdfelt | 9 | * (C) Copyright 1999-2001 Johannes Erdfelt |
| @@ -19,7 +19,7 @@ | |||
| 19 | 19 | ||
| 20 | static struct dentry *uhci_debugfs_root = NULL; | 20 | static struct dentry *uhci_debugfs_root = NULL; |
| 21 | 21 | ||
| 22 | /* Handle REALLY large printk's so we don't overflow buffers */ | 22 | /* Handle REALLY large printks so we don't overflow buffers */ |
| 23 | static inline void lprintk(char *buf) | 23 | static inline void lprintk(char *buf) |
| 24 | { | 24 | { |
| 25 | char *p; | 25 | char *p; |
| @@ -160,7 +160,7 @@ static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space) | |||
| 160 | } | 160 | } |
| 161 | 161 | ||
| 162 | if (active && ni > i) { | 162 | if (active && ni > i) { |
| 163 | out += sprintf(out, "%*s[skipped %d active TD's]\n", space, "", ni - i); | 163 | out += sprintf(out, "%*s[skipped %d active TDs]\n", space, "", ni - i); |
| 164 | tmp = ntmp; | 164 | tmp = ntmp; |
| 165 | td = ntd; | 165 | td = ntd; |
| 166 | i = ni; | 166 | i = ni; |
| @@ -173,7 +173,7 @@ static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space) | |||
| 173 | if (list_empty(&urbp->queue_list) || urbp->queued) | 173 | if (list_empty(&urbp->queue_list) || urbp->queued) |
| 174 | goto out; | 174 | goto out; |
| 175 | 175 | ||
| 176 | out += sprintf(out, "%*sQueued QH's:\n", -space, "--"); | 176 | out += sprintf(out, "%*sQueued QHs:\n", -space, "--"); |
| 177 | 177 | ||
| 178 | head = &urbp->queue_list; | 178 | head = &urbp->queue_list; |
| 179 | tmp = head->next; | 179 | tmp = head->next; |
| @@ -197,7 +197,7 @@ out: | |||
| 197 | } | 197 | } |
| 198 | 198 | ||
| 199 | #ifdef CONFIG_PROC_FS | 199 | #ifdef CONFIG_PROC_FS |
| 200 | static const char *qh_names[] = { | 200 | static const char * const qh_names[] = { |
| 201 | "skel_int128_qh", "skel_int64_qh", | 201 | "skel_int128_qh", "skel_int64_qh", |
| 202 | "skel_int32_qh", "skel_int16_qh", | 202 | "skel_int32_qh", "skel_int16_qh", |
| 203 | "skel_int8_qh", "skel_int4_qh", | 203 | "skel_int8_qh", "skel_int4_qh", |
| @@ -464,7 +464,7 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len) | |||
| 464 | } while (tmp != head); | 464 | } while (tmp != head); |
| 465 | } | 465 | } |
| 466 | 466 | ||
| 467 | out += sprintf(out, "Skeleton QH's\n"); | 467 | out += sprintf(out, "Skeleton QHs\n"); |
| 468 | 468 | ||
| 469 | for (i = 0; i < UHCI_NUM_SKELQH; ++i) { | 469 | for (i = 0; i < UHCI_NUM_SKELQH; ++i) { |
| 470 | int shown = 0; | 470 | int shown = 0; |
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index 79efaf7d86a3..dfe121d35887 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c | |||
| @@ -23,11 +23,6 @@ | |||
| 23 | */ | 23 | */ |
| 24 | 24 | ||
| 25 | #include <linux/config.h> | 25 | #include <linux/config.h> |
| 26 | #ifdef CONFIG_USB_DEBUG | ||
| 27 | #define DEBUG | ||
| 28 | #else | ||
| 29 | #undef DEBUG | ||
| 30 | #endif | ||
| 31 | #include <linux/module.h> | 26 | #include <linux/module.h> |
| 32 | #include <linux/pci.h> | 27 | #include <linux/pci.h> |
| 33 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
| @@ -67,10 +62,10 @@ Alan Stern" | |||
| 67 | 62 | ||
| 68 | /* | 63 | /* |
| 69 | * debug = 0, no debugging messages | 64 | * debug = 0, no debugging messages |
| 70 | * debug = 1, dump failed URB's except for stalls | 65 | * debug = 1, dump failed URBs except for stalls |
| 71 | * debug = 2, dump all failed URB's (including stalls) | 66 | * debug = 2, dump all failed URBs (including stalls) |
| 72 | * show all queues in /debug/uhci/[pci_addr] | 67 | * show all queues in /debug/uhci/[pci_addr] |
| 73 | * debug = 3, show all TD's in URB's when dumping | 68 | * debug = 3, show all TDs in URBs when dumping |
| 74 | */ | 69 | */ |
| 75 | #ifdef DEBUG | 70 | #ifdef DEBUG |
| 76 | static int debug = 1; | 71 | static int debug = 1; |
| @@ -93,7 +88,7 @@ static void uhci_get_current_frame_number(struct uhci_hcd *uhci); | |||
| 93 | #define FSBR_DELAY msecs_to_jiffies(50) | 88 | #define FSBR_DELAY msecs_to_jiffies(50) |
| 94 | 89 | ||
| 95 | /* When we timeout an idle transfer for FSBR, we'll switch it over to */ | 90 | /* When we timeout an idle transfer for FSBR, we'll switch it over to */ |
| 96 | /* depth first traversal. We'll do it in groups of this number of TD's */ | 91 | /* depth first traversal. We'll do it in groups of this number of TDs */ |
| 97 | /* to make sure it doesn't hog all of the bandwidth */ | 92 | /* to make sure it doesn't hog all of the bandwidth */ |
| 98 | #define DEPTH_INTERVAL 5 | 93 | #define DEPTH_INTERVAL 5 |
| 99 | 94 | ||
| @@ -478,8 +473,6 @@ static int uhci_start(struct usb_hcd *hcd) | |||
| 478 | struct dentry *dentry; | 473 | struct dentry *dentry; |
| 479 | 474 | ||
| 480 | hcd->uses_new_polling = 1; | 475 | hcd->uses_new_polling = 1; |
| 481 | if (pci_find_capability(to_pci_dev(uhci_dev(uhci)), PCI_CAP_ID_PM)) | ||
| 482 | hcd->can_wakeup = 1; /* Assume it supports PME# */ | ||
| 483 | 476 | ||
| 484 | dentry = debugfs_create_file(hcd->self.bus_name, | 477 | dentry = debugfs_create_file(hcd->self.bus_name, |
| 485 | S_IFREG|S_IRUGO|S_IWUSR, uhci_debugfs_root, uhci, | 478 | S_IFREG|S_IRUGO|S_IWUSR, uhci_debugfs_root, uhci, |
| @@ -573,7 +566,7 @@ static int uhci_start(struct usb_hcd *hcd) | |||
| 573 | uhci->skel_bulk_qh->link = cpu_to_le32(uhci->skel_term_qh->dma_handle) | UHCI_PTR_QH; | 566 | uhci->skel_bulk_qh->link = cpu_to_le32(uhci->skel_term_qh->dma_handle) | UHCI_PTR_QH; |
| 574 | 567 | ||
| 575 | /* This dummy TD is to work around a bug in Intel PIIX controllers */ | 568 | /* This dummy TD is to work around a bug in Intel PIIX controllers */ |
| 576 | uhci_fill_td(uhci->term_td, 0, (UHCI_NULL_DATA_SIZE << 21) | | 569 | uhci_fill_td(uhci->term_td, 0, uhci_explen(0) | |
| 577 | (0x7f << TD_TOKEN_DEVADDR_SHIFT) | USB_PID_IN, 0); | 570 | (0x7f << TD_TOKEN_DEVADDR_SHIFT) | USB_PID_IN, 0); |
| 578 | uhci->term_td->link = cpu_to_le32(uhci->term_td->dma_handle); | 571 | uhci->term_td->link = cpu_to_le32(uhci->term_td->dma_handle); |
| 579 | 572 | ||
| @@ -735,8 +728,9 @@ static int uhci_resume(struct usb_hcd *hcd) | |||
| 735 | 728 | ||
| 736 | dev_dbg(uhci_dev(uhci), "%s\n", __FUNCTION__); | 729 | dev_dbg(uhci_dev(uhci), "%s\n", __FUNCTION__); |
| 737 | 730 | ||
| 738 | /* We aren't in D3 state anymore, we do that even if dead as I | 731 | /* Since we aren't in D3 any more, it's safe to set this flag |
| 739 | * really don't want to keep a stale HCD_FLAG_HW_ACCESSIBLE=0 | 732 | * even if the controller was dead. It might not even be dead |
| 733 | * any more, if the firmware or quirks code has reset it. | ||
| 740 | */ | 734 | */ |
| 741 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | 735 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); |
| 742 | mb(); | 736 | mb(); |
| @@ -755,8 +749,12 @@ static int uhci_resume(struct usb_hcd *hcd) | |||
| 755 | check_and_reset_hc(uhci); | 749 | check_and_reset_hc(uhci); |
| 756 | configure_hc(uhci); | 750 | configure_hc(uhci); |
| 757 | 751 | ||
| 758 | if (uhci->rh_state == UHCI_RH_RESET) | 752 | if (uhci->rh_state == UHCI_RH_RESET) { |
| 753 | |||
| 754 | /* The controller had to be reset */ | ||
| 755 | usb_root_hub_lost_power(hcd->self.root_hub); | ||
| 759 | suspend_rh(uhci, UHCI_RH_SUSPENDED); | 756 | suspend_rh(uhci, UHCI_RH_SUSPENDED); |
| 757 | } | ||
| 760 | 758 | ||
| 761 | spin_unlock_irq(&uhci->lock); | 759 | spin_unlock_irq(&uhci->lock); |
| 762 | 760 | ||
| @@ -882,7 +880,7 @@ static int __init uhci_hcd_init(void) | |||
| 882 | 880 | ||
| 883 | init_failed: | 881 | init_failed: |
| 884 | if (kmem_cache_destroy(uhci_up_cachep)) | 882 | if (kmem_cache_destroy(uhci_up_cachep)) |
| 885 | warn("not all urb_priv's were freed!"); | 883 | warn("not all urb_privs were freed!"); |
| 886 | 884 | ||
| 887 | up_failed: | 885 | up_failed: |
| 888 | debugfs_remove(uhci_debugfs_root); | 886 | debugfs_remove(uhci_debugfs_root); |
| @@ -900,7 +898,7 @@ static void __exit uhci_hcd_cleanup(void) | |||
| 900 | pci_unregister_driver(&uhci_pci_driver); | 898 | pci_unregister_driver(&uhci_pci_driver); |
| 901 | 899 | ||
| 902 | if (kmem_cache_destroy(uhci_up_cachep)) | 900 | if (kmem_cache_destroy(uhci_up_cachep)) |
| 903 | warn("not all urb_priv's were freed!"); | 901 | warn("not all urb_privs were freed!"); |
| 904 | 902 | ||
| 905 | debugfs_remove(uhci_debugfs_root); | 903 | debugfs_remove(uhci_debugfs_root); |
| 906 | kfree(errbuf); | 904 | kfree(errbuf); |
diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h index e576db57a926..8b4b887a7d41 100644 --- a/drivers/usb/host/uhci-hcd.h +++ b/drivers/usb/host/uhci-hcd.h | |||
| @@ -71,8 +71,6 @@ | |||
| 71 | #define USBLEGSUP_RWC 0x8f00 /* the R/WC bits */ | 71 | #define USBLEGSUP_RWC 0x8f00 /* the R/WC bits */ |
| 72 | #define USBLEGSUP_RO 0x5040 /* R/O and reserved bits */ | 72 | #define USBLEGSUP_RO 0x5040 /* R/O and reserved bits */ |
| 73 | 73 | ||
| 74 | #define UHCI_NULL_DATA_SIZE 0x7FF /* for UHCI controller TD */ | ||
| 75 | |||
| 76 | #define UHCI_PTR_BITS cpu_to_le32(0x000F) | 74 | #define UHCI_PTR_BITS cpu_to_le32(0x000F) |
| 77 | #define UHCI_PTR_TERM cpu_to_le32(0x0001) | 75 | #define UHCI_PTR_TERM cpu_to_le32(0x0001) |
| 78 | #define UHCI_PTR_QH cpu_to_le32(0x0002) | 76 | #define UHCI_PTR_QH cpu_to_le32(0x0002) |
| @@ -168,9 +166,11 @@ static __le32 inline qh_element(struct uhci_qh *qh) { | |||
| 168 | #define TD_TOKEN_EXPLEN_MASK 0x7FF /* expected length, encoded as n - 1 */ | 166 | #define TD_TOKEN_EXPLEN_MASK 0x7FF /* expected length, encoded as n - 1 */ |
| 169 | #define TD_TOKEN_PID_MASK 0xFF | 167 | #define TD_TOKEN_PID_MASK 0xFF |
| 170 | 168 | ||
| 171 | #define uhci_explen(len) ((len) << TD_TOKEN_EXPLEN_SHIFT) | 169 | #define uhci_explen(len) ((((len) - 1) & TD_TOKEN_EXPLEN_MASK) << \ |
| 170 | TD_TOKEN_EXPLEN_SHIFT) | ||
| 172 | 171 | ||
| 173 | #define uhci_expected_length(token) ((((token) >> 21) + 1) & TD_TOKEN_EXPLEN_MASK) | 172 | #define uhci_expected_length(token) ((((token) >> TD_TOKEN_EXPLEN_SHIFT) + \ |
| 173 | 1) & TD_TOKEN_EXPLEN_MASK) | ||
| 174 | #define uhci_toggle(token) (((token) >> TD_TOKEN_TOGGLE_SHIFT) & 1) | 174 | #define uhci_toggle(token) (((token) >> TD_TOKEN_TOGGLE_SHIFT) & 1) |
| 175 | #define uhci_endpoint(token) (((token) >> 15) & 0xf) | 175 | #define uhci_endpoint(token) (((token) >> 15) & 0xf) |
| 176 | #define uhci_devaddr(token) (((token) >> TD_TOKEN_DEVADDR_SHIFT) & 0x7f) | 176 | #define uhci_devaddr(token) (((token) >> TD_TOKEN_DEVADDR_SHIFT) & 0x7f) |
| @@ -223,10 +223,10 @@ static u32 inline td_status(struct uhci_td *td) { | |||
| 223 | */ | 223 | */ |
| 224 | 224 | ||
| 225 | /* | 225 | /* |
| 226 | * The UHCI driver places Interrupt, Control and Bulk into QH's both | 226 | * The UHCI driver places Interrupt, Control and Bulk into QHs both |
| 227 | * to group together TD's for one transfer, and also to faciliate queuing | 227 | * to group together TDs for one transfer, and also to facilitate queuing |
| 228 | * of URB's. To make it easy to insert entries into the schedule, we have | 228 | * of URBs. To make it easy to insert entries into the schedule, we have |
| 229 | * a skeleton of QH's for each predefined Interrupt latency, low-speed | 229 | * a skeleton of QHs for each predefined Interrupt latency, low-speed |
| 230 | * control, full-speed control and terminating QH (see explanation for | 230 | * control, full-speed control and terminating QH (see explanation for |
| 231 | * the terminating QH below). | 231 | * the terminating QH below). |
| 232 | * | 232 | * |
| @@ -257,8 +257,8 @@ static u32 inline td_status(struct uhci_td *td) { | |||
| 257 | * reclamation. | 257 | * reclamation. |
| 258 | * | 258 | * |
| 259 | * Isochronous transfers are stored before the start of the skeleton | 259 | * Isochronous transfers are stored before the start of the skeleton |
| 260 | * schedule and don't use QH's. While the UHCI spec doesn't forbid the | 260 | * schedule and don't use QHs. While the UHCI spec doesn't forbid the |
| 261 | * use of QH's for Isochronous, it doesn't use them either. And the spec | 261 | * use of QHs for Isochronous, it doesn't use them either. And the spec |
| 262 | * says that queues never advance on an error completion status, which | 262 | * says that queues never advance on an error completion status, which |
| 263 | * makes them totally unsuitable for Isochronous transfers. | 263 | * makes them totally unsuitable for Isochronous transfers. |
| 264 | */ | 264 | */ |
| @@ -359,7 +359,7 @@ struct uhci_hcd { | |||
| 359 | struct dma_pool *td_pool; | 359 | struct dma_pool *td_pool; |
| 360 | 360 | ||
| 361 | struct uhci_td *term_td; /* Terminating TD, see UHCI bug */ | 361 | struct uhci_td *term_td; /* Terminating TD, see UHCI bug */ |
| 362 | struct uhci_qh *skelqh[UHCI_NUM_SKELQH]; /* Skeleton QH's */ | 362 | struct uhci_qh *skelqh[UHCI_NUM_SKELQH]; /* Skeleton QHs */ |
| 363 | 363 | ||
| 364 | spinlock_t lock; | 364 | spinlock_t lock; |
| 365 | 365 | ||
| @@ -389,22 +389,22 @@ struct uhci_hcd { | |||
| 389 | unsigned long resuming_ports; | 389 | unsigned long resuming_ports; |
| 390 | unsigned long ports_timeout; /* Time to stop signalling */ | 390 | unsigned long ports_timeout; /* Time to stop signalling */ |
| 391 | 391 | ||
| 392 | /* Main list of URB's currently controlled by this HC */ | 392 | /* Main list of URBs currently controlled by this HC */ |
| 393 | struct list_head urb_list; | 393 | struct list_head urb_list; |
| 394 | 394 | ||
| 395 | /* List of QH's that are done, but waiting to be unlinked (race) */ | 395 | /* List of QHs that are done, but waiting to be unlinked (race) */ |
| 396 | struct list_head qh_remove_list; | 396 | struct list_head qh_remove_list; |
| 397 | unsigned int qh_remove_age; /* Age in frames */ | 397 | unsigned int qh_remove_age; /* Age in frames */ |
| 398 | 398 | ||
| 399 | /* List of TD's that are done, but waiting to be freed (race) */ | 399 | /* List of TDs that are done, but waiting to be freed (race) */ |
| 400 | struct list_head td_remove_list; | 400 | struct list_head td_remove_list; |
| 401 | unsigned int td_remove_age; /* Age in frames */ | 401 | unsigned int td_remove_age; /* Age in frames */ |
| 402 | 402 | ||
| 403 | /* List of asynchronously unlinked URB's */ | 403 | /* List of asynchronously unlinked URBs */ |
| 404 | struct list_head urb_remove_list; | 404 | struct list_head urb_remove_list; |
| 405 | unsigned int urb_remove_age; /* Age in frames */ | 405 | unsigned int urb_remove_age; /* Age in frames */ |
| 406 | 406 | ||
| 407 | /* List of URB's awaiting completion callback */ | 407 | /* List of URBs awaiting completion callback */ |
| 408 | struct list_head complete_list; | 408 | struct list_head complete_list; |
| 409 | 409 | ||
| 410 | int rh_numports; /* Number of root-hub ports */ | 410 | int rh_numports; /* Number of root-hub ports */ |
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index 7e46887d9e12..b6076004a437 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c | |||
| @@ -80,7 +80,7 @@ static inline void uhci_fill_td(struct uhci_td *td, u32 status, | |||
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | /* | 82 | /* |
| 83 | * We insert Isochronous URB's directly into the frame list at the beginning | 83 | * We insert Isochronous URBs directly into the frame list at the beginning |
| 84 | */ | 84 | */ |
| 85 | static void uhci_insert_td_frame_list(struct uhci_hcd *uhci, struct uhci_td *td, unsigned framenum) | 85 | static void uhci_insert_td_frame_list(struct uhci_hcd *uhci, struct uhci_td *td, unsigned framenum) |
| 86 | { | 86 | { |
| @@ -369,7 +369,7 @@ static void uhci_append_queued_urb(struct uhci_hcd *uhci, struct urb *eurb, stru | |||
| 369 | uhci_fixup_toggle(urb, | 369 | uhci_fixup_toggle(urb, |
| 370 | uhci_toggle(td_token(lltd)) ^ 1)); | 370 | uhci_toggle(td_token(lltd)) ^ 1)); |
| 371 | 371 | ||
| 372 | /* All qh's in the queue need to link to the next queue */ | 372 | /* All qhs in the queue need to link to the next queue */ |
| 373 | urbp->qh->link = eurbp->qh->link; | 373 | urbp->qh->link = eurbp->qh->link; |
| 374 | 374 | ||
| 375 | wmb(); /* Make sure we flush everything */ | 375 | wmb(); /* Make sure we flush everything */ |
| @@ -502,7 +502,7 @@ static void uhci_destroy_urb_priv(struct uhci_hcd *uhci, struct urb *urb) | |||
| 502 | } | 502 | } |
| 503 | 503 | ||
| 504 | /* Check to see if the remove list is empty. Set the IOC bit */ | 504 | /* Check to see if the remove list is empty. Set the IOC bit */ |
| 505 | /* to force an interrupt so we can remove the TD's*/ | 505 | /* to force an interrupt so we can remove the TDs*/ |
| 506 | if (list_empty(&uhci->td_remove_list)) | 506 | if (list_empty(&uhci->td_remove_list)) |
| 507 | uhci_set_next_interrupt(uhci); | 507 | uhci_set_next_interrupt(uhci); |
| 508 | 508 | ||
| @@ -596,7 +596,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, struct ur | |||
| 596 | return -ENOMEM; | 596 | return -ENOMEM; |
| 597 | 597 | ||
| 598 | uhci_add_td_to_urb(urb, td); | 598 | uhci_add_td_to_urb(urb, td); |
| 599 | uhci_fill_td(td, status, destination | uhci_explen(7), | 599 | uhci_fill_td(td, status, destination | uhci_explen(8), |
| 600 | urb->setup_dma); | 600 | urb->setup_dma); |
| 601 | 601 | ||
| 602 | /* | 602 | /* |
| @@ -612,7 +612,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, struct ur | |||
| 612 | } | 612 | } |
| 613 | 613 | ||
| 614 | /* | 614 | /* |
| 615 | * Build the DATA TD's | 615 | * Build the DATA TDs |
| 616 | */ | 616 | */ |
| 617 | while (len > 0) { | 617 | while (len > 0) { |
| 618 | int pktsze = len; | 618 | int pktsze = len; |
| @@ -628,7 +628,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, struct ur | |||
| 628 | destination ^= TD_TOKEN_TOGGLE; | 628 | destination ^= TD_TOKEN_TOGGLE; |
| 629 | 629 | ||
| 630 | uhci_add_td_to_urb(urb, td); | 630 | uhci_add_td_to_urb(urb, td); |
| 631 | uhci_fill_td(td, status, destination | uhci_explen(pktsze - 1), | 631 | uhci_fill_td(td, status, destination | uhci_explen(pktsze), |
| 632 | data); | 632 | data); |
| 633 | 633 | ||
| 634 | data += pktsze; | 634 | data += pktsze; |
| @@ -658,7 +658,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, struct ur | |||
| 658 | 658 | ||
| 659 | uhci_add_td_to_urb(urb, td); | 659 | uhci_add_td_to_urb(urb, td); |
| 660 | uhci_fill_td(td, status | TD_CTRL_IOC, | 660 | uhci_fill_td(td, status | TD_CTRL_IOC, |
| 661 | destination | uhci_explen(UHCI_NULL_DATA_SIZE), 0); | 661 | destination | uhci_explen(0), 0); |
| 662 | 662 | ||
| 663 | qh = uhci_alloc_qh(uhci); | 663 | qh = uhci_alloc_qh(uhci); |
| 664 | if (!qh) | 664 | if (!qh) |
| @@ -744,7 +744,7 @@ static int uhci_result_control(struct uhci_hcd *uhci, struct urb *urb) | |||
| 744 | 744 | ||
| 745 | urb->actual_length = 0; | 745 | urb->actual_length = 0; |
| 746 | 746 | ||
| 747 | /* The rest of the TD's (but the last) are data */ | 747 | /* The rest of the TDs (but the last) are data */ |
| 748 | tmp = tmp->next; | 748 | tmp = tmp->next; |
| 749 | while (tmp != head && tmp->next != head) { | 749 | while (tmp != head && tmp->next != head) { |
| 750 | unsigned int ctrlstat; | 750 | unsigned int ctrlstat; |
| @@ -848,7 +848,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, struct urb | |||
| 848 | status |= TD_CTRL_SPD; | 848 | status |= TD_CTRL_SPD; |
| 849 | 849 | ||
| 850 | /* | 850 | /* |
| 851 | * Build the DATA TD's | 851 | * Build the DATA TDs |
| 852 | */ | 852 | */ |
| 853 | do { /* Allow zero length packets */ | 853 | do { /* Allow zero length packets */ |
| 854 | int pktsze = maxsze; | 854 | int pktsze = maxsze; |
| @@ -864,7 +864,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, struct urb | |||
| 864 | return -ENOMEM; | 864 | return -ENOMEM; |
| 865 | 865 | ||
| 866 | uhci_add_td_to_urb(urb, td); | 866 | uhci_add_td_to_urb(urb, td); |
| 867 | uhci_fill_td(td, status, destination | uhci_explen(pktsze - 1) | | 867 | uhci_fill_td(td, status, destination | uhci_explen(pktsze) | |
| 868 | (usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), | 868 | (usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), |
| 869 | usb_pipeout(urb->pipe)) << TD_TOKEN_TOGGLE_SHIFT), | 869 | usb_pipeout(urb->pipe)) << TD_TOKEN_TOGGLE_SHIFT), |
| 870 | data); | 870 | data); |
| @@ -890,7 +890,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, struct urb | |||
| 890 | return -ENOMEM; | 890 | return -ENOMEM; |
| 891 | 891 | ||
| 892 | uhci_add_td_to_urb(urb, td); | 892 | uhci_add_td_to_urb(urb, td); |
| 893 | uhci_fill_td(td, status, destination | uhci_explen(UHCI_NULL_DATA_SIZE) | | 893 | uhci_fill_td(td, status, destination | uhci_explen(0) | |
| 894 | (usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), | 894 | (usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), |
| 895 | usb_pipeout(urb->pipe)) << TD_TOKEN_TOGGLE_SHIFT), | 895 | usb_pipeout(urb->pipe)) << TD_TOKEN_TOGGLE_SHIFT), |
| 896 | data); | 896 | data); |
| @@ -1025,7 +1025,7 @@ static int isochronous_find_limits(struct uhci_hcd *uhci, struct urb *urb, unsig | |||
| 1025 | list_for_each_entry(up, &uhci->urb_list, urb_list) { | 1025 | list_for_each_entry(up, &uhci->urb_list, urb_list) { |
| 1026 | struct urb *u = up->urb; | 1026 | struct urb *u = up->urb; |
| 1027 | 1027 | ||
| 1028 | /* look for pending URB's with identical pipe handle */ | 1028 | /* look for pending URBs with identical pipe handle */ |
| 1029 | if ((urb->pipe == u->pipe) && (urb->dev == u->dev) && | 1029 | if ((urb->pipe == u->pipe) && (urb->dev == u->dev) && |
| 1030 | (u->status == -EINPROGRESS) && (u != urb)) { | 1030 | (u->status == -EINPROGRESS) && (u != urb)) { |
| 1031 | if (!last_urb) | 1031 | if (!last_urb) |
| @@ -1092,7 +1092,7 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb) | |||
| 1092 | return -ENOMEM; | 1092 | return -ENOMEM; |
| 1093 | 1093 | ||
| 1094 | uhci_add_td_to_urb(urb, td); | 1094 | uhci_add_td_to_urb(urb, td); |
| 1095 | uhci_fill_td(td, status, destination | uhci_explen(urb->iso_frame_desc[i].length - 1), | 1095 | uhci_fill_td(td, status, destination | uhci_explen(urb->iso_frame_desc[i].length), |
| 1096 | urb->transfer_dma + urb->iso_frame_desc[i].offset); | 1096 | urb->transfer_dma + urb->iso_frame_desc[i].offset); |
| 1097 | 1097 | ||
| 1098 | if (i + 1 >= urb->number_of_packets) | 1098 | if (i + 1 >= urb->number_of_packets) |
| @@ -1355,7 +1355,7 @@ static void uhci_unlink_generic(struct uhci_hcd *uhci, struct urb *urb) | |||
| 1355 | 1355 | ||
| 1356 | uhci_delete_queued_urb(uhci, urb); | 1356 | uhci_delete_queued_urb(uhci, urb); |
| 1357 | 1357 | ||
| 1358 | /* The interrupt loop will reclaim the QH's */ | 1358 | /* The interrupt loop will reclaim the QHs */ |
| 1359 | uhci_remove_qh(uhci, urbp->qh); | 1359 | uhci_remove_qh(uhci, urbp->qh); |
| 1360 | urbp->qh = NULL; | 1360 | urbp->qh = NULL; |
| 1361 | } | 1361 | } |
| @@ -1413,7 +1413,7 @@ static int uhci_fsbr_timeout(struct uhci_hcd *uhci, struct urb *urb) | |||
| 1413 | list_for_each_entry(td, head, list) { | 1413 | list_for_each_entry(td, head, list) { |
| 1414 | /* | 1414 | /* |
| 1415 | * Make sure we don't do the last one (since it'll have the | 1415 | * Make sure we don't do the last one (since it'll have the |
| 1416 | * TERM bit set) as well as we skip every so many TD's to | 1416 | * TERM bit set) as well as we skip every so many TDs to |
| 1417 | * make sure it doesn't hog the bandwidth | 1417 | * make sure it doesn't hog the bandwidth |
| 1418 | */ | 1418 | */ |
| 1419 | if (td->list.next != head && (count % DEPTH_INTERVAL) == | 1419 | if (td->list.next != head && (count % DEPTH_INTERVAL) == |
diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c index 1d973bcf56aa..049871145d63 100644 --- a/drivers/usb/image/mdc800.c +++ b/drivers/usb/image/mdc800.c | |||
| @@ -962,7 +962,6 @@ MODULE_DEVICE_TABLE (usb, mdc800_table); | |||
| 962 | */ | 962 | */ |
| 963 | static struct usb_driver mdc800_usb_driver = | 963 | static struct usb_driver mdc800_usb_driver = |
| 964 | { | 964 | { |
| 965 | .owner = THIS_MODULE, | ||
| 966 | .name = "mdc800", | 965 | .name = "mdc800", |
| 967 | .probe = mdc800_usb_probe, | 966 | .probe = mdc800_usb_probe, |
| 968 | .disconnect = mdc800_usb_disconnect, | 967 | .disconnect = mdc800_usb_disconnect, |
diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c index 950543aa5ac7..458f2acdeb0a 100644 --- a/drivers/usb/image/microtek.c +++ b/drivers/usb/image/microtek.c | |||
| @@ -160,7 +160,6 @@ static void mts_usb_disconnect(struct usb_interface *intf); | |||
| 160 | static struct usb_device_id mts_usb_ids []; | 160 | static struct usb_device_id mts_usb_ids []; |
| 161 | 161 | ||
| 162 | static struct usb_driver mts_usb_driver = { | 162 | static struct usb_driver mts_usb_driver = { |
| 163 | .owner = THIS_MODULE, | ||
| 164 | .name = "microtekX6", | 163 | .name = "microtekX6", |
| 165 | .probe = mts_usb_probe, | 164 | .probe = mts_usb_probe, |
| 166 | .disconnect = mts_usb_disconnect, | 165 | .disconnect = mts_usb_disconnect, |
diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig index 1e53934907c0..509dd0a04c54 100644 --- a/drivers/usb/input/Kconfig +++ b/drivers/usb/input/Kconfig | |||
| @@ -273,6 +273,20 @@ config USB_ATI_REMOTE | |||
| 273 | To compile this driver as a module, choose M here: the module will be | 273 | To compile this driver as a module, choose M here: the module will be |
| 274 | called ati_remote. | 274 | called ati_remote. |
| 275 | 275 | ||
| 276 | config USB_ATI_REMOTE2 | ||
| 277 | tristate "ATI / Philips USB RF remote control" | ||
| 278 | depends on USB && INPUT | ||
| 279 | ---help--- | ||
| 280 | Say Y here if you want to use an ATI or Philips USB RF remote control. | ||
| 281 | These are RF remotes with USB receivers. | ||
| 282 | ATI Remote Wonder II comes with some ATI's All-In-Wonder video cards | ||
| 283 | and is also available as a separate product. | ||
| 284 | This driver provides mouse pointer, left and right mouse buttons, | ||
| 285 | and maps all the other remote buttons to keypress events. | ||
| 286 | |||
| 287 | To compile this driver as a module, choose M here: the module will be | ||
| 288 | called ati_remote2. | ||
| 289 | |||
| 276 | config USB_KEYSPAN_REMOTE | 290 | config USB_KEYSPAN_REMOTE |
| 277 | tristate "Keyspan DMR USB remote control (EXPERIMENTAL)" | 291 | tristate "Keyspan DMR USB remote control (EXPERIMENTAL)" |
| 278 | depends on USB && INPUT && EXPERIMENTAL | 292 | depends on USB && INPUT && EXPERIMENTAL |
diff --git a/drivers/usb/input/Makefile b/drivers/usb/input/Makefile index 07cb17db42fc..d512d9f488fe 100644 --- a/drivers/usb/input/Makefile +++ b/drivers/usb/input/Makefile | |||
| @@ -28,6 +28,7 @@ endif | |||
| 28 | 28 | ||
| 29 | obj-$(CONFIG_USB_AIPTEK) += aiptek.o | 29 | obj-$(CONFIG_USB_AIPTEK) += aiptek.o |
| 30 | obj-$(CONFIG_USB_ATI_REMOTE) += ati_remote.o | 30 | obj-$(CONFIG_USB_ATI_REMOTE) += ati_remote.o |
| 31 | obj-$(CONFIG_USB_ATI_REMOTE2) += ati_remote2.o | ||
| 31 | obj-$(CONFIG_USB_HID) += usbhid.o | 32 | obj-$(CONFIG_USB_HID) += usbhid.o |
| 32 | obj-$(CONFIG_USB_KBD) += usbkbd.o | 33 | obj-$(CONFIG_USB_KBD) += usbkbd.o |
| 33 | obj-$(CONFIG_USB_KBTAB) += kbtab.o | 34 | obj-$(CONFIG_USB_KBTAB) += kbtab.o |
diff --git a/drivers/usb/input/acecad.c b/drivers/usb/input/acecad.c index a32558b4048e..df29b8078b54 100644 --- a/drivers/usb/input/acecad.c +++ b/drivers/usb/input/acecad.c | |||
| @@ -261,7 +261,6 @@ static struct usb_device_id usb_acecad_id_table [] = { | |||
| 261 | MODULE_DEVICE_TABLE(usb, usb_acecad_id_table); | 261 | MODULE_DEVICE_TABLE(usb, usb_acecad_id_table); |
| 262 | 262 | ||
| 263 | static struct usb_driver usb_acecad_driver = { | 263 | static struct usb_driver usb_acecad_driver = { |
| 264 | .owner = THIS_MODULE, | ||
| 265 | .name = "usb_acecad", | 264 | .name = "usb_acecad", |
| 266 | .probe = usb_acecad_probe, | 265 | .probe = usb_acecad_probe, |
| 267 | .disconnect = usb_acecad_disconnect, | 266 | .disconnect = usb_acecad_disconnect, |
diff --git a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c index 0e2505c073db..a6693b0d1c4c 100644 --- a/drivers/usb/input/aiptek.c +++ b/drivers/usb/input/aiptek.c | |||
| @@ -338,7 +338,7 @@ struct aiptek { | |||
| 338 | * the bitmap which comes from the tablet. This hides the | 338 | * the bitmap which comes from the tablet. This hides the |
| 339 | * issue that the F_keys are not sequentially numbered. | 339 | * issue that the F_keys are not sequentially numbered. |
| 340 | */ | 340 | */ |
| 341 | static int macroKeyEvents[] = { | 341 | static const int macroKeyEvents[] = { |
| 342 | KEY_ESC, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, | 342 | KEY_ESC, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, |
| 343 | KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_F11, | 343 | KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_F11, |
| 344 | KEY_F12, KEY_F13, KEY_F14, KEY_F15, KEY_F16, KEY_F17, | 344 | KEY_F12, KEY_F13, KEY_F14, KEY_F15, KEY_F16, KEY_F17, |
| @@ -2093,7 +2093,7 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
| 2093 | /* Programming the tablet macro keys needs to be done with a for loop | 2093 | /* Programming the tablet macro keys needs to be done with a for loop |
| 2094 | * as the keycodes are discontiguous. | 2094 | * as the keycodes are discontiguous. |
| 2095 | */ | 2095 | */ |
| 2096 | for (i = 0; i < sizeof(macroKeyEvents) / sizeof(macroKeyEvents[0]); ++i) | 2096 | for (i = 0; i < ARRAY_SIZE(macroKeyEvents); ++i) |
| 2097 | set_bit(macroKeyEvents[i], inputdev->keybit); | 2097 | set_bit(macroKeyEvents[i], inputdev->keybit); |
| 2098 | 2098 | ||
| 2099 | /* | 2099 | /* |
| @@ -2135,7 +2135,7 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
| 2135 | * not an error :-) | 2135 | * not an error :-) |
| 2136 | */ | 2136 | */ |
| 2137 | 2137 | ||
| 2138 | for (i = 0; i < sizeof(speeds) / sizeof(speeds[0]); ++i) { | 2138 | for (i = 0; i < ARRAY_SIZE(speeds); ++i) { |
| 2139 | aiptek->curSetting.programmableDelay = speeds[i]; | 2139 | aiptek->curSetting.programmableDelay = speeds[i]; |
| 2140 | (void)aiptek_program_tablet(aiptek); | 2140 | (void)aiptek_program_tablet(aiptek); |
| 2141 | if (aiptek->inputdev->absmax[ABS_X] > 0) { | 2141 | if (aiptek->inputdev->absmax[ABS_X] > 0) { |
| @@ -2190,7 +2190,6 @@ fail1: input_free_device(inputdev); | |||
| 2190 | static void aiptek_disconnect(struct usb_interface *intf); | 2190 | static void aiptek_disconnect(struct usb_interface *intf); |
| 2191 | 2191 | ||
| 2192 | static struct usb_driver aiptek_driver = { | 2192 | static struct usb_driver aiptek_driver = { |
| 2193 | .owner = THIS_MODULE, | ||
| 2194 | .name = "aiptek", | 2193 | .name = "aiptek", |
| 2195 | .probe = aiptek_probe, | 2194 | .probe = aiptek_probe, |
| 2196 | .disconnect = aiptek_disconnect, | 2195 | .disconnect = aiptek_disconnect, |
diff --git a/drivers/usb/input/appletouch.c b/drivers/usb/input/appletouch.c index 15840db092a5..1949b54f41f2 100644 --- a/drivers/usb/input/appletouch.c +++ b/drivers/usb/input/appletouch.c | |||
| @@ -452,7 +452,6 @@ static int atp_resume(struct usb_interface *iface) | |||
| 452 | } | 452 | } |
| 453 | 453 | ||
| 454 | static struct usb_driver atp_driver = { | 454 | static struct usb_driver atp_driver = { |
| 455 | .owner = THIS_MODULE, | ||
| 456 | .name = "appletouch", | 455 | .name = "appletouch", |
| 457 | .probe = atp_probe, | 456 | .probe = atp_probe, |
| 458 | .disconnect = atp_disconnect, | 457 | .disconnect = atp_disconnect, |
diff --git a/drivers/usb/input/ati_remote.c b/drivers/usb/input/ati_remote.c index 9a2a47db9494..f7bdc506e613 100644 --- a/drivers/usb/input/ati_remote.c +++ b/drivers/usb/input/ati_remote.c | |||
| @@ -96,6 +96,7 @@ | |||
| 96 | #include <linux/usb.h> | 96 | #include <linux/usb.h> |
| 97 | #include <linux/usb_input.h> | 97 | #include <linux/usb_input.h> |
| 98 | #include <linux/wait.h> | 98 | #include <linux/wait.h> |
| 99 | #include <linux/jiffies.h> | ||
| 99 | 100 | ||
| 100 | /* | 101 | /* |
| 101 | * Module and Version Information, Module Parameters | 102 | * Module and Version Information, Module Parameters |
| @@ -146,7 +147,7 @@ static char init1[] = { 0x01, 0x00, 0x20, 0x14 }; | |||
| 146 | static char init2[] = { 0x01, 0x00, 0x20, 0x14, 0x20, 0x20, 0x20 }; | 147 | static char init2[] = { 0x01, 0x00, 0x20, 0x14, 0x20, 0x20, 0x20 }; |
| 147 | 148 | ||
| 148 | /* Acceleration curve for directional control pad */ | 149 | /* Acceleration curve for directional control pad */ |
| 149 | static char accel[] = { 1, 2, 4, 6, 9, 13, 20 }; | 150 | static const char accel[] = { 1, 2, 4, 6, 9, 13, 20 }; |
| 150 | 151 | ||
| 151 | /* Duplicate event filtering time. | 152 | /* Duplicate event filtering time. |
| 152 | * Sequential, identical KIND_FILTERED inputs with less than | 153 | * Sequential, identical KIND_FILTERED inputs with less than |
| @@ -197,7 +198,7 @@ struct ati_remote { | |||
| 197 | #define KIND_ACCEL 7 /* Directional keypad - left, right, up, down.*/ | 198 | #define KIND_ACCEL 7 /* Directional keypad - left, right, up, down.*/ |
| 198 | 199 | ||
| 199 | /* Translation table from hardware messages to input events. */ | 200 | /* Translation table from hardware messages to input events. */ |
| 200 | static struct { | 201 | static const struct { |
| 201 | short kind; | 202 | short kind; |
| 202 | unsigned char data1, data2; | 203 | unsigned char data1, data2; |
| 203 | int type; | 204 | int type; |
| @@ -295,7 +296,6 @@ static void ati_remote_disconnect (struct usb_interface *interface); | |||
| 295 | 296 | ||
| 296 | /* usb specific object to register with the usb subsystem */ | 297 | /* usb specific object to register with the usb subsystem */ |
| 297 | static struct usb_driver ati_remote_driver = { | 298 | static struct usb_driver ati_remote_driver = { |
| 298 | .owner = THIS_MODULE, | ||
| 299 | .name = "ati_remote", | 299 | .name = "ati_remote", |
| 300 | .probe = ati_remote_probe, | 300 | .probe = ati_remote_probe, |
| 301 | .disconnect = ati_remote_disconnect, | 301 | .disconnect = ati_remote_disconnect, |
| @@ -472,7 +472,7 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs) | |||
| 472 | /* Filter duplicate events which happen "too close" together. */ | 472 | /* Filter duplicate events which happen "too close" together. */ |
| 473 | if ((ati_remote->old_data[0] == data[1]) && | 473 | if ((ati_remote->old_data[0] == data[1]) && |
| 474 | (ati_remote->old_data[1] == data[2]) && | 474 | (ati_remote->old_data[1] == data[2]) && |
| 475 | ((ati_remote->old_jiffies + FILTER_TIME) > jiffies)) { | 475 | time_before(jiffies, ati_remote->old_jiffies + FILTER_TIME)) { |
| 476 | ati_remote->repeat_count++; | 476 | ati_remote->repeat_count++; |
| 477 | } else { | 477 | } else { |
| 478 | ati_remote->repeat_count = 0; | 478 | ati_remote->repeat_count = 0; |
| @@ -507,16 +507,16 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs) | |||
| 507 | * pad down, so we increase acceleration, ramping up over two seconds to | 507 | * pad down, so we increase acceleration, ramping up over two seconds to |
| 508 | * a maximum speed. The acceleration curve is #defined above. | 508 | * a maximum speed. The acceleration curve is #defined above. |
| 509 | */ | 509 | */ |
| 510 | if ((jiffies - ati_remote->old_jiffies) > (HZ >> 2)) { | 510 | if (time_after(jiffies, ati_remote->old_jiffies + (HZ >> 2))) { |
| 511 | acc = 1; | 511 | acc = 1; |
| 512 | ati_remote->acc_jiffies = jiffies; | 512 | ati_remote->acc_jiffies = jiffies; |
| 513 | } | 513 | } |
| 514 | else if ((jiffies - ati_remote->acc_jiffies) < (HZ >> 3)) acc = accel[0]; | 514 | else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ >> 3))) acc = accel[0]; |
| 515 | else if ((jiffies - ati_remote->acc_jiffies) < (HZ >> 2)) acc = accel[1]; | 515 | else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ >> 2))) acc = accel[1]; |
| 516 | else if ((jiffies - ati_remote->acc_jiffies) < (HZ >> 1)) acc = accel[2]; | 516 | else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ >> 1))) acc = accel[2]; |
| 517 | else if ((jiffies - ati_remote->acc_jiffies) < HZ ) acc = accel[3]; | 517 | else if (time_before(jiffies, ati_remote->acc_jiffies + HZ)) acc = accel[3]; |
| 518 | else if ((jiffies - ati_remote->acc_jiffies) < HZ+(HZ>>1)) acc = accel[4]; | 518 | else if (time_before(jiffies, ati_remote->acc_jiffies + HZ+(HZ>>1))) acc = accel[4]; |
| 519 | else if ((jiffies - ati_remote->acc_jiffies) < (HZ << 1)) acc = accel[5]; | 519 | else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ << 1))) acc = accel[5]; |
| 520 | else acc = accel[6]; | 520 | else acc = accel[6]; |
| 521 | 521 | ||
| 522 | input_regs(dev, regs); | 522 | input_regs(dev, regs); |
diff --git a/drivers/usb/input/ati_remote2.c b/drivers/usb/input/ati_remote2.c new file mode 100644 index 000000000000..ab1a1ae24be9 --- /dev/null +++ b/drivers/usb/input/ati_remote2.c | |||
| @@ -0,0 +1,477 @@ | |||
| 1 | /* | ||
| 2 | * ati_remote2 - ATI/Philips USB RF remote driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2005 Ville Syrjala <syrjala@sci.fi> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License version 2 | ||
| 8 | * as published by the Free Software Foundation. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #include <linux/usb_input.h> | ||
| 12 | |||
| 13 | #define DRIVER_DESC "ATI/Philips USB RF remote driver" | ||
| 14 | #define DRIVER_VERSION "0.1" | ||
| 15 | |||
| 16 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
| 17 | MODULE_VERSION(DRIVER_VERSION); | ||
| 18 | MODULE_AUTHOR("Ville Syrjala <syrjala@sci.fi>"); | ||
| 19 | MODULE_LICENSE("GPL"); | ||
| 20 | |||
| 21 | static unsigned int mode_mask = 0x1F; | ||
| 22 | module_param(mode_mask, uint, 0644); | ||
| 23 | MODULE_PARM_DESC(mode_mask, "Bitmask of modes to accept <4:PC><3:AUX4><2:AUX3><1:AUX2><0:AUX1>"); | ||
| 24 | |||
| 25 | static struct usb_device_id ati_remote2_id_table[] = { | ||
| 26 | { USB_DEVICE(0x0471, 0x0602) }, /* ATI Remote Wonder II */ | ||
| 27 | { } | ||
| 28 | }; | ||
| 29 | MODULE_DEVICE_TABLE(usb, ati_remote2_id_table); | ||
| 30 | |||
| 31 | static struct { | ||
| 32 | int hw_code; | ||
| 33 | int key_code; | ||
| 34 | } ati_remote2_key_table[] = { | ||
| 35 | { 0x00, KEY_0 }, | ||
| 36 | { 0x01, KEY_1 }, | ||
| 37 | { 0x02, KEY_2 }, | ||
| 38 | { 0x03, KEY_3 }, | ||
| 39 | { 0x04, KEY_4 }, | ||
| 40 | { 0x05, KEY_5 }, | ||
| 41 | { 0x06, KEY_6 }, | ||
| 42 | { 0x07, KEY_7 }, | ||
| 43 | { 0x08, KEY_8 }, | ||
| 44 | { 0x09, KEY_9 }, | ||
| 45 | { 0x0c, KEY_POWER }, | ||
| 46 | { 0x0d, KEY_MUTE }, | ||
| 47 | { 0x10, KEY_VOLUMEUP }, | ||
| 48 | { 0x11, KEY_VOLUMEDOWN }, | ||
| 49 | { 0x20, KEY_CHANNELUP }, | ||
| 50 | { 0x21, KEY_CHANNELDOWN }, | ||
| 51 | { 0x28, KEY_FORWARD }, | ||
| 52 | { 0x29, KEY_REWIND }, | ||
| 53 | { 0x2c, KEY_PLAY }, | ||
| 54 | { 0x30, KEY_PAUSE }, | ||
| 55 | { 0x31, KEY_STOP }, | ||
| 56 | { 0x37, KEY_RECORD }, | ||
| 57 | { 0x38, KEY_DVD }, | ||
| 58 | { 0x39, KEY_TV }, | ||
| 59 | { 0x54, KEY_MENU }, | ||
| 60 | { 0x58, KEY_UP }, | ||
| 61 | { 0x59, KEY_DOWN }, | ||
| 62 | { 0x5a, KEY_LEFT }, | ||
| 63 | { 0x5b, KEY_RIGHT }, | ||
| 64 | { 0x5c, KEY_OK }, | ||
| 65 | { 0x78, KEY_A }, | ||
| 66 | { 0x79, KEY_B }, | ||
| 67 | { 0x7a, KEY_C }, | ||
| 68 | { 0x7b, KEY_D }, | ||
| 69 | { 0x7c, KEY_E }, | ||
| 70 | { 0x7d, KEY_F }, | ||
| 71 | { 0x82, KEY_ENTER }, | ||
| 72 | { 0x8e, KEY_VENDOR }, | ||
| 73 | { 0x96, KEY_COFFEE }, | ||
| 74 | { 0xa9, BTN_LEFT }, | ||
| 75 | { 0xaa, BTN_RIGHT }, | ||
| 76 | { 0xbe, KEY_QUESTION }, | ||
| 77 | { 0xd5, KEY_FRONT }, | ||
| 78 | { 0xd0, KEY_EDIT }, | ||
| 79 | { 0xf9, KEY_INFO }, | ||
| 80 | { (0x00 << 8) | 0x3f, KEY_PROG1 }, | ||
| 81 | { (0x01 << 8) | 0x3f, KEY_PROG2 }, | ||
| 82 | { (0x02 << 8) | 0x3f, KEY_PROG3 }, | ||
| 83 | { (0x03 << 8) | 0x3f, KEY_PROG4 }, | ||
| 84 | { (0x04 << 8) | 0x3f, KEY_PC }, | ||
| 85 | { 0, KEY_RESERVED } | ||
| 86 | }; | ||
| 87 | |||
| 88 | struct ati_remote2 { | ||
| 89 | struct input_dev *idev; | ||
| 90 | struct usb_device *udev; | ||
| 91 | |||
| 92 | struct usb_interface *intf[2]; | ||
| 93 | struct usb_endpoint_descriptor *ep[2]; | ||
| 94 | struct urb *urb[2]; | ||
| 95 | void *buf[2]; | ||
| 96 | dma_addr_t buf_dma[2]; | ||
| 97 | |||
| 98 | unsigned long jiffies; | ||
| 99 | int mode; | ||
| 100 | |||
| 101 | char name[64]; | ||
| 102 | char phys[64]; | ||
| 103 | }; | ||
| 104 | |||
| 105 | static int ati_remote2_probe(struct usb_interface *interface, const struct usb_device_id *id); | ||
| 106 | static void ati_remote2_disconnect(struct usb_interface *interface); | ||
| 107 | |||
| 108 | static struct usb_driver ati_remote2_driver = { | ||
| 109 | .name = "ati_remote2", | ||
| 110 | .probe = ati_remote2_probe, | ||
| 111 | .disconnect = ati_remote2_disconnect, | ||
| 112 | .id_table = ati_remote2_id_table, | ||
| 113 | }; | ||
| 114 | |||
| 115 | static int ati_remote2_open(struct input_dev *idev) | ||
| 116 | { | ||
| 117 | struct ati_remote2 *ar2 = idev->private; | ||
| 118 | int r; | ||
| 119 | |||
| 120 | r = usb_submit_urb(ar2->urb[0], GFP_KERNEL); | ||
| 121 | if (r) { | ||
| 122 | dev_err(&ar2->intf[0]->dev, | ||
| 123 | "%s: usb_submit_urb() = %d\n", __FUNCTION__, r); | ||
| 124 | return r; | ||
| 125 | } | ||
| 126 | r = usb_submit_urb(ar2->urb[1], GFP_KERNEL); | ||
| 127 | if (r) { | ||
| 128 | usb_kill_urb(ar2->urb[0]); | ||
| 129 | dev_err(&ar2->intf[1]->dev, | ||
| 130 | "%s: usb_submit_urb() = %d\n", __FUNCTION__, r); | ||
| 131 | return r; | ||
| 132 | } | ||
| 133 | |||
| 134 | return 0; | ||
| 135 | } | ||
| 136 | |||
| 137 | static void ati_remote2_close(struct input_dev *idev) | ||
| 138 | { | ||
| 139 | struct ati_remote2 *ar2 = idev->private; | ||
| 140 | |||
| 141 | usb_kill_urb(ar2->urb[0]); | ||
| 142 | usb_kill_urb(ar2->urb[1]); | ||
| 143 | } | ||
| 144 | |||
| 145 | static void ati_remote2_input_mouse(struct ati_remote2 *ar2, struct pt_regs *regs) | ||
| 146 | { | ||
| 147 | struct input_dev *idev = ar2->idev; | ||
| 148 | u8 *data = ar2->buf[0]; | ||
| 149 | |||
| 150 | if (data[0] > 4) { | ||
| 151 | dev_err(&ar2->intf[0]->dev, | ||
| 152 | "Unknown mode byte (%02x %02x %02x %02x)\n", | ||
| 153 | data[3], data[2], data[1], data[0]); | ||
| 154 | return; | ||
| 155 | } | ||
| 156 | |||
| 157 | if (!((1 << data[0]) & mode_mask)) | ||
| 158 | return; | ||
| 159 | |||
| 160 | input_regs(idev, regs); | ||
| 161 | input_event(idev, EV_REL, REL_X, (s8) data[1]); | ||
| 162 | input_event(idev, EV_REL, REL_Y, (s8) data[2]); | ||
| 163 | input_sync(idev); | ||
| 164 | } | ||
| 165 | |||
| 166 | static int ati_remote2_lookup(unsigned int hw_code) | ||
| 167 | { | ||
| 168 | int i; | ||
| 169 | |||
| 170 | for (i = 0; ati_remote2_key_table[i].key_code != KEY_RESERVED; i++) | ||
| 171 | if (ati_remote2_key_table[i].hw_code == hw_code) | ||
| 172 | return i; | ||
| 173 | |||
| 174 | return -1; | ||
| 175 | } | ||
| 176 | |||
| 177 | static void ati_remote2_input_key(struct ati_remote2 *ar2, struct pt_regs *regs) | ||
| 178 | { | ||
| 179 | struct input_dev *idev = ar2->idev; | ||
| 180 | u8 *data = ar2->buf[1]; | ||
| 181 | int hw_code, index; | ||
| 182 | |||
| 183 | if (data[0] > 4) { | ||
| 184 | dev_err(&ar2->intf[1]->dev, | ||
| 185 | "Unknown mode byte (%02x %02x %02x %02x)\n", | ||
| 186 | data[3], data[2], data[1], data[0]); | ||
| 187 | return; | ||
| 188 | } | ||
| 189 | |||
| 190 | hw_code = data[2]; | ||
| 191 | /* | ||
| 192 | * Mode keys (AUX1-AUX4, PC) all generate the same code byte. | ||
| 193 | * Use the mode byte to figure out which one was pressed. | ||
| 194 | */ | ||
| 195 | if (hw_code == 0x3f) { | ||
| 196 | /* | ||
| 197 | * For some incomprehensible reason the mouse pad generates | ||
| 198 | * events which look identical to the events from the last | ||
| 199 | * pressed mode key. Naturally we don't want to generate key | ||
| 200 | * events for the mouse pad so we filter out any subsequent | ||
| 201 | * events from the same mode key. | ||
| 202 | */ | ||
| 203 | if (ar2->mode == data[0]) | ||
| 204 | return; | ||
| 205 | |||
| 206 | if (data[1] == 0) | ||
| 207 | ar2->mode = data[0]; | ||
| 208 | |||
| 209 | hw_code |= data[0] << 8; | ||
| 210 | } | ||
| 211 | |||
| 212 | if (!((1 << data[0]) & mode_mask)) | ||
| 213 | return; | ||
| 214 | |||
| 215 | index = ati_remote2_lookup(hw_code); | ||
| 216 | if (index < 0) { | ||
| 217 | dev_err(&ar2->intf[1]->dev, | ||
| 218 | "Unknown code byte (%02x %02x %02x %02x)\n", | ||
| 219 | data[3], data[2], data[1], data[0]); | ||
| 220 | return; | ||
| 221 | } | ||
| 222 | |||
| 223 | switch (data[1]) { | ||
| 224 | case 0: /* release */ | ||
| 225 | break; | ||
| 226 | case 1: /* press */ | ||
| 227 | ar2->jiffies = jiffies + msecs_to_jiffies(idev->rep[REP_DELAY]); | ||
| 228 | break; | ||
| 229 | case 2: /* repeat */ | ||
| 230 | |||
| 231 | /* No repeat for mouse buttons. */ | ||
| 232 | if (ati_remote2_key_table[index].key_code == BTN_LEFT || | ||
| 233 | ati_remote2_key_table[index].key_code == BTN_RIGHT) | ||
| 234 | return; | ||
| 235 | |||
| 236 | if (!time_after_eq(jiffies, ar2->jiffies)) | ||
| 237 | return; | ||
| 238 | |||
| 239 | ar2->jiffies = jiffies + msecs_to_jiffies(idev->rep[REP_PERIOD]); | ||
| 240 | break; | ||
| 241 | default: | ||
| 242 | dev_err(&ar2->intf[1]->dev, | ||
| 243 | "Unknown state byte (%02x %02x %02x %02x)\n", | ||
| 244 | data[3], data[2], data[1], data[0]); | ||
| 245 | return; | ||
| 246 | } | ||
| 247 | |||
| 248 | input_regs(idev, regs); | ||
| 249 | input_event(idev, EV_KEY, ati_remote2_key_table[index].key_code, data[1]); | ||
| 250 | input_sync(idev); | ||
| 251 | } | ||
| 252 | |||
| 253 | static void ati_remote2_complete_mouse(struct urb *urb, struct pt_regs *regs) | ||
| 254 | { | ||
| 255 | struct ati_remote2 *ar2 = urb->context; | ||
| 256 | int r; | ||
| 257 | |||
| 258 | switch (urb->status) { | ||
| 259 | case 0: | ||
| 260 | ati_remote2_input_mouse(ar2, regs); | ||
| 261 | break; | ||
| 262 | case -ENOENT: | ||
| 263 | case -EILSEQ: | ||
| 264 | case -ECONNRESET: | ||
| 265 | case -ESHUTDOWN: | ||
| 266 | dev_dbg(&ar2->intf[0]->dev, | ||
| 267 | "%s(): urb status = %d\n", __FUNCTION__, urb->status); | ||
| 268 | return; | ||
| 269 | default: | ||
| 270 | dev_err(&ar2->intf[0]->dev, | ||
| 271 | "%s(): urb status = %d\n", __FUNCTION__, urb->status); | ||
| 272 | } | ||
| 273 | |||
| 274 | r = usb_submit_urb(urb, GFP_ATOMIC); | ||
| 275 | if (r) | ||
| 276 | dev_err(&ar2->intf[0]->dev, | ||
| 277 | "%s(): usb_submit_urb() = %d\n", __FUNCTION__, r); | ||
| 278 | } | ||
| 279 | |||
| 280 | static void ati_remote2_complete_key(struct urb *urb, struct pt_regs *regs) | ||
| 281 | { | ||
| 282 | struct ati_remote2 *ar2 = urb->context; | ||
| 283 | int r; | ||
| 284 | |||
| 285 | switch (urb->status) { | ||
| 286 | case 0: | ||
| 287 | ati_remote2_input_key(ar2, regs); | ||
| 288 | break; | ||
| 289 | case -ENOENT: | ||
| 290 | case -EILSEQ: | ||
| 291 | case -ECONNRESET: | ||
| 292 | case -ESHUTDOWN: | ||
| 293 | dev_dbg(&ar2->intf[1]->dev, | ||
| 294 | "%s(): urb status = %d\n", __FUNCTION__, urb->status); | ||
| 295 | return; | ||
| 296 | default: | ||
| 297 | dev_err(&ar2->intf[1]->dev, | ||
| 298 | "%s(): urb status = %d\n", __FUNCTION__, urb->status); | ||
| 299 | } | ||
| 300 | |||
| 301 | r = usb_submit_urb(urb, GFP_ATOMIC); | ||
| 302 | if (r) | ||
| 303 | dev_err(&ar2->intf[1]->dev, | ||
| 304 | "%s(): usb_submit_urb() = %d\n", __FUNCTION__, r); | ||
| 305 | } | ||
| 306 | |||
| 307 | static int ati_remote2_input_init(struct ati_remote2 *ar2) | ||
| 308 | { | ||
| 309 | struct input_dev *idev; | ||
| 310 | int i; | ||
| 311 | |||
| 312 | idev = input_allocate_device(); | ||
| 313 | if (!idev) | ||
| 314 | return -ENOMEM; | ||
| 315 | |||
| 316 | ar2->idev = idev; | ||
| 317 | idev->private = ar2; | ||
| 318 | |||
| 319 | idev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_REL); | ||
| 320 | idev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT); | ||
| 321 | idev->relbit[0] = BIT(REL_X) | BIT(REL_Y); | ||
| 322 | for (i = 0; ati_remote2_key_table[i].key_code != KEY_RESERVED; i++) | ||
| 323 | set_bit(ati_remote2_key_table[i].key_code, idev->keybit); | ||
| 324 | |||
| 325 | idev->rep[REP_DELAY] = 250; | ||
| 326 | idev->rep[REP_PERIOD] = 33; | ||
| 327 | |||
| 328 | idev->open = ati_remote2_open; | ||
| 329 | idev->close = ati_remote2_close; | ||
| 330 | |||
| 331 | idev->name = ar2->name; | ||
| 332 | idev->phys = ar2->phys; | ||
| 333 | |||
| 334 | usb_to_input_id(ar2->udev, &idev->id); | ||
| 335 | idev->cdev.dev = &ar2->udev->dev; | ||
| 336 | |||
| 337 | i = input_register_device(idev); | ||
| 338 | if (i) | ||
| 339 | input_free_device(idev); | ||
| 340 | |||
| 341 | return i; | ||
| 342 | } | ||
| 343 | |||
| 344 | static int ati_remote2_urb_init(struct ati_remote2 *ar2) | ||
| 345 | { | ||
| 346 | struct usb_device *udev = ar2->udev; | ||
| 347 | int i, pipe, maxp; | ||
| 348 | |||
| 349 | for (i = 0; i < 2; i++) { | ||
| 350 | ar2->buf[i] = usb_buffer_alloc(udev, 4, GFP_KERNEL, &ar2->buf_dma[i]); | ||
| 351 | if (!ar2->buf[i]) | ||
| 352 | return -ENOMEM; | ||
| 353 | |||
| 354 | ar2->urb[i] = usb_alloc_urb(0, GFP_KERNEL); | ||
| 355 | if (!ar2->urb[i]) | ||
| 356 | return -ENOMEM; | ||
| 357 | |||
| 358 | pipe = usb_rcvintpipe(udev, ar2->ep[i]->bEndpointAddress); | ||
| 359 | maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); | ||
| 360 | maxp = maxp > 4 ? 4 : maxp; | ||
| 361 | |||
| 362 | usb_fill_int_urb(ar2->urb[i], udev, pipe, ar2->buf[i], maxp, | ||
| 363 | i ? ati_remote2_complete_key : ati_remote2_complete_mouse, | ||
| 364 | ar2, ar2->ep[i]->bInterval); | ||
| 365 | ar2->urb[i]->transfer_dma = ar2->buf_dma[i]; | ||
| 366 | ar2->urb[i]->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
| 367 | } | ||
| 368 | |||
| 369 | return 0; | ||
| 370 | } | ||
| 371 | |||
| 372 | static void ati_remote2_urb_cleanup(struct ati_remote2 *ar2) | ||
| 373 | { | ||
| 374 | int i; | ||
| 375 | |||
| 376 | for (i = 0; i < 2; i++) { | ||
| 377 | if (ar2->urb[i]) | ||
| 378 | usb_free_urb(ar2->urb[i]); | ||
| 379 | |||
| 380 | if (ar2->buf[i]) | ||
| 381 | usb_buffer_free(ar2->udev, 4, ar2->buf[i], ar2->buf_dma[i]); | ||
| 382 | } | ||
| 383 | } | ||
| 384 | |||
| 385 | static int ati_remote2_probe(struct usb_interface *interface, const struct usb_device_id *id) | ||
| 386 | { | ||
| 387 | struct usb_device *udev = interface_to_usbdev(interface); | ||
| 388 | struct usb_host_interface *alt = interface->cur_altsetting; | ||
| 389 | struct ati_remote2 *ar2; | ||
| 390 | int r; | ||
| 391 | |||
| 392 | if (alt->desc.bInterfaceNumber) | ||
| 393 | return -ENODEV; | ||
| 394 | |||
| 395 | ar2 = kzalloc(sizeof (struct ati_remote2), GFP_KERNEL); | ||
| 396 | if (!ar2) | ||
| 397 | return -ENOMEM; | ||
| 398 | |||
| 399 | ar2->udev = udev; | ||
| 400 | |||
| 401 | ar2->intf[0] = interface; | ||
| 402 | ar2->ep[0] = &alt->endpoint[0].desc; | ||
| 403 | |||
| 404 | ar2->intf[1] = usb_ifnum_to_if(udev, 1); | ||
| 405 | r = usb_driver_claim_interface(&ati_remote2_driver, ar2->intf[1], ar2); | ||
| 406 | if (r) | ||
| 407 | goto fail1; | ||
| 408 | alt = ar2->intf[1]->cur_altsetting; | ||
| 409 | ar2->ep[1] = &alt->endpoint[0].desc; | ||
| 410 | |||
| 411 | r = ati_remote2_urb_init(ar2); | ||
| 412 | if (r) | ||
| 413 | goto fail2; | ||
| 414 | |||
| 415 | usb_make_path(udev, ar2->phys, sizeof(ar2->phys)); | ||
| 416 | strlcat(ar2->phys, "/input0", sizeof(ar2->phys)); | ||
| 417 | |||
| 418 | strlcat(ar2->name, "ATI Remote Wonder II", sizeof(ar2->name)); | ||
| 419 | |||
| 420 | r = ati_remote2_input_init(ar2); | ||
| 421 | if (r) | ||
| 422 | goto fail2; | ||
| 423 | |||
| 424 | usb_set_intfdata(interface, ar2); | ||
| 425 | |||
| 426 | return 0; | ||
| 427 | |||
| 428 | fail2: | ||
| 429 | ati_remote2_urb_cleanup(ar2); | ||
| 430 | |||
| 431 | usb_driver_release_interface(&ati_remote2_driver, ar2->intf[1]); | ||
| 432 | fail1: | ||
| 433 | kfree(ar2); | ||
| 434 | |||
| 435 | return r; | ||
| 436 | } | ||
| 437 | |||
| 438 | static void ati_remote2_disconnect(struct usb_interface *interface) | ||
| 439 | { | ||
| 440 | struct ati_remote2 *ar2; | ||
| 441 | struct usb_host_interface *alt = interface->cur_altsetting; | ||
| 442 | |||
| 443 | if (alt->desc.bInterfaceNumber) | ||
| 444 | return; | ||
| 445 | |||
| 446 | ar2 = usb_get_intfdata(interface); | ||
| 447 | usb_set_intfdata(interface, NULL); | ||
| 448 | |||
| 449 | input_unregister_device(ar2->idev); | ||
| 450 | |||
| 451 | ati_remote2_urb_cleanup(ar2); | ||
| 452 | |||
| 453 | usb_driver_release_interface(&ati_remote2_driver, ar2->intf[1]); | ||
| 454 | |||
| 455 | kfree(ar2); | ||
| 456 | } | ||
| 457 | |||
| 458 | static int __init ati_remote2_init(void) | ||
| 459 | { | ||
| 460 | int r; | ||
| 461 | |||
| 462 | r = usb_register(&ati_remote2_driver); | ||
| 463 | if (r) | ||
| 464 | printk(KERN_ERR "ati_remote2: usb_register() = %d\n", r); | ||
| 465 | else | ||
| 466 | printk(KERN_INFO "ati_remote2: " DRIVER_DESC " " DRIVER_VERSION "\n"); | ||
| 467 | |||
| 468 | return r; | ||
| 469 | } | ||
| 470 | |||
| 471 | static void __exit ati_remote2_exit(void) | ||
| 472 | { | ||
| 473 | usb_deregister(&ati_remote2_driver); | ||
| 474 | } | ||
| 475 | |||
| 476 | module_init(ati_remote2_init); | ||
| 477 | module_exit(ati_remote2_exit); | ||
diff --git a/drivers/usb/input/fixp-arith.h b/drivers/usb/input/fixp-arith.h index 26ca5b890a61..b44d398de071 100644 --- a/drivers/usb/input/fixp-arith.h +++ b/drivers/usb/input/fixp-arith.h | |||
| @@ -38,7 +38,7 @@ typedef s16 fixp_t; | |||
| 38 | #define FRAC_MASK ((1<<FRAC_N)-1) | 38 | #define FRAC_MASK ((1<<FRAC_N)-1) |
| 39 | 39 | ||
| 40 | // Not to be used directly. Use fixp_{cos,sin} | 40 | // Not to be used directly. Use fixp_{cos,sin} |
| 41 | static fixp_t cos_table[45] = { | 41 | static const fixp_t cos_table[45] = { |
| 42 | 0x0100, 0x00FF, 0x00FF, 0x00FE, 0x00FD, 0x00FC, 0x00FA, 0x00F8, | 42 | 0x0100, 0x00FF, 0x00FF, 0x00FE, 0x00FD, 0x00FC, 0x00FA, 0x00F8, |
| 43 | 0x00F6, 0x00F3, 0x00F0, 0x00ED, 0x00E9, 0x00E6, 0x00E2, 0x00DD, | 43 | 0x00F6, 0x00F3, 0x00F0, 0x00ED, 0x00E9, 0x00E6, 0x00E2, 0x00DD, |
| 44 | 0x00D9, 0x00D4, 0x00CF, 0x00C9, 0x00C4, 0x00BE, 0x00B8, 0x00B1, | 44 | 0x00D9, 0x00D4, 0x00CF, 0x00C9, 0x00C4, 0x00BE, 0x00B8, 0x00B1, |
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index a3e44ef1df43..5f52979af1c7 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c | |||
| @@ -1454,7 +1454,7 @@ void hid_init_reports(struct hid_device *hid) | |||
| 1454 | * Alphabetically sorted blacklist by quirk type. | 1454 | * Alphabetically sorted blacklist by quirk type. |
| 1455 | */ | 1455 | */ |
| 1456 | 1456 | ||
| 1457 | static struct hid_blacklist { | 1457 | static const struct hid_blacklist { |
| 1458 | __u16 idVendor; | 1458 | __u16 idVendor; |
| 1459 | __u16 idProduct; | 1459 | __u16 idProduct; |
| 1460 | unsigned quirks; | 1460 | unsigned quirks; |
| @@ -1930,7 +1930,6 @@ static struct usb_device_id hid_usb_ids [] = { | |||
| 1930 | MODULE_DEVICE_TABLE (usb, hid_usb_ids); | 1930 | MODULE_DEVICE_TABLE (usb, hid_usb_ids); |
| 1931 | 1931 | ||
| 1932 | static struct usb_driver hid_driver = { | 1932 | static struct usb_driver hid_driver = { |
| 1933 | .owner = THIS_MODULE, | ||
| 1934 | .name = "usbhid", | 1933 | .name = "usbhid", |
| 1935 | .probe = hid_probe, | 1934 | .probe = hid_probe, |
| 1936 | .disconnect = hid_disconnect, | 1935 | .disconnect = hid_disconnect, |
diff --git a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c index 1220a5004a5c..192a03b28971 100644 --- a/drivers/usb/input/hid-input.c +++ b/drivers/usb/input/hid-input.c | |||
| @@ -39,7 +39,7 @@ | |||
| 39 | 39 | ||
| 40 | #define unk KEY_UNKNOWN | 40 | #define unk KEY_UNKNOWN |
| 41 | 41 | ||
| 42 | static unsigned char hid_keyboard[256] = { | 42 | static const unsigned char hid_keyboard[256] = { |
| 43 | 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38, | 43 | 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38, |
| 44 | 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3, | 44 | 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3, |
| 45 | 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26, | 45 | 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26, |
| @@ -58,7 +58,7 @@ static unsigned char hid_keyboard[256] = { | |||
| 58 | 150,158,159,128,136,177,178,176,142,152,173,140,unk,unk,unk,unk | 58 | 150,158,159,128,136,177,178,176,142,152,173,140,unk,unk,unk,unk |
| 59 | }; | 59 | }; |
| 60 | 60 | ||
| 61 | static struct { | 61 | static const struct { |
| 62 | __s32 x; | 62 | __s32 x; |
| 63 | __s32 y; | 63 | __s32 y; |
| 64 | } hid_hat_to_axis[] = {{ 0, 0}, { 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}}; | 64 | } hid_hat_to_axis[] = {{ 0, 0}, { 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}}; |
diff --git a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c index 440377c7a0da..4dff8473553d 100644 --- a/drivers/usb/input/hiddev.c +++ b/drivers/usb/input/hiddev.c | |||
| @@ -826,7 +826,6 @@ static int hiddev_usbd_probe(struct usb_interface *intf, | |||
| 826 | 826 | ||
| 827 | 827 | ||
| 828 | static /* const */ struct usb_driver hiddev_driver = { | 828 | static /* const */ struct usb_driver hiddev_driver = { |
| 829 | .owner = THIS_MODULE, | ||
| 830 | .name = "hiddev", | 829 | .name = "hiddev", |
| 831 | .probe = hiddev_usbd_probe, | 830 | .probe = hiddev_usbd_probe, |
| 832 | }; | 831 | }; |
diff --git a/drivers/usb/input/itmtouch.c b/drivers/usb/input/itmtouch.c index 4a50acb39d29..7618ae5c104f 100644 --- a/drivers/usb/input/itmtouch.c +++ b/drivers/usb/input/itmtouch.c | |||
| @@ -250,7 +250,6 @@ static void itmtouch_disconnect(struct usb_interface *intf) | |||
| 250 | MODULE_DEVICE_TABLE(usb, itmtouch_ids); | 250 | MODULE_DEVICE_TABLE(usb, itmtouch_ids); |
| 251 | 251 | ||
| 252 | static struct usb_driver itmtouch_driver = { | 252 | static struct usb_driver itmtouch_driver = { |
| 253 | .owner = THIS_MODULE, | ||
| 254 | .name = "itmtouch", | 253 | .name = "itmtouch", |
| 255 | .probe = itmtouch_probe, | 254 | .probe = itmtouch_probe, |
| 256 | .disconnect = itmtouch_disconnect, | 255 | .disconnect = itmtouch_disconnect, |
diff --git a/drivers/usb/input/kbtab.c b/drivers/usb/input/kbtab.c index fd48e74e78ed..f6d5cead542b 100644 --- a/drivers/usb/input/kbtab.c +++ b/drivers/usb/input/kbtab.c | |||
| @@ -197,7 +197,6 @@ static void kbtab_disconnect(struct usb_interface *intf) | |||
| 197 | } | 197 | } |
| 198 | 198 | ||
| 199 | static struct usb_driver kbtab_driver = { | 199 | static struct usb_driver kbtab_driver = { |
| 200 | .owner = THIS_MODULE, | ||
| 201 | .name = "kbtab", | 200 | .name = "kbtab", |
| 202 | .probe = kbtab_probe, | 201 | .probe = kbtab_probe, |
| 203 | .disconnect = kbtab_disconnect, | 202 | .disconnect = kbtab_disconnect, |
diff --git a/drivers/usb/input/keyspan_remote.c b/drivers/usb/input/keyspan_remote.c index a32cfe51b77d..b4a051b549d1 100644 --- a/drivers/usb/input/keyspan_remote.c +++ b/drivers/usb/input/keyspan_remote.c | |||
| @@ -95,7 +95,7 @@ struct usb_keyspan { | |||
| 95 | * Currently there are 15 and 17 button models so RESERVED codes | 95 | * Currently there are 15 and 17 button models so RESERVED codes |
| 96 | * are blank areas in the mapping. | 96 | * are blank areas in the mapping. |
| 97 | */ | 97 | */ |
| 98 | static int keyspan_key_table[] = { | 98 | static const int keyspan_key_table[] = { |
| 99 | KEY_RESERVED, /* 0 is just a place holder. */ | 99 | KEY_RESERVED, /* 0 is just a place holder. */ |
| 100 | KEY_RESERVED, | 100 | KEY_RESERVED, |
| 101 | KEY_STOP, | 101 | KEY_STOP, |
| @@ -559,7 +559,6 @@ static void keyspan_disconnect(struct usb_interface *interface) | |||
| 559 | */ | 559 | */ |
| 560 | static struct usb_driver keyspan_driver = | 560 | static struct usb_driver keyspan_driver = |
| 561 | { | 561 | { |
| 562 | .owner = THIS_MODULE, | ||
| 563 | .name = "keyspan_remote", | 562 | .name = "keyspan_remote", |
| 564 | .probe = keyspan_probe, | 563 | .probe = keyspan_probe, |
| 565 | .disconnect = keyspan_disconnect, | 564 | .disconnect = keyspan_disconnect, |
diff --git a/drivers/usb/input/mtouchusb.c b/drivers/usb/input/mtouchusb.c index 52cc18cd247d..f018953a5485 100644 --- a/drivers/usb/input/mtouchusb.c +++ b/drivers/usb/input/mtouchusb.c | |||
| @@ -310,7 +310,6 @@ static void mtouchusb_disconnect(struct usb_interface *intf) | |||
| 310 | MODULE_DEVICE_TABLE(usb, mtouchusb_devices); | 310 | MODULE_DEVICE_TABLE(usb, mtouchusb_devices); |
| 311 | 311 | ||
| 312 | static struct usb_driver mtouchusb_driver = { | 312 | static struct usb_driver mtouchusb_driver = { |
| 313 | .owner = THIS_MODULE, | ||
| 314 | .name = "mtouchusb", | 313 | .name = "mtouchusb", |
| 315 | .probe = mtouchusb_probe, | 314 | .probe = mtouchusb_probe, |
| 316 | .disconnect = mtouchusb_disconnect, | 315 | .disconnect = mtouchusb_disconnect, |
diff --git a/drivers/usb/input/powermate.c b/drivers/usb/input/powermate.c index b7476233ef5d..fdf0f788062c 100644 --- a/drivers/usb/input/powermate.c +++ b/drivers/usb/input/powermate.c | |||
| @@ -441,7 +441,6 @@ static struct usb_device_id powermate_devices [] = { | |||
| 441 | MODULE_DEVICE_TABLE (usb, powermate_devices); | 441 | MODULE_DEVICE_TABLE (usb, powermate_devices); |
| 442 | 442 | ||
| 443 | static struct usb_driver powermate_driver = { | 443 | static struct usb_driver powermate_driver = { |
| 444 | .owner = THIS_MODULE, | ||
| 445 | .name = "powermate", | 444 | .name = "powermate", |
| 446 | .probe = powermate_probe, | 445 | .probe = powermate_probe, |
| 447 | .disconnect = powermate_disconnect, | 446 | .disconnect = powermate_disconnect, |
diff --git a/drivers/usb/input/touchkitusb.c b/drivers/usb/input/touchkitusb.c index 7420c6b84284..3b3c7b4120a2 100644 --- a/drivers/usb/input/touchkitusb.c +++ b/drivers/usb/input/touchkitusb.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /****************************************************************************** | 1 | /****************************************************************************** |
| 2 | * touchkitusb.c -- Driver for eGalax TouchKit USB Touchscreens | 2 | * touchkitusb.c -- Driver for eGalax TouchKit USB Touchscreens |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2004 by Daniel Ritz | 4 | * Copyright (C) 2004-2005 by Daniel Ritz <daniel.ritz@gmx.ch> |
| 5 | * Copyright (C) by Todd E. Johnson (mtouchusb.c) | 5 | * Copyright (C) by Todd E. Johnson (mtouchusb.c) |
| 6 | * | 6 | * |
| 7 | * This program is free software; you can redistribute it and/or | 7 | * This program is free software; you can redistribute it and/or |
| @@ -41,15 +41,13 @@ | |||
| 41 | #define TOUCHKIT_MAX_YC 0x07ff | 41 | #define TOUCHKIT_MAX_YC 0x07ff |
| 42 | #define TOUCHKIT_YC_FUZZ 0x0 | 42 | #define TOUCHKIT_YC_FUZZ 0x0 |
| 43 | #define TOUCHKIT_YC_FLAT 0x0 | 43 | #define TOUCHKIT_YC_FLAT 0x0 |
| 44 | #define TOUCHKIT_REPORT_DATA_SIZE 8 | 44 | #define TOUCHKIT_REPORT_DATA_SIZE 16 |
| 45 | 45 | ||
| 46 | #define TOUCHKIT_DOWN 0x01 | 46 | #define TOUCHKIT_DOWN 0x01 |
| 47 | #define TOUCHKIT_POINT_TOUCH 0x81 | ||
| 48 | #define TOUCHKIT_POINT_NOTOUCH 0x80 | ||
| 49 | 47 | ||
| 50 | #define TOUCHKIT_GET_TOUCHED(dat) ((((dat)[0]) & TOUCHKIT_DOWN) ? 1 : 0) | 48 | #define TOUCHKIT_PKT_TYPE_MASK 0xFE |
| 51 | #define TOUCHKIT_GET_X(dat) (((dat)[3] << 7) | (dat)[4]) | 49 | #define TOUCHKIT_PKT_TYPE_REPT 0x80 |
| 52 | #define TOUCHKIT_GET_Y(dat) (((dat)[1] << 7) | (dat)[2]) | 50 | #define TOUCHKIT_PKT_TYPE_DIAG 0x0A |
| 53 | 51 | ||
| 54 | #define DRIVER_VERSION "v0.1" | 52 | #define DRIVER_VERSION "v0.1" |
| 55 | #define DRIVER_AUTHOR "Daniel Ritz <daniel.ritz@gmx.ch>" | 53 | #define DRIVER_AUTHOR "Daniel Ritz <daniel.ritz@gmx.ch>" |
| @@ -62,6 +60,8 @@ MODULE_PARM_DESC(swap_xy, "If set X and Y axes are swapped."); | |||
| 62 | struct touchkit_usb { | 60 | struct touchkit_usb { |
| 63 | unsigned char *data; | 61 | unsigned char *data; |
| 64 | dma_addr_t data_dma; | 62 | dma_addr_t data_dma; |
| 63 | char buffer[TOUCHKIT_REPORT_DATA_SIZE]; | ||
| 64 | int buf_len; | ||
| 65 | struct urb *irq; | 65 | struct urb *irq; |
| 66 | struct usb_device *udev; | 66 | struct usb_device *udev; |
| 67 | struct input_dev *input; | 67 | struct input_dev *input; |
| @@ -77,11 +77,128 @@ static struct usb_device_id touchkit_devices[] = { | |||
| 77 | {} | 77 | {} |
| 78 | }; | 78 | }; |
| 79 | 79 | ||
| 80 | /* helpers to read the data */ | ||
| 81 | static inline int touchkit_get_touched(char *data) | ||
| 82 | { | ||
| 83 | return (data[0] & TOUCHKIT_DOWN) ? 1 : 0; | ||
| 84 | } | ||
| 85 | |||
| 86 | static inline int touchkit_get_x(char *data) | ||
| 87 | { | ||
| 88 | return ((data[3] & 0x0F) << 7) | (data[4] & 0x7F); | ||
| 89 | } | ||
| 90 | |||
| 91 | static inline int touchkit_get_y(char *data) | ||
| 92 | { | ||
| 93 | return ((data[1] & 0x0F) << 7) | (data[2] & 0x7F); | ||
| 94 | } | ||
| 95 | |||
| 96 | |||
| 97 | /* processes one input packet. */ | ||
| 98 | static void touchkit_process_pkt(struct touchkit_usb *touchkit, | ||
| 99 | struct pt_regs *regs, char *pkt) | ||
| 100 | { | ||
| 101 | int x, y; | ||
| 102 | |||
| 103 | /* only process report packets */ | ||
| 104 | if ((pkt[0] & TOUCHKIT_PKT_TYPE_MASK) != TOUCHKIT_PKT_TYPE_REPT) | ||
| 105 | return; | ||
| 106 | |||
| 107 | if (swap_xy) { | ||
| 108 | y = touchkit_get_x(pkt); | ||
| 109 | x = touchkit_get_y(pkt); | ||
| 110 | } else { | ||
| 111 | x = touchkit_get_x(pkt); | ||
| 112 | y = touchkit_get_y(pkt); | ||
| 113 | } | ||
| 114 | |||
| 115 | input_regs(touchkit->input, regs); | ||
| 116 | input_report_key(touchkit->input, BTN_TOUCH, touchkit_get_touched(pkt)); | ||
| 117 | input_report_abs(touchkit->input, ABS_X, x); | ||
| 118 | input_report_abs(touchkit->input, ABS_Y, y); | ||
| 119 | input_sync(touchkit->input); | ||
| 120 | } | ||
| 121 | |||
| 122 | |||
| 123 | static int touchkit_get_pkt_len(char *buf) | ||
| 124 | { | ||
| 125 | switch (buf[0] & TOUCHKIT_PKT_TYPE_MASK) { | ||
| 126 | case TOUCHKIT_PKT_TYPE_REPT: | ||
| 127 | return 5; | ||
| 128 | |||
| 129 | case TOUCHKIT_PKT_TYPE_DIAG: | ||
| 130 | return buf[1] + 2; | ||
| 131 | } | ||
| 132 | |||
| 133 | return 0; | ||
| 134 | } | ||
| 135 | |||
| 136 | static void touchkit_process(struct touchkit_usb *touchkit, int len, | ||
| 137 | struct pt_regs *regs) | ||
| 138 | { | ||
| 139 | char *buffer; | ||
| 140 | int pkt_len, buf_len, pos; | ||
| 141 | |||
| 142 | /* if the buffer contains data, append */ | ||
| 143 | if (unlikely(touchkit->buf_len)) { | ||
| 144 | int tmp; | ||
| 145 | |||
| 146 | /* if only 1 byte in buffer, add another one to get length */ | ||
| 147 | if (touchkit->buf_len == 1) | ||
| 148 | touchkit->buffer[1] = touchkit->data[0]; | ||
| 149 | |||
| 150 | pkt_len = touchkit_get_pkt_len(touchkit->buffer); | ||
| 151 | |||
| 152 | /* unknown packet: drop everything */ | ||
| 153 | if (!pkt_len) | ||
| 154 | return; | ||
| 155 | |||
| 156 | /* append, process */ | ||
| 157 | tmp = pkt_len - touchkit->buf_len; | ||
| 158 | memcpy(touchkit->buffer + touchkit->buf_len, touchkit->data, tmp); | ||
| 159 | touchkit_process_pkt(touchkit, regs, touchkit->buffer); | ||
| 160 | |||
| 161 | buffer = touchkit->data + tmp; | ||
| 162 | buf_len = len - tmp; | ||
| 163 | } else { | ||
| 164 | buffer = touchkit->data; | ||
| 165 | buf_len = len; | ||
| 166 | } | ||
| 167 | |||
| 168 | /* only one byte left in buffer */ | ||
| 169 | if (unlikely(buf_len == 1)) { | ||
| 170 | touchkit->buffer[0] = buffer[0]; | ||
| 171 | touchkit->buf_len = 1; | ||
| 172 | return; | ||
| 173 | } | ||
| 174 | |||
| 175 | /* loop over the buffer */ | ||
| 176 | pos = 0; | ||
| 177 | while (pos < buf_len) { | ||
| 178 | /* get packet len */ | ||
| 179 | pkt_len = touchkit_get_pkt_len(buffer + pos); | ||
| 180 | |||
| 181 | /* unknown packet: drop everything */ | ||
| 182 | if (unlikely(!pkt_len)) | ||
| 183 | return; | ||
| 184 | |||
| 185 | /* full packet: process */ | ||
| 186 | if (likely(pkt_len <= buf_len)) { | ||
| 187 | touchkit_process_pkt(touchkit, regs, buffer + pos); | ||
| 188 | } else { | ||
| 189 | /* incomplete packet: save in buffer */ | ||
| 190 | memcpy(touchkit->buffer, buffer + pos, buf_len - pos); | ||
| 191 | touchkit->buf_len = buf_len - pos; | ||
| 192 | } | ||
| 193 | pos += pkt_len; | ||
| 194 | } | ||
| 195 | } | ||
| 196 | |||
| 197 | |||
| 80 | static void touchkit_irq(struct urb *urb, struct pt_regs *regs) | 198 | static void touchkit_irq(struct urb *urb, struct pt_regs *regs) |
| 81 | { | 199 | { |
| 82 | struct touchkit_usb *touchkit = urb->context; | 200 | struct touchkit_usb *touchkit = urb->context; |
| 83 | int retval; | 201 | int retval; |
| 84 | int x, y; | ||
| 85 | 202 | ||
| 86 | switch (urb->status) { | 203 | switch (urb->status) { |
| 87 | case 0: | 204 | case 0: |
| @@ -105,20 +222,7 @@ static void touchkit_irq(struct urb *urb, struct pt_regs *regs) | |||
| 105 | goto exit; | 222 | goto exit; |
| 106 | } | 223 | } |
| 107 | 224 | ||
| 108 | if (swap_xy) { | 225 | touchkit_process(touchkit, urb->actual_length, regs); |
| 109 | y = TOUCHKIT_GET_X(touchkit->data); | ||
| 110 | x = TOUCHKIT_GET_Y(touchkit->data); | ||
| 111 | } else { | ||
| 112 | x = TOUCHKIT_GET_X(touchkit->data); | ||
| 113 | y = TOUCHKIT_GET_Y(touchkit->data); | ||
| 114 | } | ||
| 115 | |||
| 116 | input_regs(touchkit->input, regs); | ||
| 117 | input_report_key(touchkit->input, BTN_TOUCH, | ||
| 118 | TOUCHKIT_GET_TOUCHED(touchkit->data)); | ||
| 119 | input_report_abs(touchkit->input, ABS_X, x); | ||
| 120 | input_report_abs(touchkit->input, ABS_Y, y); | ||
| 121 | input_sync(touchkit->input); | ||
| 122 | 226 | ||
| 123 | exit: | 227 | exit: |
| 124 | retval = usb_submit_urb(urb, GFP_ATOMIC); | 228 | retval = usb_submit_urb(urb, GFP_ATOMIC); |
| @@ -267,7 +371,6 @@ static void touchkit_disconnect(struct usb_interface *intf) | |||
| 267 | MODULE_DEVICE_TABLE(usb, touchkit_devices); | 371 | MODULE_DEVICE_TABLE(usb, touchkit_devices); |
| 268 | 372 | ||
| 269 | static struct usb_driver touchkit_driver = { | 373 | static struct usb_driver touchkit_driver = { |
| 270 | .owner = THIS_MODULE, | ||
| 271 | .name = "touchkitusb", | 374 | .name = "touchkitusb", |
| 272 | .probe = touchkit_probe, | 375 | .probe = touchkit_probe, |
| 273 | .disconnect = touchkit_disconnect, | 376 | .disconnect = touchkit_disconnect, |
diff --git a/drivers/usb/input/usbkbd.c b/drivers/usb/input/usbkbd.c index 226b6f90a907..2f3edc26cb50 100644 --- a/drivers/usb/input/usbkbd.c +++ b/drivers/usb/input/usbkbd.c | |||
| @@ -345,7 +345,6 @@ static struct usb_device_id usb_kbd_id_table [] = { | |||
| 345 | MODULE_DEVICE_TABLE (usb, usb_kbd_id_table); | 345 | MODULE_DEVICE_TABLE (usb, usb_kbd_id_table); |
| 346 | 346 | ||
| 347 | static struct usb_driver usb_kbd_driver = { | 347 | static struct usb_driver usb_kbd_driver = { |
| 348 | .owner = THIS_MODULE, | ||
| 349 | .name = "usbkbd", | 348 | .name = "usbkbd", |
| 350 | .probe = usb_kbd_probe, | 349 | .probe = usb_kbd_probe, |
| 351 | .disconnect = usb_kbd_disconnect, | 350 | .disconnect = usb_kbd_disconnect, |
diff --git a/drivers/usb/input/usbmouse.c b/drivers/usb/input/usbmouse.c index 230f6b1b314a..af526135d210 100644 --- a/drivers/usb/input/usbmouse.c +++ b/drivers/usb/input/usbmouse.c | |||
| @@ -226,7 +226,6 @@ static struct usb_device_id usb_mouse_id_table [] = { | |||
| 226 | MODULE_DEVICE_TABLE (usb, usb_mouse_id_table); | 226 | MODULE_DEVICE_TABLE (usb, usb_mouse_id_table); |
| 227 | 227 | ||
| 228 | static struct usb_driver usb_mouse_driver = { | 228 | static struct usb_driver usb_mouse_driver = { |
| 229 | .owner = THIS_MODULE, | ||
| 230 | .name = "usbmouse", | 229 | .name = "usbmouse", |
| 231 | .probe = usb_mouse_probe, | 230 | .probe = usb_mouse_probe, |
| 232 | .disconnect = usb_mouse_disconnect, | 231 | .disconnect = usb_mouse_disconnect, |
diff --git a/drivers/usb/input/wacom.c b/drivers/usb/input/wacom.c index dc099bbe12bf..48df4cfd5a42 100644 --- a/drivers/usb/input/wacom.c +++ b/drivers/usb/input/wacom.c | |||
| @@ -945,7 +945,6 @@ static void wacom_disconnect(struct usb_interface *intf) | |||
| 945 | } | 945 | } |
| 946 | 946 | ||
| 947 | static struct usb_driver wacom_driver = { | 947 | static struct usb_driver wacom_driver = { |
| 948 | .owner = THIS_MODULE, | ||
| 949 | .name = "wacom", | 948 | .name = "wacom", |
| 950 | .probe = wacom_probe, | 949 | .probe = wacom_probe, |
| 951 | .disconnect = wacom_disconnect, | 950 | .disconnect = wacom_disconnect, |
diff --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c index 43112f040b6d..e278489a80c6 100644 --- a/drivers/usb/input/xpad.c +++ b/drivers/usb/input/xpad.c | |||
| @@ -70,7 +70,7 @@ | |||
| 70 | 70 | ||
| 71 | #define XPAD_PKT_LEN 32 | 71 | #define XPAD_PKT_LEN 32 |
| 72 | 72 | ||
| 73 | static struct xpad_device { | 73 | static const struct xpad_device { |
| 74 | u16 idVendor; | 74 | u16 idVendor; |
| 75 | u16 idProduct; | 75 | u16 idProduct; |
| 76 | char *name; | 76 | char *name; |
| @@ -81,13 +81,13 @@ static struct xpad_device { | |||
| 81 | { 0x0000, 0x0000, "X-Box pad" } | 81 | { 0x0000, 0x0000, "X-Box pad" } |
| 82 | }; | 82 | }; |
| 83 | 83 | ||
| 84 | static signed short xpad_btn[] = { | 84 | static const signed short xpad_btn[] = { |
| 85 | BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, /* "analog" buttons */ | 85 | BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, /* "analog" buttons */ |
| 86 | BTN_START, BTN_BACK, BTN_THUMBL, BTN_THUMBR, /* start/back/sticks */ | 86 | BTN_START, BTN_BACK, BTN_THUMBL, BTN_THUMBR, /* start/back/sticks */ |
| 87 | -1 /* terminating entry */ | 87 | -1 /* terminating entry */ |
| 88 | }; | 88 | }; |
| 89 | 89 | ||
| 90 | static signed short xpad_abs[] = { | 90 | static const signed short xpad_abs[] = { |
| 91 | ABS_X, ABS_Y, /* left stick */ | 91 | ABS_X, ABS_Y, /* left stick */ |
| 92 | ABS_RX, ABS_RY, /* right stick */ | 92 | ABS_RX, ABS_RY, /* right stick */ |
| 93 | ABS_Z, ABS_RZ, /* triggers left/right */ | 93 | ABS_Z, ABS_RZ, /* triggers left/right */ |
| @@ -316,7 +316,6 @@ static void xpad_disconnect(struct usb_interface *intf) | |||
| 316 | } | 316 | } |
| 317 | 317 | ||
| 318 | static struct usb_driver xpad_driver = { | 318 | static struct usb_driver xpad_driver = { |
| 319 | .owner = THIS_MODULE, | ||
| 320 | .name = "xpad", | 319 | .name = "xpad", |
| 321 | .probe = xpad_probe, | 320 | .probe = xpad_probe, |
| 322 | .disconnect = xpad_disconnect, | 321 | .disconnect = xpad_disconnect, |
diff --git a/drivers/usb/input/yealink.c b/drivers/usb/input/yealink.c index f526aebea502..1bfc105ad4d6 100644 --- a/drivers/usb/input/yealink.c +++ b/drivers/usb/input/yealink.c | |||
| @@ -987,7 +987,6 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
| 987 | } | 987 | } |
| 988 | 988 | ||
| 989 | static struct usb_driver yealink_driver = { | 989 | static struct usb_driver yealink_driver = { |
| 990 | .owner = THIS_MODULE, | ||
| 991 | .name = "yealink", | 990 | .name = "yealink", |
| 992 | .probe = usb_probe, | 991 | .probe = usb_probe, |
| 993 | .disconnect = usb_disconnect, | 992 | .disconnect = usb_disconnect, |
diff --git a/drivers/usb/media/dabusb.c b/drivers/usb/media/dabusb.c index 27b23c55bbc7..18d8eaf408d5 100644 --- a/drivers/usb/media/dabusb.c +++ b/drivers/usb/media/dabusb.c | |||
| @@ -812,7 +812,6 @@ static struct usb_device_id dabusb_ids [] = { | |||
| 812 | MODULE_DEVICE_TABLE (usb, dabusb_ids); | 812 | MODULE_DEVICE_TABLE (usb, dabusb_ids); |
| 813 | 813 | ||
| 814 | static struct usb_driver dabusb_driver = { | 814 | static struct usb_driver dabusb_driver = { |
| 815 | .owner = THIS_MODULE, | ||
| 816 | .name = "dabusb", | 815 | .name = "dabusb", |
| 817 | .probe = dabusb_probe, | 816 | .probe = dabusb_probe, |
| 818 | .disconnect = dabusb_disconnect, | 817 | .disconnect = dabusb_disconnect, |
diff --git a/drivers/usb/media/dsbr100.c b/drivers/usb/media/dsbr100.c index 7503f5b96f59..6a5700e9d428 100644 --- a/drivers/usb/media/dsbr100.c +++ b/drivers/usb/media/dsbr100.c | |||
| @@ -150,7 +150,6 @@ MODULE_DEVICE_TABLE (usb, usb_dsbr100_device_table); | |||
| 150 | 150 | ||
| 151 | /* USB subsystem interface */ | 151 | /* USB subsystem interface */ |
| 152 | static struct usb_driver usb_dsbr100_driver = { | 152 | static struct usb_driver usb_dsbr100_driver = { |
| 153 | .owner = THIS_MODULE, | ||
| 154 | .name = "dsbr100", | 153 | .name = "dsbr100", |
| 155 | .probe = usb_dsbr100_probe, | 154 | .probe = usb_dsbr100_probe, |
| 156 | .disconnect = usb_dsbr100_disconnect, | 155 | .disconnect = usb_dsbr100_disconnect, |
diff --git a/drivers/usb/media/ibmcam.c b/drivers/usb/media/ibmcam.c index ba41fc7b95c2..a42c22294124 100644 --- a/drivers/usb/media/ibmcam.c +++ b/drivers/usb/media/ibmcam.c | |||
| @@ -3457,7 +3457,7 @@ static void ibmcam_model3_setup_after_video_if(struct uvd *uvd) | |||
| 3457 | if(init_model3_input) { | 3457 | if(init_model3_input) { |
| 3458 | if (debug > 0) | 3458 | if (debug > 0) |
| 3459 | info("Setting input to RCA."); | 3459 | info("Setting input to RCA."); |
| 3460 | for (i=0; i < (sizeof(initData)/sizeof(initData[0])); i++) { | 3460 | for (i=0; i < ARRAY_SIZE(initData); i++) { |
| 3461 | ibmcam_veio(uvd, initData[i].req, initData[i].value, initData[i].index); | 3461 | ibmcam_veio(uvd, initData[i].req, initData[i].value, initData[i].index); |
| 3462 | } | 3462 | } |
| 3463 | } | 3463 | } |
diff --git a/drivers/usb/media/konicawc.c b/drivers/usb/media/konicawc.c index 9fe2c2710d13..e2ede583518f 100644 --- a/drivers/usb/media/konicawc.c +++ b/drivers/usb/media/konicawc.c | |||
| @@ -77,14 +77,14 @@ static int saturation = MAX_SATURATION/2; | |||
| 77 | static int sharpness = MAX_SHARPNESS/2; | 77 | static int sharpness = MAX_SHARPNESS/2; |
| 78 | static int whitebal = 3*(MAX_WHITEBAL/4); | 78 | static int whitebal = 3*(MAX_WHITEBAL/4); |
| 79 | 79 | ||
| 80 | static int spd_to_iface[] = { 1, 0, 3, 2, 4, 5, 6 }; | 80 | static const int spd_to_iface[] = { 1, 0, 3, 2, 4, 5, 6 }; |
| 81 | 81 | ||
| 82 | /* These FPS speeds are from the windows config box. They are | 82 | /* These FPS speeds are from the windows config box. They are |
| 83 | * indexed on size (0-2) and speed (0-6). Divide by 3 to get the | 83 | * indexed on size (0-2) and speed (0-6). Divide by 3 to get the |
| 84 | * real fps. | 84 | * real fps. |
| 85 | */ | 85 | */ |
| 86 | 86 | ||
| 87 | static int spd_to_fps[][7] = { { 24, 40, 48, 60, 72, 80, 100 }, | 87 | static const int spd_to_fps[][7] = { { 24, 40, 48, 60, 72, 80, 100 }, |
| 88 | { 24, 40, 48, 60, 72, 80, 100 }, | 88 | { 24, 40, 48, 60, 72, 80, 100 }, |
| 89 | { 18, 30, 36, 45, 54, 60, 75 }, | 89 | { 18, 30, 36, 45, 54, 60, 75 }, |
| 90 | { 6, 10, 12, 15, 18, 21, 25 } }; | 90 | { 6, 10, 12, 15, 18, 21, 25 } }; |
| @@ -95,7 +95,7 @@ struct cam_size { | |||
| 95 | u8 cmd; | 95 | u8 cmd; |
| 96 | }; | 96 | }; |
| 97 | 97 | ||
| 98 | static struct cam_size camera_sizes[] = { { 160, 120, 0x7 }, | 98 | static const struct cam_size camera_sizes[] = { { 160, 120, 0x7 }, |
| 99 | { 160, 136, 0xa }, | 99 | { 160, 136, 0xa }, |
| 100 | { 176, 144, 0x4 }, | 100 | { 176, 144, 0x4 }, |
| 101 | { 320, 240, 0x5 } }; | 101 | { 320, 240, 0x5 } }; |
diff --git a/drivers/usb/media/ov511.c b/drivers/usb/media/ov511.c index 036c485d1d1e..3a0e8ce67ebe 100644 --- a/drivers/usb/media/ov511.c +++ b/drivers/usb/media/ov511.c | |||
| @@ -211,7 +211,7 @@ static struct ov51x_decomp_ops *ov518_mmx_decomp_ops; | |||
| 211 | 211 | ||
| 212 | /* Number of times to retry a failed I2C transaction. Increase this if you | 212 | /* Number of times to retry a failed I2C transaction. Increase this if you |
| 213 | * are getting "Failed to read sensor ID..." */ | 213 | * are getting "Failed to read sensor ID..." */ |
| 214 | static int i2c_detect_tries = 5; | 214 | static const int i2c_detect_tries = 5; |
| 215 | 215 | ||
| 216 | /* MMX support is present in kernel and CPU. Checked upon decomp module load. */ | 216 | /* MMX support is present in kernel and CPU. Checked upon decomp module load. */ |
| 217 | #if defined(__i386__) || defined(__x86_64__) | 217 | #if defined(__i386__) || defined(__x86_64__) |
| @@ -6008,7 +6008,6 @@ ov51x_disconnect(struct usb_interface *intf) | |||
| 6008 | } | 6008 | } |
| 6009 | 6009 | ||
| 6010 | static struct usb_driver ov511_driver = { | 6010 | static struct usb_driver ov511_driver = { |
| 6011 | .owner = THIS_MODULE, | ||
| 6012 | .name = "ov511", | 6011 | .name = "ov511", |
| 6013 | .id_table = device_table, | 6012 | .id_table = device_table, |
| 6014 | .probe = ov51x_probe, | 6013 | .probe = ov51x_probe, |
diff --git a/drivers/usb/media/pwc/pwc-ctrl.c b/drivers/usb/media/pwc/pwc-ctrl.c index 53099190952c..359c4b2df735 100644 --- a/drivers/usb/media/pwc/pwc-ctrl.c +++ b/drivers/usb/media/pwc/pwc-ctrl.c | |||
| @@ -109,7 +109,7 @@ | |||
| 109 | #define PT_RESET_CONTROL_FORMATTER 0x02 | 109 | #define PT_RESET_CONTROL_FORMATTER 0x02 |
| 110 | #define PT_STATUS_FORMATTER 0x03 | 110 | #define PT_STATUS_FORMATTER 0x03 |
| 111 | 111 | ||
| 112 | static char *size2name[PSZ_MAX] = | 112 | static const char *size2name[PSZ_MAX] = |
| 113 | { | 113 | { |
| 114 | "subQCIF", | 114 | "subQCIF", |
| 115 | "QSIF", | 115 | "QSIF", |
diff --git a/drivers/usb/media/pwc/pwc-if.c b/drivers/usb/media/pwc/pwc-if.c index 5524fd70210b..09ca6128ac20 100644 --- a/drivers/usb/media/pwc/pwc-if.c +++ b/drivers/usb/media/pwc/pwc-if.c | |||
| @@ -111,7 +111,6 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
| 111 | static void usb_pwc_disconnect(struct usb_interface *intf); | 111 | static void usb_pwc_disconnect(struct usb_interface *intf); |
| 112 | 112 | ||
| 113 | static struct usb_driver pwc_driver = { | 113 | static struct usb_driver pwc_driver = { |
| 114 | .owner = THIS_MODULE, | ||
| 115 | .name = "Philips webcam", /* name */ | 114 | .name = "Philips webcam", /* name */ |
| 116 | .id_table = pwc_device_table, | 115 | .id_table = pwc_device_table, |
| 117 | .probe = usb_pwc_probe, /* probe() */ | 116 | .probe = usb_pwc_probe, /* probe() */ |
diff --git a/drivers/usb/media/se401.c b/drivers/usb/media/se401.c index f69e443cd1bc..b2ae29af5940 100644 --- a/drivers/usb/media/se401.c +++ b/drivers/usb/media/se401.c | |||
| @@ -1401,7 +1401,6 @@ static void se401_disconnect(struct usb_interface *intf) | |||
| 1401 | } | 1401 | } |
| 1402 | 1402 | ||
| 1403 | static struct usb_driver se401_driver = { | 1403 | static struct usb_driver se401_driver = { |
| 1404 | .owner = THIS_MODULE, | ||
| 1405 | .name = "se401", | 1404 | .name = "se401", |
| 1406 | .id_table = device_table, | 1405 | .id_table = device_table, |
| 1407 | .probe = se401_probe, | 1406 | .probe = se401_probe, |
diff --git a/drivers/usb/media/sn9c102_core.c b/drivers/usb/media/sn9c102_core.c index b2e66e3b90aa..8d1a1c357d5a 100644 --- a/drivers/usb/media/sn9c102_core.c +++ b/drivers/usb/media/sn9c102_core.c | |||
| @@ -1316,7 +1316,7 @@ static int sn9c102_init(struct sn9c102_device* cam) | |||
| 1316 | struct v4l2_control ctrl; | 1316 | struct v4l2_control ctrl; |
| 1317 | struct v4l2_queryctrl *qctrl; | 1317 | struct v4l2_queryctrl *qctrl; |
| 1318 | struct v4l2_rect* rect; | 1318 | struct v4l2_rect* rect; |
| 1319 | u8 i = 0, n = 0; | 1319 | u8 i = 0; |
| 1320 | int err = 0; | 1320 | int err = 0; |
| 1321 | 1321 | ||
| 1322 | if (!(cam->state & DEV_INITIALIZED)) { | 1322 | if (!(cam->state & DEV_INITIALIZED)) { |
| @@ -1352,7 +1352,7 @@ static int sn9c102_init(struct sn9c102_device* cam) | |||
| 1352 | return err; | 1352 | return err; |
| 1353 | 1353 | ||
| 1354 | if (s->pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X) | 1354 | if (s->pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X) |
| 1355 | DBG(3, "Compressed video format is active, quality %d", | 1355 | DBG(3, "Compressed video format is active, quality %d", |
| 1356 | cam->compression.quality) | 1356 | cam->compression.quality) |
| 1357 | else | 1357 | else |
| 1358 | DBG(3, "Uncompressed video format is active") | 1358 | DBG(3, "Uncompressed video format is active") |
| @@ -1364,9 +1364,8 @@ static int sn9c102_init(struct sn9c102_device* cam) | |||
| 1364 | } | 1364 | } |
| 1365 | 1365 | ||
| 1366 | if (s->set_ctrl) { | 1366 | if (s->set_ctrl) { |
| 1367 | n = sizeof(s->qctrl) / sizeof(s->qctrl[0]); | 1367 | for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) |
| 1368 | for (i = 0; i < n; i++) | 1368 | if (s->qctrl[i].id != 0 && |
| 1369 | if (s->qctrl[i].id != 0 && | ||
| 1370 | !(s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED)) { | 1369 | !(s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED)) { |
| 1371 | ctrl.id = s->qctrl[i].id; | 1370 | ctrl.id = s->qctrl[i].id; |
| 1372 | ctrl.value = qctrl[i].default_value; | 1371 | ctrl.value = qctrl[i].default_value; |
| @@ -1388,7 +1387,7 @@ static int sn9c102_init(struct sn9c102_device* cam) | |||
| 1388 | init_waitqueue_head(&cam->wait_stream); | 1387 | init_waitqueue_head(&cam->wait_stream); |
| 1389 | cam->nreadbuffers = 2; | 1388 | cam->nreadbuffers = 2; |
| 1390 | memcpy(s->_qctrl, s->qctrl, sizeof(s->qctrl)); | 1389 | memcpy(s->_qctrl, s->qctrl, sizeof(s->qctrl)); |
| 1391 | memcpy(&(s->_rect), &(s->cropcap.defrect), | 1390 | memcpy(&(s->_rect), &(s->cropcap.defrect), |
| 1392 | sizeof(struct v4l2_rect)); | 1391 | sizeof(struct v4l2_rect)); |
| 1393 | cam->state |= DEV_INITIALIZED; | 1392 | cam->state |= DEV_INITIALIZED; |
| 1394 | } | 1393 | } |
| @@ -1810,13 +1809,12 @@ static int sn9c102_ioctl_v4l2(struct inode* inode, struct file* filp, | |||
| 1810 | { | 1809 | { |
| 1811 | struct sn9c102_sensor* s = cam->sensor; | 1810 | struct sn9c102_sensor* s = cam->sensor; |
| 1812 | struct v4l2_queryctrl qc; | 1811 | struct v4l2_queryctrl qc; |
| 1813 | u8 i, n; | 1812 | u8 i; |
| 1814 | 1813 | ||
| 1815 | if (copy_from_user(&qc, arg, sizeof(qc))) | 1814 | if (copy_from_user(&qc, arg, sizeof(qc))) |
| 1816 | return -EFAULT; | 1815 | return -EFAULT; |
| 1817 | 1816 | ||
| 1818 | n = sizeof(s->qctrl) / sizeof(s->qctrl[0]); | 1817 | for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) |
| 1819 | for (i = 0; i < n; i++) | ||
| 1820 | if (qc.id && qc.id == s->qctrl[i].id) { | 1818 | if (qc.id && qc.id == s->qctrl[i].id) { |
| 1821 | memcpy(&qc, &(s->qctrl[i]), sizeof(qc)); | 1819 | memcpy(&qc, &(s->qctrl[i]), sizeof(qc)); |
| 1822 | if (copy_to_user(arg, &qc, sizeof(qc))) | 1820 | if (copy_to_user(arg, &qc, sizeof(qc))) |
| @@ -1852,7 +1850,7 @@ static int sn9c102_ioctl_v4l2(struct inode* inode, struct file* filp, | |||
| 1852 | { | 1850 | { |
| 1853 | struct sn9c102_sensor* s = cam->sensor; | 1851 | struct sn9c102_sensor* s = cam->sensor; |
| 1854 | struct v4l2_control ctrl; | 1852 | struct v4l2_control ctrl; |
| 1855 | u8 i, n; | 1853 | u8 i; |
| 1856 | int err = 0; | 1854 | int err = 0; |
| 1857 | 1855 | ||
| 1858 | if (!s->set_ctrl) | 1856 | if (!s->set_ctrl) |
| @@ -1861,8 +1859,7 @@ static int sn9c102_ioctl_v4l2(struct inode* inode, struct file* filp, | |||
| 1861 | if (copy_from_user(&ctrl, arg, sizeof(ctrl))) | 1859 | if (copy_from_user(&ctrl, arg, sizeof(ctrl))) |
| 1862 | return -EFAULT; | 1860 | return -EFAULT; |
| 1863 | 1861 | ||
| 1864 | n = sizeof(s->qctrl) / sizeof(s->qctrl[0]); | 1862 | for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) |
| 1865 | for (i = 0; i < n; i++) | ||
| 1866 | if (ctrl.id == s->qctrl[i].id) { | 1863 | if (ctrl.id == s->qctrl[i].id) { |
| 1867 | if (ctrl.value < s->qctrl[i].minimum || | 1864 | if (ctrl.value < s->qctrl[i].minimum || |
| 1868 | ctrl.value > s->qctrl[i].maximum) | 1865 | ctrl.value > s->qctrl[i].maximum) |
| @@ -2544,7 +2541,7 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
| 2544 | unsigned int i, n; | 2541 | unsigned int i, n; |
| 2545 | int err = 0, r; | 2542 | int err = 0, r; |
| 2546 | 2543 | ||
| 2547 | n = sizeof(sn9c102_id_table)/sizeof(sn9c102_id_table[0]); | 2544 | n = ARRAY_SIZE(sn9c102_id_table); |
| 2548 | for (i = 0; i < n-1; i++) | 2545 | for (i = 0; i < n-1; i++) |
| 2549 | if (le16_to_cpu(udev->descriptor.idVendor) == | 2546 | if (le16_to_cpu(udev->descriptor.idVendor) == |
| 2550 | sn9c102_id_table[i].idVendor && | 2547 | sn9c102_id_table[i].idVendor && |
| @@ -2711,7 +2708,6 @@ static void sn9c102_usb_disconnect(struct usb_interface* intf) | |||
| 2711 | 2708 | ||
| 2712 | 2709 | ||
| 2713 | static struct usb_driver sn9c102_usb_driver = { | 2710 | static struct usb_driver sn9c102_usb_driver = { |
| 2714 | .owner = THIS_MODULE, | ||
| 2715 | .name = "sn9c102", | 2711 | .name = "sn9c102", |
| 2716 | .id_table = sn9c102_id_table, | 2712 | .id_table = sn9c102_id_table, |
| 2717 | .probe = sn9c102_usb_probe, | 2713 | .probe = sn9c102_usb_probe, |
diff --git a/drivers/usb/media/stv680.c b/drivers/usb/media/stv680.c index 0fd0fa9fec21..774038b352cd 100644 --- a/drivers/usb/media/stv680.c +++ b/drivers/usb/media/stv680.c | |||
| @@ -1477,7 +1477,6 @@ static void stv680_disconnect (struct usb_interface *intf) | |||
| 1477 | } | 1477 | } |
| 1478 | 1478 | ||
| 1479 | static struct usb_driver stv680_driver = { | 1479 | static struct usb_driver stv680_driver = { |
| 1480 | .owner = THIS_MODULE, | ||
| 1481 | .name = "stv680", | 1480 | .name = "stv680", |
| 1482 | .probe = stv680_probe, | 1481 | .probe = stv680_probe, |
| 1483 | .disconnect = stv680_disconnect, | 1482 | .disconnect = stv680_disconnect, |
diff --git a/drivers/usb/media/stv680.h b/drivers/usb/media/stv680.h index 445940612603..b0551cdb280b 100644 --- a/drivers/usb/media/stv680.h +++ b/drivers/usb/media/stv680.h | |||
| @@ -151,7 +151,7 @@ struct usb_stv { | |||
| 151 | }; | 151 | }; |
| 152 | 152 | ||
| 153 | 153 | ||
| 154 | static unsigned char red[256] = { | 154 | static const unsigned char red[256] = { |
| 155 | 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, | 155 | 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, |
| 156 | 18, 18, 18, 18, 18, 18, 18, 25, 30, 35, 38, 42, | 156 | 18, 18, 18, 18, 18, 18, 18, 25, 30, 35, 38, 42, |
| 157 | 44, 47, 50, 53, 54, 57, 59, 61, 63, 65, 67, 69, | 157 | 44, 47, 50, 53, 54, 57, 59, 61, 63, 65, 67, 69, |
| @@ -176,7 +176,7 @@ static unsigned char red[256] = { | |||
| 176 | 220, 220, 221, 221 | 176 | 220, 220, 221, 221 |
| 177 | }; | 177 | }; |
| 178 | 178 | ||
| 179 | static unsigned char green[256] = { | 179 | static const unsigned char green[256] = { |
| 180 | 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, | 180 | 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, |
| 181 | 21, 21, 21, 21, 21, 21, 21, 28, 34, 39, 43, 47, | 181 | 21, 21, 21, 21, 21, 21, 21, 28, 34, 39, 43, 47, |
| 182 | 50, 53, 56, 59, 61, 64, 66, 68, 71, 73, 75, 77, | 182 | 50, 53, 56, 59, 61, 64, 66, 68, 71, 73, 75, 77, |
| @@ -201,7 +201,7 @@ static unsigned char green[256] = { | |||
| 201 | 245, 245, 246, 246 | 201 | 245, 245, 246, 246 |
| 202 | }; | 202 | }; |
| 203 | 203 | ||
| 204 | static unsigned char blue[256] = { | 204 | static const unsigned char blue[256] = { |
| 205 | 0, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, | 205 | 0, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, |
| 206 | 23, 23, 23, 23, 23, 23, 23, 30, 37, 42, 47, 51, | 206 | 23, 23, 23, 23, 23, 23, 23, 30, 37, 42, 47, 51, |
| 207 | 55, 58, 61, 64, 67, 70, 72, 74, 78, 80, 82, 84, | 207 | 55, 58, 61, 64, 67, 70, 72, 74, 78, 80, 82, 84, |
diff --git a/drivers/usb/media/usbvideo.c b/drivers/usb/media/usbvideo.c index 24efb21969c6..4bd113325ef9 100644 --- a/drivers/usb/media/usbvideo.c +++ b/drivers/usb/media/usbvideo.c | |||
| @@ -725,7 +725,7 @@ int usbvideo_register( | |||
| 725 | /* Allocate user_data separately because of kmalloc's limits */ | 725 | /* Allocate user_data separately because of kmalloc's limits */ |
| 726 | if (num_extra > 0) { | 726 | if (num_extra > 0) { |
| 727 | up->user_size = num_cams * num_extra; | 727 | up->user_size = num_cams * num_extra; |
| 728 | up->user_data = (char *) kmalloc(up->user_size, GFP_KERNEL); | 728 | up->user_data = kmalloc(up->user_size, GFP_KERNEL); |
| 729 | if (up->user_data == NULL) { | 729 | if (up->user_data == NULL) { |
| 730 | err("%s: Failed to allocate user_data (%d. bytes)", | 730 | err("%s: Failed to allocate user_data (%d. bytes)", |
| 731 | __FUNCTION__, up->user_size); | 731 | __FUNCTION__, up->user_size); |
| @@ -955,7 +955,7 @@ static struct file_operations usbvideo_fops = { | |||
| 955 | .ioctl = usbvideo_v4l_ioctl, | 955 | .ioctl = usbvideo_v4l_ioctl, |
| 956 | .llseek = no_llseek, | 956 | .llseek = no_llseek, |
| 957 | }; | 957 | }; |
| 958 | static struct video_device usbvideo_template = { | 958 | static const struct video_device usbvideo_template = { |
| 959 | .owner = THIS_MODULE, | 959 | .owner = THIS_MODULE, |
| 960 | .type = VID_TYPE_CAPTURE, | 960 | .type = VID_TYPE_CAPTURE, |
| 961 | .hardware = VID_HARDWARE_CPIA, | 961 | .hardware = VID_HARDWARE_CPIA, |
diff --git a/drivers/usb/media/vicam.c b/drivers/usb/media/vicam.c index 0bc0b1247a6b..1c73155c8d77 100644 --- a/drivers/usb/media/vicam.c +++ b/drivers/usb/media/vicam.c | |||
| @@ -1257,7 +1257,6 @@ static struct usb_device_id vicam_table[] = { | |||
| 1257 | MODULE_DEVICE_TABLE(usb, vicam_table); | 1257 | MODULE_DEVICE_TABLE(usb, vicam_table); |
| 1258 | 1258 | ||
| 1259 | static struct usb_driver vicam_driver = { | 1259 | static struct usb_driver vicam_driver = { |
| 1260 | .owner = THIS_MODULE, | ||
| 1261 | .name = "vicam", | 1260 | .name = "vicam", |
| 1262 | .probe = vicam_probe, | 1261 | .probe = vicam_probe, |
| 1263 | .disconnect = vicam_disconnect, | 1262 | .disconnect = vicam_disconnect, |
diff --git a/drivers/usb/media/w9968cf.c b/drivers/usb/media/w9968cf.c index 67612c81cb9f..04d69339c054 100644 --- a/drivers/usb/media/w9968cf.c +++ b/drivers/usb/media/w9968cf.c | |||
| @@ -2958,7 +2958,7 @@ static int w9968cf_v4l_ioctl(struct inode* inode, struct file* filp, | |||
| 2958 | }; | 2958 | }; |
| 2959 | 2959 | ||
| 2960 | #define V4L1_IOCTL(cmd) \ | 2960 | #define V4L1_IOCTL(cmd) \ |
| 2961 | ((_IOC_NR((cmd)) < sizeof(v4l1_ioctls)/sizeof(char*)) ? \ | 2961 | ((_IOC_NR((cmd)) < ARRAY_SIZE(v4l1_ioctls)) ? \ |
| 2962 | v4l1_ioctls[_IOC_NR((cmd))] : "?") | 2962 | v4l1_ioctls[_IOC_NR((cmd))] : "?") |
| 2963 | 2963 | ||
| 2964 | cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp)); | 2964 | cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp)); |
| @@ -3554,7 +3554,7 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
| 3554 | 3554 | ||
| 3555 | 3555 | ||
| 3556 | /* Allocate 2 bytes of memory for camera control USB transfers */ | 3556 | /* Allocate 2 bytes of memory for camera control USB transfers */ |
| 3557 | if (!(cam->control_buffer = (u16*)kmalloc(2, GFP_KERNEL))) { | 3557 | if (!(cam->control_buffer = kmalloc(2, GFP_KERNEL))) { |
| 3558 | DBG(1,"Couldn't allocate memory for camera control transfers") | 3558 | DBG(1,"Couldn't allocate memory for camera control transfers") |
| 3559 | err = -ENOMEM; | 3559 | err = -ENOMEM; |
| 3560 | goto fail; | 3560 | goto fail; |
| @@ -3562,7 +3562,7 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
| 3562 | memset(cam->control_buffer, 0, 2); | 3562 | memset(cam->control_buffer, 0, 2); |
| 3563 | 3563 | ||
| 3564 | /* Allocate 8 bytes of memory for USB data transfers to the FSB */ | 3564 | /* Allocate 8 bytes of memory for USB data transfers to the FSB */ |
| 3565 | if (!(cam->data_buffer = (u16*)kmalloc(8, GFP_KERNEL))) { | 3565 | if (!(cam->data_buffer = kmalloc(8, GFP_KERNEL))) { |
| 3566 | DBG(1, "Couldn't allocate memory for data " | 3566 | DBG(1, "Couldn't allocate memory for data " |
| 3567 | "transfers to the FSB") | 3567 | "transfers to the FSB") |
| 3568 | err = -ENOMEM; | 3568 | err = -ENOMEM; |
| @@ -3668,7 +3668,6 @@ static void w9968cf_usb_disconnect(struct usb_interface* intf) | |||
| 3668 | 3668 | ||
| 3669 | 3669 | ||
| 3670 | static struct usb_driver w9968cf_usb_driver = { | 3670 | static struct usb_driver w9968cf_usb_driver = { |
| 3671 | .owner = THIS_MODULE, | ||
| 3672 | .name = "w9968cf", | 3671 | .name = "w9968cf", |
| 3673 | .id_table = winbond_id_table, | 3672 | .id_table = winbond_id_table, |
| 3674 | .probe = w9968cf_usb_probe, | 3673 | .probe = w9968cf_usb_probe, |
diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c index b293db3c28c3..449b2501acf3 100644 --- a/drivers/usb/misc/auerswald.c +++ b/drivers/usb/misc/auerswald.c | |||
| @@ -767,7 +767,7 @@ static int auerbuf_setup (pauerbufctl_t bcp, unsigned int numElements, unsigned | |||
| 767 | memset (bep, 0, sizeof (auerbuf_t)); | 767 | memset (bep, 0, sizeof (auerbuf_t)); |
| 768 | bep->list = bcp; | 768 | bep->list = bcp; |
| 769 | INIT_LIST_HEAD (&bep->buff_list); | 769 | INIT_LIST_HEAD (&bep->buff_list); |
| 770 | bep->bufp = (char *) kmalloc (bufsize, GFP_KERNEL); | 770 | bep->bufp = kmalloc (bufsize, GFP_KERNEL); |
| 771 | if (!bep->bufp) | 771 | if (!bep->bufp) |
| 772 | goto bl_fail; | 772 | goto bl_fail; |
| 773 | bep->dr = (struct usb_ctrlrequest *) kmalloc (sizeof (struct usb_ctrlrequest), GFP_KERNEL); | 773 | bep->dr = (struct usb_ctrlrequest *) kmalloc (sizeof (struct usb_ctrlrequest), GFP_KERNEL); |
| @@ -1123,7 +1123,7 @@ static int auerswald_int_open (pauerswald_t cp) | |||
| 1123 | } | 1123 | } |
| 1124 | } | 1124 | } |
| 1125 | if (!cp->intbufp) { | 1125 | if (!cp->intbufp) { |
| 1126 | cp->intbufp = (char *) kmalloc (irqsize, GFP_KERNEL); | 1126 | cp->intbufp = kmalloc (irqsize, GFP_KERNEL); |
| 1127 | if (!cp->intbufp) { | 1127 | if (!cp->intbufp) { |
| 1128 | ret = -ENOMEM; | 1128 | ret = -ENOMEM; |
| 1129 | goto intoend; | 1129 | goto intoend; |
| @@ -2103,7 +2103,6 @@ MODULE_DEVICE_TABLE (usb, auerswald_ids); | |||
| 2103 | 2103 | ||
| 2104 | /* Standard usb driver struct */ | 2104 | /* Standard usb driver struct */ |
| 2105 | static struct usb_driver auerswald_driver = { | 2105 | static struct usb_driver auerswald_driver = { |
| 2106 | .owner = THIS_MODULE, | ||
| 2107 | .name = "auerswald", | 2106 | .name = "auerswald", |
| 2108 | .probe = auerswald_probe, | 2107 | .probe = auerswald_probe, |
| 2109 | .disconnect = auerswald_disconnect, | 2108 | .disconnect = auerswald_disconnect, |
diff --git a/drivers/usb/misc/cytherm.c b/drivers/usb/misc/cytherm.c index b33044d56a1e..6671317b495f 100644 --- a/drivers/usb/misc/cytherm.c +++ b/drivers/usb/misc/cytherm.c | |||
| @@ -50,7 +50,6 @@ static void cytherm_disconnect(struct usb_interface *interface); | |||
| 50 | 50 | ||
| 51 | /* usb specific object needed to register this driver with the usb subsystem */ | 51 | /* usb specific object needed to register this driver with the usb subsystem */ |
| 52 | static struct usb_driver cytherm_driver = { | 52 | static struct usb_driver cytherm_driver = { |
| 53 | .owner = THIS_MODULE, | ||
| 54 | .name = "cytherm", | 53 | .name = "cytherm", |
| 55 | .probe = cytherm_probe, | 54 | .probe = cytherm_probe, |
| 56 | .disconnect = cytherm_disconnect, | 55 | .disconnect = cytherm_disconnect, |
diff --git a/drivers/usb/misc/emi26.c b/drivers/usb/misc/emi26.c index c8155209bf4b..3824df33094e 100644 --- a/drivers/usb/misc/emi26.c +++ b/drivers/usb/misc/emi26.c | |||
| @@ -227,7 +227,6 @@ static void emi26_disconnect(struct usb_interface *intf) | |||
| 227 | } | 227 | } |
| 228 | 228 | ||
| 229 | static struct usb_driver emi26_driver = { | 229 | static struct usb_driver emi26_driver = { |
| 230 | .owner = THIS_MODULE, | ||
| 231 | .name = "emi26 - firmware loader", | 230 | .name = "emi26 - firmware loader", |
| 232 | .probe = emi26_probe, | 231 | .probe = emi26_probe, |
| 233 | .disconnect = emi26_disconnect, | 232 | .disconnect = emi26_disconnect, |
diff --git a/drivers/usb/misc/emi62.c b/drivers/usb/misc/emi62.c index 189986af2ac7..52fea2e08db8 100644 --- a/drivers/usb/misc/emi62.c +++ b/drivers/usb/misc/emi62.c | |||
| @@ -266,7 +266,6 @@ static void emi62_disconnect(struct usb_interface *intf) | |||
| 266 | } | 266 | } |
| 267 | 267 | ||
| 268 | static struct usb_driver emi62_driver = { | 268 | static struct usb_driver emi62_driver = { |
| 269 | .owner = THIS_MODULE, | ||
| 270 | .name = "emi62 - firmware loader", | 269 | .name = "emi62 - firmware loader", |
| 271 | .probe = emi62_probe, | 270 | .probe = emi62_probe, |
| 272 | .disconnect = emi62_disconnect, | 271 | .disconnect = emi62_disconnect, |
diff --git a/drivers/usb/misc/idmouse.c b/drivers/usb/misc/idmouse.c index 1dc3e0f73014..d8cde1017985 100644 --- a/drivers/usb/misc/idmouse.c +++ b/drivers/usb/misc/idmouse.c | |||
| @@ -114,7 +114,6 @@ static struct usb_class_driver idmouse_class = { | |||
| 114 | 114 | ||
| 115 | /* 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 */ |
| 116 | static struct usb_driver idmouse_driver = { | 116 | static struct usb_driver idmouse_driver = { |
| 117 | .owner = THIS_MODULE, | ||
| 118 | .name = DRIVER_SHORT, | 117 | .name = DRIVER_SHORT, |
| 119 | .probe = idmouse_probe, | 118 | .probe = idmouse_probe, |
| 120 | .disconnect = idmouse_disconnect, | 119 | .disconnect = idmouse_disconnect, |
diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c index 7e93ac96490f..981d8a5fbfd9 100644 --- a/drivers/usb/misc/ldusb.c +++ b/drivers/usb/misc/ldusb.c | |||
| @@ -763,7 +763,6 @@ static void ld_usb_disconnect(struct usb_interface *intf) | |||
| 763 | 763 | ||
| 764 | /* usb specific object needed to register this driver with the usb subsystem */ | 764 | /* usb specific object needed to register this driver with the usb subsystem */ |
| 765 | static struct usb_driver ld_usb_driver = { | 765 | static struct usb_driver ld_usb_driver = { |
| 766 | .owner = THIS_MODULE, | ||
| 767 | .name = "ldusb", | 766 | .name = "ldusb", |
| 768 | .probe = ld_usb_probe, | 767 | .probe = ld_usb_probe, |
| 769 | .disconnect = ld_usb_disconnect, | 768 | .disconnect = ld_usb_disconnect, |
diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c index 2703e205bc8f..1336745b8f55 100644 --- a/drivers/usb/misc/legousbtower.c +++ b/drivers/usb/misc/legousbtower.c | |||
| @@ -282,7 +282,6 @@ static struct usb_class_driver tower_class = { | |||
| 282 | 282 | ||
| 283 | /* usb specific object needed to register this driver with the usb subsystem */ | 283 | /* usb specific object needed to register this driver with the usb subsystem */ |
| 284 | static struct usb_driver tower_driver = { | 284 | static struct usb_driver tower_driver = { |
| 285 | .owner = THIS_MODULE, | ||
| 286 | .name = "legousbtower", | 285 | .name = "legousbtower", |
| 287 | .probe = tower_probe, | 286 | .probe = tower_probe, |
| 288 | .disconnect = tower_disconnect, | 287 | .disconnect = tower_disconnect, |
diff --git a/drivers/usb/misc/phidgetkit.c b/drivers/usb/misc/phidgetkit.c index 067a81486921..605a3c87e05c 100644 --- a/drivers/usb/misc/phidgetkit.c +++ b/drivers/usb/misc/phidgetkit.c | |||
| @@ -555,7 +555,6 @@ static void interfacekit_disconnect(struct usb_interface *interface) | |||
| 555 | } | 555 | } |
| 556 | 556 | ||
| 557 | static struct usb_driver interfacekit_driver = { | 557 | static struct usb_driver interfacekit_driver = { |
| 558 | .owner = THIS_MODULE, | ||
| 559 | .name = "phidgetkit", | 558 | .name = "phidgetkit", |
| 560 | .probe = interfacekit_probe, | 559 | .probe = interfacekit_probe, |
| 561 | .disconnect = interfacekit_disconnect, | 560 | .disconnect = interfacekit_disconnect, |
diff --git a/drivers/usb/misc/phidgetservo.c b/drivers/usb/misc/phidgetservo.c index a30d4a6ee824..b3418d2bcc69 100644 --- a/drivers/usb/misc/phidgetservo.c +++ b/drivers/usb/misc/phidgetservo.c | |||
| @@ -306,7 +306,6 @@ servo_disconnect(struct usb_interface *interface) | |||
| 306 | } | 306 | } |
| 307 | 307 | ||
| 308 | static struct usb_driver servo_driver = { | 308 | static struct usb_driver servo_driver = { |
| 309 | .owner = THIS_MODULE, | ||
| 310 | .name = "phidgetservo", | 309 | .name = "phidgetservo", |
| 311 | .probe = servo_probe, | 310 | .probe = servo_probe, |
| 312 | .disconnect = servo_disconnect, | 311 | .disconnect = servo_disconnect, |
diff --git a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c index 9590dbac5d9a..384fa3769805 100644 --- a/drivers/usb/misc/rio500.c +++ b/drivers/usb/misc/rio500.c | |||
| @@ -465,14 +465,14 @@ static int probe_rio(struct usb_interface *intf, | |||
| 465 | 465 | ||
| 466 | rio->rio_dev = dev; | 466 | rio->rio_dev = dev; |
| 467 | 467 | ||
| 468 | if (!(rio->obuf = (char *) kmalloc(OBUF_SIZE, GFP_KERNEL))) { | 468 | if (!(rio->obuf = kmalloc(OBUF_SIZE, GFP_KERNEL))) { |
| 469 | err("probe_rio: Not enough memory for the output buffer"); | 469 | err("probe_rio: Not enough memory for the output buffer"); |
| 470 | usb_deregister_dev(intf, &usb_rio_class); | 470 | usb_deregister_dev(intf, &usb_rio_class); |
| 471 | return -ENOMEM; | 471 | return -ENOMEM; |
| 472 | } | 472 | } |
| 473 | dbg("probe_rio: obuf address:%p", rio->obuf); | 473 | dbg("probe_rio: obuf address:%p", rio->obuf); |
| 474 | 474 | ||
| 475 | if (!(rio->ibuf = (char *) kmalloc(IBUF_SIZE, GFP_KERNEL))) { | 475 | if (!(rio->ibuf = kmalloc(IBUF_SIZE, GFP_KERNEL))) { |
| 476 | err("probe_rio: Not enough memory for the input buffer"); | 476 | err("probe_rio: Not enough memory for the input buffer"); |
| 477 | usb_deregister_dev(intf, &usb_rio_class); | 477 | usb_deregister_dev(intf, &usb_rio_class); |
| 478 | kfree(rio->obuf); | 478 | kfree(rio->obuf); |
| @@ -522,7 +522,6 @@ static struct usb_device_id rio_table [] = { | |||
| 522 | MODULE_DEVICE_TABLE (usb, rio_table); | 522 | MODULE_DEVICE_TABLE (usb, rio_table); |
| 523 | 523 | ||
| 524 | static struct usb_driver rio_driver = { | 524 | static struct usb_driver rio_driver = { |
| 525 | .owner = THIS_MODULE, | ||
| 526 | .name = "rio500", | 525 | .name = "rio500", |
| 527 | .probe = probe_rio, | 526 | .probe = probe_rio, |
| 528 | .disconnect = disconnect_rio, | 527 | .disconnect = disconnect_rio, |
diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c index 41ef2b606751..3260d595441f 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.c +++ b/drivers/usb/misc/sisusbvga/sisusb.c | |||
| @@ -863,9 +863,6 @@ static int sisusb_write_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr, | |||
| 863 | 863 | ||
| 864 | switch (length) { | 864 | switch (length) { |
| 865 | 865 | ||
| 866 | case 0: | ||
| 867 | return ret; | ||
| 868 | |||
| 869 | case 1: | 866 | case 1: |
| 870 | if (userbuffer) { | 867 | if (userbuffer) { |
| 871 | if (get_user(swap8, (u8 __user *)userbuffer)) | 868 | if (get_user(swap8, (u8 __user *)userbuffer)) |
| @@ -1221,9 +1218,6 @@ static int sisusb_read_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr, | |||
| 1221 | 1218 | ||
| 1222 | switch (length) { | 1219 | switch (length) { |
| 1223 | 1220 | ||
| 1224 | case 0: | ||
| 1225 | return ret; | ||
| 1226 | |||
| 1227 | case 1: | 1221 | case 1: |
| 1228 | 1222 | ||
| 1229 | ret |= sisusb_read_memio_byte(sisusb, SISUSB_TYPE_MEM, | 1223 | ret |= sisusb_read_memio_byte(sisusb, SISUSB_TYPE_MEM, |
| @@ -2443,8 +2437,8 @@ sisusb_reset_text_mode(struct sisusb_usb_data *sisusb, int init) | |||
| 2443 | u8 *tempbuf; | 2437 | u8 *tempbuf; |
| 2444 | u16 *tempbufb; | 2438 | u16 *tempbufb; |
| 2445 | size_t written; | 2439 | size_t written; |
| 2446 | static char bootstring[] = "SiSUSB VGA text console, (C) 2005 Thomas Winischhofer."; | 2440 | static const char bootstring[] = "SiSUSB VGA text console, (C) 2005 Thomas Winischhofer."; |
| 2447 | static char bootlogo[] = "(o_ //\\ V_/_"; | 2441 | static const char bootlogo[] = "(o_ //\\ V_/_"; |
| 2448 | 2442 | ||
| 2449 | /* sisusb->lock is down */ | 2443 | /* sisusb->lock is down */ |
| 2450 | 2444 | ||
| @@ -3489,7 +3483,6 @@ static struct usb_device_id sisusb_table [] = { | |||
| 3489 | MODULE_DEVICE_TABLE (usb, sisusb_table); | 3483 | MODULE_DEVICE_TABLE (usb, sisusb_table); |
| 3490 | 3484 | ||
| 3491 | static struct usb_driver sisusb_driver = { | 3485 | static struct usb_driver sisusb_driver = { |
| 3492 | .owner = THIS_MODULE, | ||
| 3493 | .name = "sisusb", | 3486 | .name = "sisusb", |
| 3494 | .probe = sisusb_probe, | 3487 | .probe = sisusb_probe, |
| 3495 | .disconnect = sisusb_disconnect, | 3488 | .disconnect = sisusb_disconnect, |
diff --git a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c index 85f3725334b0..cc3dae3f34e0 100644 --- a/drivers/usb/misc/usblcd.c +++ b/drivers/usb/misc/usblcd.c | |||
| @@ -371,7 +371,6 @@ static void lcd_disconnect(struct usb_interface *interface) | |||
| 371 | } | 371 | } |
| 372 | 372 | ||
| 373 | static struct usb_driver lcd_driver = { | 373 | static struct usb_driver lcd_driver = { |
| 374 | .owner = THIS_MODULE, | ||
| 375 | .name = "usblcd", | 374 | .name = "usblcd", |
| 376 | .probe = lcd_probe, | 375 | .probe = lcd_probe, |
| 377 | .disconnect = lcd_disconnect, | 376 | .disconnect = lcd_disconnect, |
diff --git a/drivers/usb/misc/usbled.c b/drivers/usb/misc/usbled.c index 3c93921cb6b3..877b081a3a6e 100644 --- a/drivers/usb/misc/usbled.c +++ b/drivers/usb/misc/usbled.c | |||
| @@ -148,7 +148,6 @@ static void led_disconnect(struct usb_interface *interface) | |||
| 148 | } | 148 | } |
| 149 | 149 | ||
| 150 | static struct usb_driver led_driver = { | 150 | static struct usb_driver led_driver = { |
| 151 | .owner = THIS_MODULE, | ||
| 152 | .name = "usbled", | 151 | .name = "usbled", |
| 153 | .probe = led_probe, | 152 | .probe = led_probe, |
| 154 | .disconnect = led_disconnect, | 153 | .disconnect = led_disconnect, |
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index 605a2afe34ed..84fa1728f052 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c | |||
| @@ -2134,7 +2134,6 @@ static struct usb_device_id id_table [] = { | |||
| 2134 | MODULE_DEVICE_TABLE (usb, id_table); | 2134 | MODULE_DEVICE_TABLE (usb, id_table); |
| 2135 | 2135 | ||
| 2136 | static struct usb_driver usbtest_driver = { | 2136 | static struct usb_driver usbtest_driver = { |
| 2137 | .owner = THIS_MODULE, | ||
| 2138 | .name = "usbtest", | 2137 | .name = "usbtest", |
| 2139 | .id_table = id_table, | 2138 | .id_table = id_table, |
| 2140 | .probe = usbtest_probe, | 2139 | .probe = usbtest_probe, |
diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c index 1cabe7ed91f5..4081990b7d1a 100644 --- a/drivers/usb/misc/uss720.c +++ b/drivers/usb/misc/uss720.c | |||
| @@ -780,7 +780,6 @@ MODULE_DEVICE_TABLE (usb, uss720_table); | |||
| 780 | 780 | ||
| 781 | 781 | ||
| 782 | static struct usb_driver uss720_driver = { | 782 | static struct usb_driver uss720_driver = { |
| 783 | .owner = THIS_MODULE, | ||
| 784 | .name = "uss720", | 783 | .name = "uss720", |
| 785 | .probe = uss720_probe, | 784 | .probe = uss720_probe, |
| 786 | .disconnect = uss720_disconnect, | 785 | .disconnect = uss720_disconnect, |
diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c index 17d0190ef64e..611612146ae9 100644 --- a/drivers/usb/mon/mon_text.c +++ b/drivers/usb/mon/mon_text.c | |||
| @@ -97,19 +97,12 @@ static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb, | |||
| 97 | if (len >= DATA_MAX) | 97 | if (len >= DATA_MAX) |
| 98 | len = DATA_MAX; | 98 | len = DATA_MAX; |
| 99 | 99 | ||
| 100 | /* | 100 | if (usb_pipein(pipe)) { |
| 101 | * Bulk is easy to shortcut reliably. | 101 | if (ev_type == 'S') |
| 102 | * XXX Other pipe types need consideration. Currently, we overdo it | 102 | return '<'; |
| 103 | * and collect garbage for them: better more than less. | 103 | } else { |
| 104 | */ | 104 | if (ev_type == 'C') |
| 105 | if (usb_pipebulk(pipe) || usb_pipecontrol(pipe)) { | 105 | return '>'; |
| 106 | if (usb_pipein(pipe)) { | ||
| 107 | if (ev_type == 'S') | ||
| 108 | return '<'; | ||
| 109 | } else { | ||
| 110 | if (ev_type == 'C') | ||
| 111 | return '>'; | ||
| 112 | } | ||
| 113 | } | 106 | } |
| 114 | 107 | ||
| 115 | /* | 108 | /* |
diff --git a/drivers/usb/net/asix.c b/drivers/usb/net/asix.c index 542120ef1fd2..541181695040 100644 --- a/drivers/usb/net/asix.c +++ b/drivers/usb/net/asix.c | |||
| @@ -912,13 +912,16 @@ static const struct usb_device_id products [] = { | |||
| 912 | // ASIX AX88772 10/100 | 912 | // ASIX AX88772 10/100 |
| 913 | USB_DEVICE (0x0b95, 0x7720), | 913 | USB_DEVICE (0x0b95, 0x7720), |
| 914 | .driver_info = (unsigned long) &ax88772_info, | 914 | .driver_info = (unsigned long) &ax88772_info, |
| 915 | }, { | ||
| 916 | // Linksys USB200M Rev 2 | ||
| 917 | USB_DEVICE (0x13b1, 0x0018), | ||
| 918 | .driver_info = (unsigned long) &ax88772_info, | ||
| 915 | }, | 919 | }, |
| 916 | { }, // END | 920 | { }, // END |
| 917 | }; | 921 | }; |
| 918 | MODULE_DEVICE_TABLE(usb, products); | 922 | MODULE_DEVICE_TABLE(usb, products); |
| 919 | 923 | ||
| 920 | static struct usb_driver asix_driver = { | 924 | static struct usb_driver asix_driver = { |
| 921 | .owner = THIS_MODULE, | ||
| 922 | .name = "asix", | 925 | .name = "asix", |
| 923 | .id_table = products, | 926 | .id_table = products, |
| 924 | .probe = usbnet_probe, | 927 | .probe = usbnet_probe, |
diff --git a/drivers/usb/net/catc.c b/drivers/usb/net/catc.c index 37ef365a2472..be5f5e142dd0 100644 --- a/drivers/usb/net/catc.c +++ b/drivers/usb/net/catc.c | |||
| @@ -934,7 +934,6 @@ static struct usb_device_id catc_id_table [] = { | |||
| 934 | MODULE_DEVICE_TABLE(usb, catc_id_table); | 934 | MODULE_DEVICE_TABLE(usb, catc_id_table); |
| 935 | 935 | ||
| 936 | static struct usb_driver catc_driver = { | 936 | static struct usb_driver catc_driver = { |
| 937 | .owner = THIS_MODULE, | ||
| 938 | .name = driver_name, | 937 | .name = driver_name, |
| 939 | .probe = catc_probe, | 938 | .probe = catc_probe, |
| 940 | .disconnect = catc_disconnect, | 939 | .disconnect = catc_disconnect, |
diff --git a/drivers/usb/net/cdc_ether.c b/drivers/usb/net/cdc_ether.c index c008c981862b..63f1f3ba8e0b 100644 --- a/drivers/usb/net/cdc_ether.c +++ b/drivers/usb/net/cdc_ether.c | |||
| @@ -476,7 +476,6 @@ static const struct usb_device_id products [] = { | |||
| 476 | MODULE_DEVICE_TABLE(usb, products); | 476 | MODULE_DEVICE_TABLE(usb, products); |
| 477 | 477 | ||
| 478 | static struct usb_driver cdc_driver = { | 478 | static struct usb_driver cdc_driver = { |
| 479 | .owner = THIS_MODULE, | ||
| 480 | .name = "cdc_ether", | 479 | .name = "cdc_ether", |
| 481 | .id_table = products, | 480 | .id_table = products, |
| 482 | .probe = usbnet_probe, | 481 | .probe = usbnet_probe, |
diff --git a/drivers/usb/net/cdc_subset.c b/drivers/usb/net/cdc_subset.c index f05cfb83c82d..ec801e8bb1bb 100644 --- a/drivers/usb/net/cdc_subset.c +++ b/drivers/usb/net/cdc_subset.c | |||
| @@ -306,7 +306,6 @@ MODULE_DEVICE_TABLE(usb, products); | |||
| 306 | /*-------------------------------------------------------------------------*/ | 306 | /*-------------------------------------------------------------------------*/ |
| 307 | 307 | ||
| 308 | static struct usb_driver cdc_subset_driver = { | 308 | static struct usb_driver cdc_subset_driver = { |
| 309 | .owner = THIS_MODULE, | ||
| 310 | .name = "cdc_subset", | 309 | .name = "cdc_subset", |
| 311 | .probe = usbnet_probe, | 310 | .probe = usbnet_probe, |
| 312 | .suspend = usbnet_suspend, | 311 | .suspend = usbnet_suspend, |
diff --git a/drivers/usb/net/gl620a.c b/drivers/usb/net/gl620a.c index 2455e9a85674..faf1e86be687 100644 --- a/drivers/usb/net/gl620a.c +++ b/drivers/usb/net/gl620a.c | |||
| @@ -377,7 +377,6 @@ static const struct usb_device_id products [] = { | |||
| 377 | MODULE_DEVICE_TABLE(usb, products); | 377 | MODULE_DEVICE_TABLE(usb, products); |
| 378 | 378 | ||
| 379 | static struct usb_driver gl620a_driver = { | 379 | static struct usb_driver gl620a_driver = { |
| 380 | .owner = THIS_MODULE, | ||
| 381 | .name = "gl620a", | 380 | .name = "gl620a", |
| 382 | .id_table = products, | 381 | .id_table = products, |
| 383 | .probe = usbnet_probe, | 382 | .probe = usbnet_probe, |
diff --git a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c index b5776518020f..def3bb8e2290 100644 --- a/drivers/usb/net/kaweth.c +++ b/drivers/usb/net/kaweth.c | |||
| @@ -175,7 +175,6 @@ MODULE_DEVICE_TABLE (usb, usb_klsi_table); | |||
| 175 | * kaweth_driver | 175 | * kaweth_driver |
| 176 | ****************************************************************/ | 176 | ****************************************************************/ |
| 177 | static struct usb_driver kaweth_driver = { | 177 | static struct usb_driver kaweth_driver = { |
| 178 | .owner = THIS_MODULE, | ||
| 179 | .name = driver_name, | 178 | .name = driver_name, |
| 180 | .probe = kaweth_probe, | 179 | .probe = kaweth_probe, |
| 181 | .disconnect = kaweth_disconnect, | 180 | .disconnect = kaweth_disconnect, |
diff --git a/drivers/usb/net/net1080.c b/drivers/usb/net/net1080.c index b3799b1a2b0d..78e6a43b1087 100644 --- a/drivers/usb/net/net1080.c +++ b/drivers/usb/net/net1080.c | |||
| @@ -593,7 +593,6 @@ static const struct usb_device_id products [] = { | |||
| 593 | MODULE_DEVICE_TABLE(usb, products); | 593 | MODULE_DEVICE_TABLE(usb, products); |
| 594 | 594 | ||
| 595 | static struct usb_driver net1080_driver = { | 595 | static struct usb_driver net1080_driver = { |
| 596 | .owner = THIS_MODULE, | ||
| 597 | .name = "net1080", | 596 | .name = "net1080", |
| 598 | .id_table = products, | 597 | .id_table = products, |
| 599 | .probe = usbnet_probe, | 598 | .probe = usbnet_probe, |
diff --git a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c index 683e3df5d607..156a2f1cb39a 100644 --- a/drivers/usb/net/pegasus.c +++ b/drivers/usb/net/pegasus.c | |||
| @@ -45,7 +45,7 @@ | |||
| 45 | /* | 45 | /* |
| 46 | * Version Information | 46 | * Version Information |
| 47 | */ | 47 | */ |
| 48 | #define DRIVER_VERSION "v0.6.12 (2005/01/13)" | 48 | #define DRIVER_VERSION "v0.6.13 (2005/11/13)" |
| 49 | #define DRIVER_AUTHOR "Petko Manolov <petkan@users.sourceforge.net>" | 49 | #define DRIVER_AUTHOR "Petko Manolov <petkan@users.sourceforge.net>" |
| 50 | #define DRIVER_DESC "Pegasus/Pegasus II USB Ethernet driver" | 50 | #define DRIVER_DESC "Pegasus/Pegasus II USB Ethernet driver" |
| 51 | 51 | ||
| @@ -57,12 +57,14 @@ static const char driver_name[] = "pegasus"; | |||
| 57 | 57 | ||
| 58 | static int loopback = 0; | 58 | static int loopback = 0; |
| 59 | static int mii_mode = 0; | 59 | static int mii_mode = 0; |
| 60 | static char *devid=NULL; | ||
| 60 | 61 | ||
| 61 | static struct usb_eth_dev usb_dev_id[] = { | 62 | static struct usb_eth_dev usb_dev_id[] = { |
| 62 | #define PEGASUS_DEV(pn, vid, pid, flags) \ | 63 | #define PEGASUS_DEV(pn, vid, pid, flags) \ |
| 63 | {.name = pn, .vendor = vid, .device = pid, .private = flags}, | 64 | {.name = pn, .vendor = vid, .device = pid, .private = flags}, |
| 64 | #include "pegasus.h" | 65 | #include "pegasus.h" |
| 65 | #undef PEGASUS_DEV | 66 | #undef PEGASUS_DEV |
| 67 | {NULL, 0, 0, 0}, | ||
| 66 | {NULL, 0, 0, 0} | 68 | {NULL, 0, 0, 0} |
| 67 | }; | 69 | }; |
| 68 | 70 | ||
| @@ -71,6 +73,7 @@ static struct usb_device_id pegasus_ids[] = { | |||
| 71 | {.match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = vid, .idProduct = pid}, | 73 | {.match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = vid, .idProduct = pid}, |
| 72 | #include "pegasus.h" | 74 | #include "pegasus.h" |
| 73 | #undef PEGASUS_DEV | 75 | #undef PEGASUS_DEV |
| 76 | {}, | ||
| 74 | {} | 77 | {} |
| 75 | }; | 78 | }; |
| 76 | 79 | ||
| @@ -79,8 +82,10 @@ MODULE_DESCRIPTION(DRIVER_DESC); | |||
| 79 | MODULE_LICENSE("GPL"); | 82 | MODULE_LICENSE("GPL"); |
| 80 | module_param(loopback, bool, 0); | 83 | module_param(loopback, bool, 0); |
| 81 | module_param(mii_mode, bool, 0); | 84 | module_param(mii_mode, bool, 0); |
| 85 | module_param(devid, charp, 0); | ||
| 82 | MODULE_PARM_DESC(loopback, "Enable MAC loopback mode (bit 0)"); | 86 | MODULE_PARM_DESC(loopback, "Enable MAC loopback mode (bit 0)"); |
| 83 | MODULE_PARM_DESC(mii_mode, "Enable HomePNA mode (bit 0),default=MII mode = 0"); | 87 | MODULE_PARM_DESC(mii_mode, "Enable HomePNA mode (bit 0),default=MII mode = 0"); |
| 88 | MODULE_PARM_DESC(devid, "The format is: 'DEV_name:VendorID:DeviceID:Flags'"); | ||
| 84 | 89 | ||
| 85 | /* use ethtool to change the level for any given device */ | 90 | /* use ethtool to change the level for any given device */ |
| 86 | static int msg_level = -1; | 91 | static int msg_level = -1; |
| @@ -113,7 +118,7 @@ static void ctrl_callback(struct urb *urb, struct pt_regs *regs) | |||
| 113 | break; | 118 | break; |
| 114 | default: | 119 | default: |
| 115 | if (netif_msg_drv(pegasus)) | 120 | if (netif_msg_drv(pegasus)) |
| 116 | dev_err(&pegasus->intf->dev, "%s, status %d\n", | 121 | dev_dbg(&pegasus->intf->dev, "%s, status %d\n", |
| 117 | __FUNCTION__, urb->status); | 122 | __FUNCTION__, urb->status); |
| 118 | } | 123 | } |
| 119 | pegasus->flags &= ~ETH_REGS_CHANGED; | 124 | pegasus->flags &= ~ETH_REGS_CHANGED; |
| @@ -308,9 +313,9 @@ static int read_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 * regd) | |||
| 308 | __le16 regdi; | 313 | __le16 regdi; |
| 309 | int ret; | 314 | int ret; |
| 310 | 315 | ||
| 311 | ret = set_register(pegasus, PhyCtrl, 0); | 316 | set_register(pegasus, PhyCtrl, 0); |
| 312 | ret = set_registers(pegasus, PhyAddr, sizeof (data), data); | 317 | set_registers(pegasus, PhyAddr, sizeof (data), data); |
| 313 | ret = set_register(pegasus, PhyCtrl, (indx | PHY_READ)); | 318 | set_register(pegasus, PhyCtrl, (indx | PHY_READ)); |
| 314 | for (i = 0; i < REG_TIMEOUT; i++) { | 319 | for (i = 0; i < REG_TIMEOUT; i++) { |
| 315 | ret = get_registers(pegasus, PhyCtrl, 1, data); | 320 | ret = get_registers(pegasus, PhyCtrl, 1, data); |
| 316 | if (data[0] & PHY_DONE) | 321 | if (data[0] & PHY_DONE) |
| @@ -319,12 +324,12 @@ static int read_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 * regd) | |||
| 319 | if (i < REG_TIMEOUT) { | 324 | if (i < REG_TIMEOUT) { |
| 320 | ret = get_registers(pegasus, PhyData, 2, ®di); | 325 | ret = get_registers(pegasus, PhyData, 2, ®di); |
| 321 | *regd = le16_to_cpu(regdi); | 326 | *regd = le16_to_cpu(regdi); |
| 322 | return 1; | 327 | return ret; |
| 323 | } | 328 | } |
| 324 | if (netif_msg_drv(pegasus)) | 329 | if (netif_msg_drv(pegasus)) |
| 325 | dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); | 330 | dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); |
| 326 | 331 | ||
| 327 | return 0; | 332 | return ret; |
| 328 | } | 333 | } |
| 329 | 334 | ||
| 330 | static int mdio_read(struct net_device *dev, int phy_id, int loc) | 335 | static int mdio_read(struct net_device *dev, int phy_id, int loc) |
| @@ -344,20 +349,20 @@ static int write_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 regd) | |||
| 344 | 349 | ||
| 345 | data[1] = (u8) regd; | 350 | data[1] = (u8) regd; |
| 346 | data[2] = (u8) (regd >> 8); | 351 | data[2] = (u8) (regd >> 8); |
| 347 | ret = set_register(pegasus, PhyCtrl, 0); | 352 | set_register(pegasus, PhyCtrl, 0); |
| 348 | ret = set_registers(pegasus, PhyAddr, sizeof(data), data); | 353 | set_registers(pegasus, PhyAddr, sizeof(data), data); |
| 349 | ret = set_register(pegasus, PhyCtrl, (indx | PHY_WRITE)); | 354 | set_register(pegasus, PhyCtrl, (indx | PHY_WRITE)); |
| 350 | for (i = 0; i < REG_TIMEOUT; i++) { | 355 | for (i = 0; i < REG_TIMEOUT; i++) { |
| 351 | ret = get_registers(pegasus, PhyCtrl, 1, data); | 356 | ret = get_registers(pegasus, PhyCtrl, 1, data); |
| 352 | if (data[0] & PHY_DONE) | 357 | if (data[0] & PHY_DONE) |
| 353 | break; | 358 | break; |
| 354 | } | 359 | } |
| 355 | if (i < REG_TIMEOUT) | 360 | if (i < REG_TIMEOUT) |
| 356 | return 0; | 361 | return ret; |
| 357 | 362 | ||
| 358 | if (netif_msg_drv(pegasus)) | 363 | if (netif_msg_drv(pegasus)) |
| 359 | dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); | 364 | dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); |
| 360 | return 1; | 365 | return -ETIMEDOUT; |
| 361 | } | 366 | } |
| 362 | 367 | ||
| 363 | static void mdio_write(struct net_device *dev, int phy_id, int loc, int val) | 368 | static void mdio_write(struct net_device *dev, int phy_id, int loc, int val) |
| @@ -374,9 +379,9 @@ static int read_eprom_word(pegasus_t * pegasus, __u8 index, __u16 * retdata) | |||
| 374 | __le16 retdatai; | 379 | __le16 retdatai; |
| 375 | int ret; | 380 | int ret; |
| 376 | 381 | ||
| 377 | ret = set_register(pegasus, EpromCtrl, 0); | 382 | set_register(pegasus, EpromCtrl, 0); |
| 378 | ret = set_register(pegasus, EpromOffset, index); | 383 | set_register(pegasus, EpromOffset, index); |
| 379 | ret = set_register(pegasus, EpromCtrl, EPROM_READ); | 384 | set_register(pegasus, EpromCtrl, EPROM_READ); |
| 380 | 385 | ||
| 381 | for (i = 0; i < REG_TIMEOUT; i++) { | 386 | for (i = 0; i < REG_TIMEOUT; i++) { |
| 382 | ret = get_registers(pegasus, EpromCtrl, 1, &tmp); | 387 | ret = get_registers(pegasus, EpromCtrl, 1, &tmp); |
| @@ -386,12 +391,12 @@ static int read_eprom_word(pegasus_t * pegasus, __u8 index, __u16 * retdata) | |||
| 386 | if (i < REG_TIMEOUT) { | 391 | if (i < REG_TIMEOUT) { |
| 387 | ret = get_registers(pegasus, EpromData, 2, &retdatai); | 392 | ret = get_registers(pegasus, EpromData, 2, &retdatai); |
| 388 | *retdata = le16_to_cpu(retdatai); | 393 | *retdata = le16_to_cpu(retdatai); |
| 389 | return 0; | 394 | return ret; |
| 390 | } | 395 | } |
| 391 | 396 | ||
| 392 | if (netif_msg_drv(pegasus)) | 397 | if (netif_msg_drv(pegasus)) |
| 393 | dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); | 398 | dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); |
| 394 | return -1; | 399 | return -ETIMEDOUT; |
| 395 | } | 400 | } |
| 396 | 401 | ||
| 397 | #ifdef PEGASUS_WRITE_EEPROM | 402 | #ifdef PEGASUS_WRITE_EEPROM |
| @@ -400,8 +405,8 @@ static inline void enable_eprom_write(pegasus_t * pegasus) | |||
| 400 | __u8 tmp; | 405 | __u8 tmp; |
| 401 | int ret; | 406 | int ret; |
| 402 | 407 | ||
| 403 | ret = get_registers(pegasus, EthCtrl2, 1, &tmp); | 408 | get_registers(pegasus, EthCtrl2, 1, &tmp); |
| 404 | ret = set_register(pegasus, EthCtrl2, tmp | EPROM_WR_ENABLE); | 409 | set_register(pegasus, EthCtrl2, tmp | EPROM_WR_ENABLE); |
| 405 | } | 410 | } |
| 406 | 411 | ||
| 407 | static inline void disable_eprom_write(pegasus_t * pegasus) | 412 | static inline void disable_eprom_write(pegasus_t * pegasus) |
| @@ -409,9 +414,9 @@ static inline void disable_eprom_write(pegasus_t * pegasus) | |||
| 409 | __u8 tmp; | 414 | __u8 tmp; |
| 410 | int ret; | 415 | int ret; |
| 411 | 416 | ||
| 412 | ret = get_registers(pegasus, EthCtrl2, 1, &tmp); | 417 | get_registers(pegasus, EthCtrl2, 1, &tmp); |
| 413 | ret = set_register(pegasus, EpromCtrl, 0); | 418 | set_register(pegasus, EpromCtrl, 0); |
| 414 | ret = set_register(pegasus, EthCtrl2, tmp & ~EPROM_WR_ENABLE); | 419 | set_register(pegasus, EthCtrl2, tmp & ~EPROM_WR_ENABLE); |
| 415 | } | 420 | } |
| 416 | 421 | ||
| 417 | static int write_eprom_word(pegasus_t * pegasus, __u8 index, __u16 data) | 422 | static int write_eprom_word(pegasus_t * pegasus, __u8 index, __u16 data) |
| @@ -420,11 +425,11 @@ static int write_eprom_word(pegasus_t * pegasus, __u8 index, __u16 data) | |||
| 420 | __u8 tmp, d[4] = { 0x3f, 0, 0, EPROM_WRITE }; | 425 | __u8 tmp, d[4] = { 0x3f, 0, 0, EPROM_WRITE }; |
| 421 | int ret; | 426 | int ret; |
| 422 | 427 | ||
| 423 | ret = set_registers(pegasus, EpromOffset, 4, d); | 428 | set_registers(pegasus, EpromOffset, 4, d); |
| 424 | enable_eprom_write(pegasus); | 429 | enable_eprom_write(pegasus); |
| 425 | ret = set_register(pegasus, EpromOffset, index); | 430 | set_register(pegasus, EpromOffset, index); |
| 426 | ret = set_registers(pegasus, EpromData, 2, &data); | 431 | set_registers(pegasus, EpromData, 2, &data); |
| 427 | ret = set_register(pegasus, EpromCtrl, EPROM_WRITE); | 432 | set_register(pegasus, EpromCtrl, EPROM_WRITE); |
| 428 | 433 | ||
| 429 | for (i = 0; i < REG_TIMEOUT; i++) { | 434 | for (i = 0; i < REG_TIMEOUT; i++) { |
| 430 | ret = get_registers(pegasus, EpromCtrl, 1, &tmp); | 435 | ret = get_registers(pegasus, EpromCtrl, 1, &tmp); |
| @@ -433,10 +438,10 @@ static int write_eprom_word(pegasus_t * pegasus, __u8 index, __u16 data) | |||
| 433 | } | 438 | } |
| 434 | disable_eprom_write(pegasus); | 439 | disable_eprom_write(pegasus); |
| 435 | if (i < REG_TIMEOUT) | 440 | if (i < REG_TIMEOUT) |
| 436 | return 0; | 441 | return ret; |
| 437 | if (netif_msg_drv(pegasus)) | 442 | if (netif_msg_drv(pegasus)) |
| 438 | dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); | 443 | dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); |
| 439 | return -1; | 444 | return -ETIMEDOUT; |
| 440 | } | 445 | } |
| 441 | #endif /* PEGASUS_WRITE_EEPROM */ | 446 | #endif /* PEGASUS_WRITE_EEPROM */ |
| 442 | 447 | ||
| @@ -454,10 +459,9 @@ static inline void get_node_id(pegasus_t * pegasus, __u8 * id) | |||
| 454 | static void set_ethernet_addr(pegasus_t * pegasus) | 459 | static void set_ethernet_addr(pegasus_t * pegasus) |
| 455 | { | 460 | { |
| 456 | __u8 node_id[6]; | 461 | __u8 node_id[6]; |
| 457 | int ret; | ||
| 458 | 462 | ||
| 459 | get_node_id(pegasus, node_id); | 463 | get_node_id(pegasus, node_id); |
| 460 | ret = set_registers(pegasus, EthID, sizeof (node_id), node_id); | 464 | set_registers(pegasus, EthID, sizeof (node_id), node_id); |
| 461 | memcpy(pegasus->net->dev_addr, node_id, sizeof (node_id)); | 465 | memcpy(pegasus->net->dev_addr, node_id, sizeof (node_id)); |
| 462 | } | 466 | } |
| 463 | 467 | ||
| @@ -465,30 +469,29 @@ static inline int reset_mac(pegasus_t * pegasus) | |||
| 465 | { | 469 | { |
| 466 | __u8 data = 0x8; | 470 | __u8 data = 0x8; |
| 467 | int i; | 471 | int i; |
| 468 | int ret; | ||
| 469 | 472 | ||
| 470 | ret = set_register(pegasus, EthCtrl1, data); | 473 | set_register(pegasus, EthCtrl1, data); |
| 471 | for (i = 0; i < REG_TIMEOUT; i++) { | 474 | for (i = 0; i < REG_TIMEOUT; i++) { |
| 472 | ret = get_registers(pegasus, EthCtrl1, 1, &data); | 475 | get_registers(pegasus, EthCtrl1, 1, &data); |
| 473 | if (~data & 0x08) { | 476 | if (~data & 0x08) { |
| 474 | if (loopback & 1) | 477 | if (loopback & 1) |
| 475 | break; | 478 | break; |
| 476 | if (mii_mode && (pegasus->features & HAS_HOME_PNA)) | 479 | if (mii_mode && (pegasus->features & HAS_HOME_PNA)) |
| 477 | ret = set_register(pegasus, Gpio1, 0x34); | 480 | set_register(pegasus, Gpio1, 0x34); |
| 478 | else | 481 | else |
| 479 | ret = set_register(pegasus, Gpio1, 0x26); | 482 | set_register(pegasus, Gpio1, 0x26); |
| 480 | ret = set_register(pegasus, Gpio0, pegasus->features); | 483 | set_register(pegasus, Gpio0, pegasus->features); |
| 481 | ret = set_register(pegasus, Gpio0, DEFAULT_GPIO_SET); | 484 | set_register(pegasus, Gpio0, DEFAULT_GPIO_SET); |
| 482 | break; | 485 | break; |
| 483 | } | 486 | } |
| 484 | } | 487 | } |
| 485 | if (i == REG_TIMEOUT) | 488 | if (i == REG_TIMEOUT) |
| 486 | return 1; | 489 | return -ETIMEDOUT; |
| 487 | 490 | ||
| 488 | if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_LINKSYS || | 491 | if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_LINKSYS || |
| 489 | usb_dev_id[pegasus->dev_index].vendor == VENDOR_DLINK) { | 492 | usb_dev_id[pegasus->dev_index].vendor == VENDOR_DLINK) { |
| 490 | ret = set_register(pegasus, Gpio0, 0x24); | 493 | set_register(pegasus, Gpio0, 0x24); |
| 491 | ret = set_register(pegasus, Gpio0, 0x26); | 494 | set_register(pegasus, Gpio0, 0x26); |
| 492 | } | 495 | } |
| 493 | if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_ELCON) { | 496 | if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_ELCON) { |
| 494 | __u16 auxmode; | 497 | __u16 auxmode; |
| @@ -527,7 +530,7 @@ static int enable_net_traffic(struct net_device *dev, struct usb_device *usb) | |||
| 527 | write_mii_word(pegasus, 0, 0x1b, auxmode | 4); | 530 | write_mii_word(pegasus, 0, 0x1b, auxmode | 4); |
| 528 | } | 531 | } |
| 529 | 532 | ||
| 530 | return 0; | 533 | return ret; |
| 531 | } | 534 | } |
| 532 | 535 | ||
| 533 | static void fill_skb_pool(pegasus_t * pegasus) | 536 | static void fill_skb_pool(pegasus_t * pegasus) |
| @@ -881,9 +884,8 @@ static struct net_device_stats *pegasus_netdev_stats(struct net_device *dev) | |||
| 881 | static inline void disable_net_traffic(pegasus_t * pegasus) | 884 | static inline void disable_net_traffic(pegasus_t * pegasus) |
| 882 | { | 885 | { |
| 883 | int tmp = 0; | 886 | int tmp = 0; |
| 884 | int ret; | ||
| 885 | 887 | ||
| 886 | ret = set_registers(pegasus, EthCtrl0, 2, &tmp); | 888 | set_registers(pegasus, EthCtrl0, 2, &tmp); |
| 887 | } | 889 | } |
| 888 | 890 | ||
| 889 | static inline void get_interrupt_interval(pegasus_t * pegasus) | 891 | static inline void get_interrupt_interval(pegasus_t * pegasus) |
| @@ -1206,18 +1208,17 @@ static __u8 mii_phy_probe(pegasus_t * pegasus) | |||
| 1206 | static inline void setup_pegasus_II(pegasus_t * pegasus) | 1208 | static inline void setup_pegasus_II(pegasus_t * pegasus) |
| 1207 | { | 1209 | { |
| 1208 | __u8 data = 0xa5; | 1210 | __u8 data = 0xa5; |
| 1209 | int ret; | ||
| 1210 | 1211 | ||
| 1211 | ret = set_register(pegasus, Reg1d, 0); | 1212 | set_register(pegasus, Reg1d, 0); |
| 1212 | ret = set_register(pegasus, Reg7b, 1); | 1213 | set_register(pegasus, Reg7b, 1); |
| 1213 | mdelay(100); | 1214 | mdelay(100); |
| 1214 | if ((pegasus->features & HAS_HOME_PNA) && mii_mode) | 1215 | if ((pegasus->features & HAS_HOME_PNA) && mii_mode) |
| 1215 | ret = set_register(pegasus, Reg7b, 0); | 1216 | set_register(pegasus, Reg7b, 0); |
| 1216 | else | 1217 | else |
| 1217 | ret = set_register(pegasus, Reg7b, 2); | 1218 | set_register(pegasus, Reg7b, 2); |
| 1218 | 1219 | ||
| 1219 | ret = set_register(pegasus, 0x83, data); | 1220 | set_register(pegasus, 0x83, data); |
| 1220 | ret = get_registers(pegasus, 0x83, 1, &data); | 1221 | get_registers(pegasus, 0x83, 1, &data); |
| 1221 | 1222 | ||
| 1222 | if (data == 0xa5) { | 1223 | if (data == 0xa5) { |
| 1223 | pegasus->chip = 0x8513; | 1224 | pegasus->chip = 0x8513; |
| @@ -1225,14 +1226,14 @@ static inline void setup_pegasus_II(pegasus_t * pegasus) | |||
| 1225 | pegasus->chip = 0; | 1226 | pegasus->chip = 0; |
| 1226 | } | 1227 | } |
| 1227 | 1228 | ||
| 1228 | ret = set_register(pegasus, 0x80, 0xc0); | 1229 | set_register(pegasus, 0x80, 0xc0); |
| 1229 | ret = set_register(pegasus, 0x83, 0xff); | 1230 | set_register(pegasus, 0x83, 0xff); |
| 1230 | ret = set_register(pegasus, 0x84, 0x01); | 1231 | set_register(pegasus, 0x84, 0x01); |
| 1231 | 1232 | ||
| 1232 | if (pegasus->features & HAS_HOME_PNA && mii_mode) | 1233 | if (pegasus->features & HAS_HOME_PNA && mii_mode) |
| 1233 | ret = set_register(pegasus, Reg81, 6); | 1234 | set_register(pegasus, Reg81, 6); |
| 1234 | else | 1235 | else |
| 1235 | ret = set_register(pegasus, Reg81, 2); | 1236 | set_register(pegasus, Reg81, 2); |
| 1236 | } | 1237 | } |
| 1237 | 1238 | ||
| 1238 | 1239 | ||
| @@ -1414,9 +1415,42 @@ static struct usb_driver pegasus_driver = { | |||
| 1414 | .resume = pegasus_resume, | 1415 | .resume = pegasus_resume, |
| 1415 | }; | 1416 | }; |
| 1416 | 1417 | ||
| 1418 | static void parse_id(char *id) | ||
| 1419 | { | ||
| 1420 | unsigned int vendor_id=0, device_id=0, flags=0, i=0; | ||
| 1421 | char *token, *name=NULL; | ||
| 1422 | |||
| 1423 | if ((token = strsep(&id, ":")) != NULL) | ||
| 1424 | name = token; | ||
| 1425 | /* name now points to a null terminated string*/ | ||
| 1426 | if ((token = strsep(&id, ":")) != NULL) | ||
| 1427 | vendor_id = simple_strtoul(token, NULL, 16); | ||
| 1428 | if ((token = strsep(&id, ":")) != NULL) | ||
| 1429 | device_id = simple_strtoul(token, NULL, 16); | ||
| 1430 | flags = simple_strtoul(id, NULL, 16); | ||
| 1431 | pr_info("%s: new device %s, vendor ID 0x%04x, device ID 0x%04x, flags: 0x%x\n", | ||
| 1432 | driver_name, name, vendor_id, device_id, flags); | ||
| 1433 | |||
| 1434 | if (vendor_id > 0x10000 || vendor_id == 0) | ||
| 1435 | return; | ||
| 1436 | if (device_id > 0x10000 || device_id == 0) | ||
| 1437 | return; | ||
| 1438 | |||
| 1439 | for (i=0; usb_dev_id[i].name; i++); | ||
| 1440 | usb_dev_id[i].name = name; | ||
| 1441 | usb_dev_id[i].vendor = vendor_id; | ||
| 1442 | usb_dev_id[i].device = device_id; | ||
| 1443 | usb_dev_id[i].private = flags; | ||
| 1444 | pegasus_ids[i].match_flags = USB_DEVICE_ID_MATCH_DEVICE; | ||
| 1445 | pegasus_ids[i].idVendor = vendor_id; | ||
| 1446 | pegasus_ids[i].idProduct = device_id; | ||
| 1447 | } | ||
| 1448 | |||
| 1417 | static int __init pegasus_init(void) | 1449 | static int __init pegasus_init(void) |
| 1418 | { | 1450 | { |
| 1419 | pr_info("%s: %s, " DRIVER_DESC "\n", driver_name, DRIVER_VERSION); | 1451 | pr_info("%s: %s, " DRIVER_DESC "\n", driver_name, DRIVER_VERSION); |
| 1452 | if (devid) | ||
| 1453 | parse_id(devid); | ||
| 1420 | pegasus_workqueue = create_singlethread_workqueue("pegasus"); | 1454 | pegasus_workqueue = create_singlethread_workqueue("pegasus"); |
| 1421 | if (!pegasus_workqueue) | 1455 | if (!pegasus_workqueue) |
| 1422 | return -ENOMEM; | 1456 | return -ENOMEM; |
diff --git a/drivers/usb/net/plusb.c b/drivers/usb/net/plusb.c index 89856aa0e3b8..4fe863389cb7 100644 --- a/drivers/usb/net/plusb.c +++ b/drivers/usb/net/plusb.c | |||
| @@ -127,7 +127,6 @@ static const struct usb_device_id products [] = { | |||
| 127 | MODULE_DEVICE_TABLE(usb, products); | 127 | MODULE_DEVICE_TABLE(usb, products); |
| 128 | 128 | ||
| 129 | static struct usb_driver plusb_driver = { | 129 | static struct usb_driver plusb_driver = { |
| 130 | .owner = THIS_MODULE, | ||
| 131 | .name = "plusb", | 130 | .name = "plusb", |
| 132 | .id_table = products, | 131 | .id_table = products, |
| 133 | .probe = usbnet_probe, | 132 | .probe = usbnet_probe, |
diff --git a/drivers/usb/net/rndis_host.c b/drivers/usb/net/rndis_host.c index c0ecbab6f6ba..49991ac1bf3b 100644 --- a/drivers/usb/net/rndis_host.c +++ b/drivers/usb/net/rndis_host.c | |||
| @@ -586,7 +586,6 @@ static const struct usb_device_id products [] = { | |||
| 586 | MODULE_DEVICE_TABLE(usb, products); | 586 | MODULE_DEVICE_TABLE(usb, products); |
| 587 | 587 | ||
| 588 | static struct usb_driver rndis_driver = { | 588 | static struct usb_driver rndis_driver = { |
| 589 | .owner = THIS_MODULE, | ||
| 590 | .name = "rndis_host", | 589 | .name = "rndis_host", |
| 591 | .id_table = products, | 590 | .id_table = products, |
| 592 | .probe = usbnet_probe, | 591 | .probe = usbnet_probe, |
diff --git a/drivers/usb/net/rtl8150.c b/drivers/usb/net/rtl8150.c index 787dd3591d6a..8ca52be23976 100644 --- a/drivers/usb/net/rtl8150.c +++ b/drivers/usb/net/rtl8150.c | |||
| @@ -177,7 +177,6 @@ static int rtl8150_probe(struct usb_interface *intf, | |||
| 177 | static const char driver_name [] = "rtl8150"; | 177 | static const char driver_name [] = "rtl8150"; |
| 178 | 178 | ||
| 179 | static struct usb_driver rtl8150_driver = { | 179 | static struct usb_driver rtl8150_driver = { |
| 180 | .owner = THIS_MODULE, | ||
| 181 | .name = driver_name, | 180 | .name = driver_name, |
| 182 | .probe = rtl8150_probe, | 181 | .probe = rtl8150_probe, |
| 183 | .disconnect = rtl8150_disconnect, | 182 | .disconnect = rtl8150_disconnect, |
diff --git a/drivers/usb/net/zaurus.c b/drivers/usb/net/zaurus.c index 680d13957af4..9c5ab251370c 100644 --- a/drivers/usb/net/zaurus.c +++ b/drivers/usb/net/zaurus.c | |||
| @@ -357,7 +357,6 @@ static const struct usb_device_id products [] = { | |||
| 357 | MODULE_DEVICE_TABLE(usb, products); | 357 | MODULE_DEVICE_TABLE(usb, products); |
| 358 | 358 | ||
| 359 | static struct usb_driver zaurus_driver = { | 359 | static struct usb_driver zaurus_driver = { |
| 360 | .owner = THIS_MODULE, | ||
| 361 | .name = "zaurus", | 360 | .name = "zaurus", |
| 362 | .id_table = products, | 361 | .id_table = products, |
| 363 | .probe = usbnet_probe, | 362 | .probe = usbnet_probe, |
diff --git a/drivers/usb/net/zd1201.c b/drivers/usb/net/zd1201.c index 2f52261c7cc1..f3a8e2807c3b 100644 --- a/drivers/usb/net/zd1201.c +++ b/drivers/usb/net/zd1201.c | |||
| @@ -1722,7 +1722,7 @@ static const struct iw_priv_args zd1201_private_args[] = { | |||
| 1722 | IW_PRIV_TYPE_NONE, "sethostauth" }, | 1722 | IW_PRIV_TYPE_NONE, "sethostauth" }, |
| 1723 | { ZD1201GIWHOSTAUTH, IW_PRIV_TYPE_NONE, | 1723 | { ZD1201GIWHOSTAUTH, IW_PRIV_TYPE_NONE, |
| 1724 | IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gethostauth" }, | 1724 | IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gethostauth" }, |
| 1725 | { ZD1201SIWAUTHSTA, IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, | 1725 | { ZD1201SIWAUTHSTA, IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, |
| 1726 | IW_PRIV_TYPE_NONE, "authstation" }, | 1726 | IW_PRIV_TYPE_NONE, "authstation" }, |
| 1727 | { ZD1201SIWMAXASSOC, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, | 1727 | { ZD1201SIWMAXASSOC, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, |
| 1728 | IW_PRIV_TYPE_NONE, "setmaxassoc" }, | 1728 | IW_PRIV_TYPE_NONE, "setmaxassoc" }, |
| @@ -1731,9 +1731,9 @@ static const struct iw_priv_args zd1201_private_args[] = { | |||
| 1731 | }; | 1731 | }; |
| 1732 | 1732 | ||
| 1733 | static const struct iw_handler_def zd1201_iw_handlers = { | 1733 | static const struct iw_handler_def zd1201_iw_handlers = { |
| 1734 | .num_standard = sizeof(zd1201_iw_handler)/sizeof(iw_handler), | 1734 | .num_standard = ARRAY_SIZE(zd1201_iw_handler), |
| 1735 | .num_private = sizeof(zd1201_private_handler)/sizeof(iw_handler), | 1735 | .num_private = ARRAY_SIZE(zd1201_private_handler), |
| 1736 | .num_private_args = sizeof(zd1201_private_args)/sizeof(struct iw_priv_args), | 1736 | .num_private_args = ARRAY_SIZE(zd1201_private_args), |
| 1737 | .standard = (iw_handler *)zd1201_iw_handler, | 1737 | .standard = (iw_handler *)zd1201_iw_handler, |
| 1738 | .private = (iw_handler *)zd1201_private_handler, | 1738 | .private = (iw_handler *)zd1201_private_handler, |
| 1739 | .private_args = (struct iw_priv_args *) zd1201_private_args, | 1739 | .private_args = (struct iw_priv_args *) zd1201_private_args, |
| @@ -1829,6 +1829,8 @@ static int zd1201_probe(struct usb_interface *interface, | |||
| 1829 | if (err) | 1829 | if (err) |
| 1830 | goto err_net; | 1830 | goto err_net; |
| 1831 | 1831 | ||
| 1832 | SET_NETDEV_DEV(zd->dev, &usb->dev); | ||
| 1833 | |||
| 1832 | err = register_netdev(zd->dev); | 1834 | err = register_netdev(zd->dev); |
| 1833 | if (err) | 1835 | if (err) |
| 1834 | goto err_net; | 1836 | goto err_net; |
| @@ -1923,7 +1925,6 @@ static int zd1201_resume(struct usb_interface *interface) | |||
| 1923 | #endif | 1925 | #endif |
| 1924 | 1926 | ||
| 1925 | static struct usb_driver zd1201_usb = { | 1927 | static struct usb_driver zd1201_usb = { |
| 1926 | .owner = THIS_MODULE, | ||
| 1927 | .name = "zd1201", | 1928 | .name = "zd1201", |
| 1928 | .probe = zd1201_probe, | 1929 | .probe = zd1201_probe, |
| 1929 | .disconnect = zd1201_disconnect, | 1930 | .disconnect = zd1201_disconnect, |
diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c index 1f29d8837327..dbf1f063098c 100644 --- a/drivers/usb/serial/airprime.c +++ b/drivers/usb/serial/airprime.c | |||
| @@ -23,11 +23,11 @@ static struct usb_device_id id_table [] = { | |||
| 23 | MODULE_DEVICE_TABLE(usb, id_table); | 23 | MODULE_DEVICE_TABLE(usb, id_table); |
| 24 | 24 | ||
| 25 | static struct usb_driver airprime_driver = { | 25 | static struct usb_driver airprime_driver = { |
| 26 | .owner = THIS_MODULE, | ||
| 27 | .name = "airprime", | 26 | .name = "airprime", |
| 28 | .probe = usb_serial_probe, | 27 | .probe = usb_serial_probe, |
| 29 | .disconnect = usb_serial_disconnect, | 28 | .disconnect = usb_serial_disconnect, |
| 30 | .id_table = id_table, | 29 | .id_table = id_table, |
| 30 | .no_dynamic_id = 1, | ||
| 31 | }; | 31 | }; |
| 32 | 32 | ||
| 33 | static struct usb_serial_driver airprime_device = { | 33 | static struct usb_serial_driver airprime_device = { |
diff --git a/drivers/usb/serial/anydata.c b/drivers/usb/serial/anydata.c index 18022a74a3dc..343f6f228220 100644 --- a/drivers/usb/serial/anydata.c +++ b/drivers/usb/serial/anydata.c | |||
| @@ -27,11 +27,11 @@ static int buffer_size; | |||
| 27 | static int debug; | 27 | static int debug; |
| 28 | 28 | ||
| 29 | static struct usb_driver anydata_driver = { | 29 | static struct usb_driver anydata_driver = { |
| 30 | .owner = THIS_MODULE, | ||
| 31 | .name = "anydata", | 30 | .name = "anydata", |
| 32 | .probe = usb_serial_probe, | 31 | .probe = usb_serial_probe, |
| 33 | .disconnect = usb_serial_disconnect, | 32 | .disconnect = usb_serial_disconnect, |
| 34 | .id_table = id_table, | 33 | .id_table = id_table, |
| 34 | .no_dynamic_id = 1, | ||
| 35 | }; | 35 | }; |
| 36 | 36 | ||
| 37 | static int anydata_open(struct usb_serial_port *port, struct file *filp) | 37 | static int anydata_open(struct usb_serial_port *port, struct file *filp) |
diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c index 84bc0ee4f061..4144777ea18b 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c | |||
| @@ -113,11 +113,11 @@ static struct usb_device_id id_table_combined [] = { | |||
| 113 | MODULE_DEVICE_TABLE (usb, id_table_combined); | 113 | MODULE_DEVICE_TABLE (usb, id_table_combined); |
| 114 | 114 | ||
| 115 | static struct usb_driver belkin_driver = { | 115 | static struct usb_driver belkin_driver = { |
| 116 | .owner = THIS_MODULE, | ||
| 117 | .name = "belkin", | 116 | .name = "belkin", |
| 118 | .probe = usb_serial_probe, | 117 | .probe = usb_serial_probe, |
| 119 | .disconnect = usb_serial_disconnect, | 118 | .disconnect = usb_serial_disconnect, |
| 120 | .id_table = id_table_combined, | 119 | .id_table = id_table_combined, |
| 120 | .no_dynamic_id = 1, | ||
| 121 | }; | 121 | }; |
| 122 | 122 | ||
| 123 | /* All of the device info needed for the serial converters */ | 123 | /* All of the device info needed for the serial converters */ |
diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c index c9787001cf2a..da46b351e188 100644 --- a/drivers/usb/serial/cp2101.c +++ b/drivers/usb/serial/cp2101.c | |||
| @@ -67,11 +67,11 @@ static struct usb_device_id id_table [] = { | |||
| 67 | MODULE_DEVICE_TABLE (usb, id_table); | 67 | MODULE_DEVICE_TABLE (usb, id_table); |
| 68 | 68 | ||
| 69 | static struct usb_driver cp2101_driver = { | 69 | static struct usb_driver cp2101_driver = { |
| 70 | .owner = THIS_MODULE, | ||
| 71 | .name = "cp2101", | 70 | .name = "cp2101", |
| 72 | .probe = usb_serial_probe, | 71 | .probe = usb_serial_probe, |
| 73 | .disconnect = usb_serial_disconnect, | 72 | .disconnect = usb_serial_disconnect, |
| 74 | .id_table = id_table, | 73 | .id_table = id_table, |
| 74 | .no_dynamic_id = 1, | ||
| 75 | }; | 75 | }; |
| 76 | 76 | ||
| 77 | static struct usb_serial_driver cp2101_device = { | 77 | static struct usb_serial_driver cp2101_device = { |
diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index e581e4ae8483..6d18d4eaba35 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c | |||
| @@ -76,11 +76,11 @@ static struct usb_device_id id_table [] = { | |||
| 76 | MODULE_DEVICE_TABLE (usb, id_table); | 76 | MODULE_DEVICE_TABLE (usb, id_table); |
| 77 | 77 | ||
| 78 | static struct usb_driver cyberjack_driver = { | 78 | static struct usb_driver cyberjack_driver = { |
| 79 | .owner = THIS_MODULE, | ||
| 80 | .name = "cyberjack", | 79 | .name = "cyberjack", |
| 81 | .probe = usb_serial_probe, | 80 | .probe = usb_serial_probe, |
| 82 | .disconnect = usb_serial_disconnect, | 81 | .disconnect = usb_serial_disconnect, |
| 83 | .id_table = id_table, | 82 | .id_table = id_table, |
| 83 | .no_dynamic_id = 1, | ||
| 84 | }; | 84 | }; |
| 85 | 85 | ||
| 86 | static struct usb_serial_driver cyberjack_device = { | 86 | static struct usb_serial_driver cyberjack_device = { |
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index af9290ed257b..af18355e94cc 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c | |||
| @@ -112,6 +112,7 @@ static struct usb_driver cypress_driver = { | |||
| 112 | .probe = usb_serial_probe, | 112 | .probe = usb_serial_probe, |
| 113 | .disconnect = usb_serial_disconnect, | 113 | .disconnect = usb_serial_disconnect, |
| 114 | .id_table = id_table_combined, | 114 | .id_table = id_table_combined, |
| 115 | .no_dynamic_id = 1, | ||
| 115 | }; | 116 | }; |
| 116 | 117 | ||
| 117 | struct cypress_private { | 118 | struct cypress_private { |
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index dc74644a603d..8fc414bd5b24 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c | |||
| @@ -493,11 +493,11 @@ static struct usb_device_id id_table_4 [] = { | |||
| 493 | MODULE_DEVICE_TABLE (usb, id_table_combined); | 493 | MODULE_DEVICE_TABLE (usb, id_table_combined); |
| 494 | 494 | ||
| 495 | static struct usb_driver digi_driver = { | 495 | static struct usb_driver digi_driver = { |
| 496 | .owner = THIS_MODULE, | ||
| 497 | .name = "digi_acceleport", | 496 | .name = "digi_acceleport", |
| 498 | .probe = usb_serial_probe, | 497 | .probe = usb_serial_probe, |
| 499 | .disconnect = usb_serial_disconnect, | 498 | .disconnect = usb_serial_disconnect, |
| 500 | .id_table = id_table_combined, | 499 | .id_table = id_table_combined, |
| 500 | .no_dynamic_id = 1, | ||
| 501 | }; | 501 | }; |
| 502 | 502 | ||
| 503 | 503 | ||
diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c index 0b0546dcc7b9..79a766e9ca23 100644 --- a/drivers/usb/serial/empeg.c +++ b/drivers/usb/serial/empeg.c | |||
| @@ -105,11 +105,11 @@ static struct usb_device_id id_table [] = { | |||
| 105 | MODULE_DEVICE_TABLE (usb, id_table); | 105 | MODULE_DEVICE_TABLE (usb, id_table); |
| 106 | 106 | ||
| 107 | static struct usb_driver empeg_driver = { | 107 | static struct usb_driver empeg_driver = { |
| 108 | .owner = THIS_MODULE, | ||
| 109 | .name = "empeg", | 108 | .name = "empeg", |
| 110 | .probe = usb_serial_probe, | 109 | .probe = usb_serial_probe, |
| 111 | .disconnect = usb_serial_disconnect, | 110 | .disconnect = usb_serial_disconnect, |
| 112 | .id_table = id_table, | 111 | .id_table = id_table, |
| 112 | .no_dynamic_id = 1, | ||
| 113 | }; | 113 | }; |
| 114 | 114 | ||
| 115 | static struct usb_serial_driver empeg_device = { | 115 | static struct usb_serial_driver empeg_device = { |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 06e04b442ff1..eb863b3f2d79 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
| @@ -471,12 +471,15 @@ static struct usb_device_id id_table_combined [] = { | |||
| 471 | { USB_DEVICE(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID) }, | 471 | { USB_DEVICE(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID) }, |
| 472 | { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y6_PID) }, | 472 | { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y6_PID) }, |
| 473 | { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y8_PID) }, | 473 | { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y8_PID) }, |
| 474 | { USB_DEVICE(FTDI_VID, FTDI_TERATRONIK_VCP_PID) }, | ||
| 475 | { USB_DEVICE(FTDI_VID, FTDI_TERATRONIK_D2XX_PID) }, | ||
| 474 | { USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) }, | 476 | { USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) }, |
| 475 | { USB_DEVICE(FTDI_VID, FTDI_ARTEMIS_PID) }, | 477 | { USB_DEVICE(FTDI_VID, FTDI_ARTEMIS_PID) }, |
| 476 | { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16_PID) }, | 478 | { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16_PID) }, |
| 477 | { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16HR_PID) }, | 479 | { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16HR_PID) }, |
| 478 | { USB_DEVICE(KOBIL_VID, KOBIL_CONV_B1_PID) }, | 480 | { USB_DEVICE(KOBIL_VID, KOBIL_CONV_B1_PID) }, |
| 479 | { USB_DEVICE(KOBIL_VID, KOBIL_CONV_KAAN_PID) }, | 481 | { USB_DEVICE(KOBIL_VID, KOBIL_CONV_KAAN_PID) }, |
| 482 | { USB_DEVICE(POSIFLEX_VID, POSIFLEX_PP7000_PID) }, | ||
| 480 | { }, /* Optional parameter entry */ | 483 | { }, /* Optional parameter entry */ |
| 481 | { } /* Terminating entry */ | 484 | { } /* Terminating entry */ |
| 482 | }; | 485 | }; |
| @@ -488,9 +491,10 @@ static struct usb_driver ftdi_driver = { | |||
| 488 | .probe = usb_serial_probe, | 491 | .probe = usb_serial_probe, |
| 489 | .disconnect = usb_serial_disconnect, | 492 | .disconnect = usb_serial_disconnect, |
| 490 | .id_table = id_table_combined, | 493 | .id_table = id_table_combined, |
| 494 | .no_dynamic_id = 1, | ||
| 491 | }; | 495 | }; |
| 492 | 496 | ||
| 493 | static char *ftdi_chip_name[] = { | 497 | static const char *ftdi_chip_name[] = { |
| 494 | [SIO] = "SIO", /* the serial part of FT8U100AX */ | 498 | [SIO] = "SIO", /* the serial part of FT8U100AX */ |
| 495 | [FT8U232AM] = "FT8U232AM", | 499 | [FT8U232AM] = "FT8U232AM", |
| 496 | [FT232BM] = "FT232BM", | 500 | [FT232BM] = "FT232BM", |
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 773ea3eca086..f380f9eaff71 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h | |||
| @@ -343,6 +343,13 @@ | |||
| 343 | #define XSENS_CONVERTER_7_PID 0xD38F | 343 | #define XSENS_CONVERTER_7_PID 0xD38F |
| 344 | 344 | ||
| 345 | /* | 345 | /* |
| 346 | * Teratronik product ids. | ||
| 347 | * Submitted by O. Wölfelschneider. | ||
| 348 | */ | ||
| 349 | #define FTDI_TERATRONIK_VCP_PID 0xEC88 /* Teratronik device (preferring VCP driver on windows) */ | ||
| 350 | #define FTDI_TERATRONIK_D2XX_PID 0xEC89 /* Teratronik device (preferring D2XX driver on windows) */ | ||
| 351 | |||
| 352 | /* | ||
| 346 | * Evolution Robotics products (http://www.evolution.com/). | 353 | * Evolution Robotics products (http://www.evolution.com/). |
| 347 | * Submitted by Shawn M. Lavelle. | 354 | * Submitted by Shawn M. Lavelle. |
| 348 | */ | 355 | */ |
| @@ -352,6 +359,12 @@ | |||
| 352 | /* Pyramid Computer GmbH */ | 359 | /* Pyramid Computer GmbH */ |
| 353 | #define FTDI_PYRAMID_PID 0xE6C8 /* Pyramid Appliance Display */ | 360 | #define FTDI_PYRAMID_PID 0xE6C8 /* Pyramid Appliance Display */ |
| 354 | 361 | ||
| 362 | /* | ||
| 363 | * Posiflex inc retail equipment (http://www.posiflex.com.tw) | ||
| 364 | */ | ||
| 365 | #define POSIFLEX_VID 0x0d3a /* Vendor ID */ | ||
| 366 | #define POSIFLEX_PP7000_PID 0x0300 /* PP-7000II thermal printer */ | ||
| 367 | |||
| 355 | /* Commands */ | 368 | /* Commands */ |
| 356 | #define FTDI_SIO_RESET 0 /* Reset the port */ | 369 | #define FTDI_SIO_RESET 0 /* Reset the port */ |
| 357 | #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ | 370 | #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ |
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c index 35820bda7ae1..452efce72714 100644 --- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c | |||
| @@ -222,11 +222,11 @@ static struct usb_device_id id_table [] = { | |||
| 222 | MODULE_DEVICE_TABLE (usb, id_table); | 222 | MODULE_DEVICE_TABLE (usb, id_table); |
| 223 | 223 | ||
| 224 | static struct usb_driver garmin_driver = { | 224 | static struct usb_driver garmin_driver = { |
| 225 | .owner = THIS_MODULE, | ||
| 226 | .name = "garmin_gps", | 225 | .name = "garmin_gps", |
| 227 | .probe = usb_serial_probe, | 226 | .probe = usb_serial_probe, |
| 228 | .disconnect = usb_serial_disconnect, | 227 | .disconnect = usb_serial_disconnect, |
| 229 | .id_table = id_table, | 228 | .id_table = id_table, |
| 229 | .no_dynamic_id = 1, | ||
| 230 | }; | 230 | }; |
| 231 | 231 | ||
| 232 | 232 | ||
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 53a47c31cd0e..4ddac620fc0c 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c | |||
| @@ -68,11 +68,11 @@ static int generic_probe(struct usb_interface *interface, | |||
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | static struct usb_driver generic_driver = { | 70 | static struct usb_driver generic_driver = { |
| 71 | .owner = THIS_MODULE, | ||
| 72 | .name = "usbserial_generic", | 71 | .name = "usbserial_generic", |
| 73 | .probe = generic_probe, | 72 | .probe = generic_probe, |
| 74 | .disconnect = usb_serial_disconnect, | 73 | .disconnect = usb_serial_disconnect, |
| 75 | .id_table = generic_serial_ids, | 74 | .id_table = generic_serial_ids, |
| 75 | .no_dynamic_id = 1, | ||
| 76 | }; | 76 | }; |
| 77 | #endif | 77 | #endif |
| 78 | 78 | ||
diff --git a/drivers/usb/serial/hp4x.c b/drivers/usb/serial/hp4x.c index 8eadfb705601..e9719da2aca1 100644 --- a/drivers/usb/serial/hp4x.c +++ b/drivers/usb/serial/hp4x.c | |||
| @@ -37,11 +37,11 @@ static struct usb_device_id id_table [] = { | |||
| 37 | MODULE_DEVICE_TABLE(usb, id_table); | 37 | MODULE_DEVICE_TABLE(usb, id_table); |
| 38 | 38 | ||
| 39 | static struct usb_driver hp49gp_driver = { | 39 | static struct usb_driver hp49gp_driver = { |
| 40 | .owner = THIS_MODULE, | ||
| 41 | .name = "hp4X", | 40 | .name = "hp4X", |
| 42 | .probe = usb_serial_probe, | 41 | .probe = usb_serial_probe, |
| 43 | .disconnect = usb_serial_disconnect, | 42 | .disconnect = usb_serial_disconnect, |
| 44 | .id_table = id_table, | 43 | .id_table = id_table, |
| 44 | .no_dynamic_id = 1, | ||
| 45 | }; | 45 | }; |
| 46 | 46 | ||
| 47 | static struct usb_serial_driver hp49gp_device = { | 47 | static struct usb_serial_driver hp49gp_device = { |
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index dc4c498bd1ed..faedbeb6ba49 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c | |||
| @@ -184,7 +184,7 @@ struct divisor_table_entry { | |||
| 184 | // These assume a 3.6864MHz crystal, the standard /16, and | 184 | // These assume a 3.6864MHz crystal, the standard /16, and |
| 185 | // MCR.7 = 0. | 185 | // MCR.7 = 0. |
| 186 | // | 186 | // |
| 187 | static struct divisor_table_entry divisor_table[] = { | 187 | static const struct divisor_table_entry divisor_table[] = { |
| 188 | { 50, 4608}, | 188 | { 50, 4608}, |
| 189 | { 75, 3072}, | 189 | { 75, 3072}, |
| 190 | { 110, 2095}, /* 2094.545455 => 230450 => .0217 % over */ | 190 | { 110, 2095}, /* 2094.545455 => 230450 => .0217 % over */ |
| @@ -242,11 +242,11 @@ static void edge_shutdown (struct usb_serial *serial); | |||
| 242 | #include "io_tables.h" /* all of the devices that this driver supports */ | 242 | #include "io_tables.h" /* all of the devices that this driver supports */ |
| 243 | 243 | ||
| 244 | static struct usb_driver io_driver = { | 244 | static struct usb_driver io_driver = { |
| 245 | .owner = THIS_MODULE, | ||
| 246 | .name = "io_edgeport", | 245 | .name = "io_edgeport", |
| 247 | .probe = usb_serial_probe, | 246 | .probe = usb_serial_probe, |
| 248 | .disconnect = usb_serial_disconnect, | 247 | .disconnect = usb_serial_disconnect, |
| 249 | .id_table = id_table_combined, | 248 | .id_table = id_table_combined, |
| 249 | .no_dynamic_id = 1, | ||
| 250 | }; | 250 | }; |
| 251 | 251 | ||
| 252 | /* function prototypes for all of our local functions */ | 252 | /* function prototypes for all of our local functions */ |
| @@ -2353,7 +2353,7 @@ static int calc_baud_rate_divisor (int baudrate, int *divisor) | |||
| 2353 | 2353 | ||
| 2354 | dbg("%s - %d", __FUNCTION__, baudrate); | 2354 | dbg("%s - %d", __FUNCTION__, baudrate); |
| 2355 | 2355 | ||
| 2356 | for (i = 0; i < NUM_ENTRIES(divisor_table); i++) { | 2356 | for (i = 0; i < ARRAY_SIZE(divisor_table); i++) { |
| 2357 | if ( divisor_table[i].BaudRate == baudrate ) { | 2357 | if ( divisor_table[i].BaudRate == baudrate ) { |
| 2358 | *divisor = divisor_table[i].Divisor; | 2358 | *divisor = divisor_table[i].Divisor; |
| 2359 | return 0; | 2359 | return 0; |
diff --git a/drivers/usb/serial/io_edgeport.h b/drivers/usb/serial/io_edgeport.h index 5112d7aac055..123fa8a904e6 100644 --- a/drivers/usb/serial/io_edgeport.h +++ b/drivers/usb/serial/io_edgeport.h | |||
| @@ -31,9 +31,6 @@ | |||
| 31 | #ifndef HIGH8 | 31 | #ifndef HIGH8 |
| 32 | #define HIGH8(a) ((unsigned char)((a & 0xff00) >> 8)) | 32 | #define HIGH8(a) ((unsigned char)((a & 0xff00) >> 8)) |
| 33 | #endif | 33 | #endif |
| 34 | #ifndef NUM_ENTRIES | ||
| 35 | #define NUM_ENTRIES(x) (sizeof(x)/sizeof((x)[0])) | ||
| 36 | #endif | ||
| 37 | 34 | ||
| 38 | #ifndef __KERNEL__ | 35 | #ifndef __KERNEL__ |
| 39 | #define __KERNEL__ | 36 | #define __KERNEL__ |
diff --git a/drivers/usb/serial/io_fw_boot2.h b/drivers/usb/serial/io_fw_boot2.h index c7c3a3c305fe..e3463de99de4 100644 --- a/drivers/usb/serial/io_fw_boot2.h +++ b/drivers/usb/serial/io_fw_boot2.h | |||
| @@ -537,7 +537,7 @@ static unsigned char IMAGE_ARRAY_NAME[] = { | |||
| 537 | 537 | ||
| 538 | }; | 538 | }; |
| 539 | 539 | ||
| 540 | static struct edge_firmware_version_info IMAGE_VERSION_NAME = { | 540 | static const struct edge_firmware_version_info IMAGE_VERSION_NAME = { |
| 541 | 2, 0, 3 }; // Major, Minor, Build | 541 | 2, 0, 3 }; // Major, Minor, Build |
| 542 | 542 | ||
| 543 | #undef IMAGE_VERSION_NAME | 543 | #undef IMAGE_VERSION_NAME |
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 832b6d6734c0..2edf9cabad20 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c | |||
| @@ -216,11 +216,11 @@ static struct usb_device_id id_table_combined [] = { | |||
| 216 | MODULE_DEVICE_TABLE (usb, id_table_combined); | 216 | MODULE_DEVICE_TABLE (usb, id_table_combined); |
| 217 | 217 | ||
| 218 | static struct usb_driver io_driver = { | 218 | static struct usb_driver io_driver = { |
| 219 | .owner = THIS_MODULE, | ||
| 220 | .name = "io_ti", | 219 | .name = "io_ti", |
| 221 | .probe = usb_serial_probe, | 220 | .probe = usb_serial_probe, |
| 222 | .disconnect = usb_serial_disconnect, | 221 | .disconnect = usb_serial_disconnect, |
| 223 | .id_table = id_table_combined, | 222 | .id_table = id_table_combined, |
| 223 | .no_dynamic_id = 1, | ||
| 224 | }; | 224 | }; |
| 225 | 225 | ||
| 226 | 226 | ||
| @@ -2843,7 +2843,7 @@ static struct edge_buf *edge_buf_alloc(unsigned int size) | |||
| 2843 | * Free the buffer and all associated memory. | 2843 | * Free the buffer and all associated memory. |
| 2844 | */ | 2844 | */ |
| 2845 | 2845 | ||
| 2846 | void edge_buf_free(struct edge_buf *eb) | 2846 | static void edge_buf_free(struct edge_buf *eb) |
| 2847 | { | 2847 | { |
| 2848 | if (eb) { | 2848 | if (eb) { |
| 2849 | kfree(eb->buf_buf); | 2849 | kfree(eb->buf_buf); |
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index d5d066488100..06d07cea0b70 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c | |||
| @@ -542,11 +542,11 @@ static struct usb_device_id ipaq_id_table [] = { | |||
| 542 | MODULE_DEVICE_TABLE (usb, ipaq_id_table); | 542 | MODULE_DEVICE_TABLE (usb, ipaq_id_table); |
| 543 | 543 | ||
| 544 | static struct usb_driver ipaq_driver = { | 544 | static struct usb_driver ipaq_driver = { |
| 545 | .owner = THIS_MODULE, | ||
| 546 | .name = "ipaq", | 545 | .name = "ipaq", |
| 547 | .probe = usb_serial_probe, | 546 | .probe = usb_serial_probe, |
| 548 | .disconnect = usb_serial_disconnect, | 547 | .disconnect = usb_serial_disconnect, |
| 549 | .id_table = ipaq_id_table, | 548 | .id_table = ipaq_id_table, |
| 549 | .no_dynamic_id = 1, | ||
| 550 | }; | 550 | }; |
| 551 | 551 | ||
| 552 | 552 | ||
diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c index 7744b8148bc5..2dd191f5fe76 100644 --- a/drivers/usb/serial/ipw.c +++ b/drivers/usb/serial/ipw.c | |||
| @@ -152,11 +152,11 @@ static struct usb_device_id usb_ipw_ids[] = { | |||
| 152 | MODULE_DEVICE_TABLE(usb, usb_ipw_ids); | 152 | MODULE_DEVICE_TABLE(usb, usb_ipw_ids); |
| 153 | 153 | ||
| 154 | static struct usb_driver usb_ipw_driver = { | 154 | static struct usb_driver usb_ipw_driver = { |
| 155 | .owner = THIS_MODULE, | ||
| 156 | .name = "ipwtty", | 155 | .name = "ipwtty", |
| 157 | .probe = usb_serial_probe, | 156 | .probe = usb_serial_probe, |
| 158 | .disconnect = usb_serial_disconnect, | 157 | .disconnect = usb_serial_disconnect, |
| 159 | .id_table = usb_ipw_ids, | 158 | .id_table = usb_ipw_ids, |
| 159 | .no_dynamic_id = 1, | ||
| 160 | }; | 160 | }; |
| 161 | 161 | ||
| 162 | static int debug; | 162 | static int debug; |
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c index 19f329e9bdcf..a59010421444 100644 --- a/drivers/usb/serial/ir-usb.c +++ b/drivers/usb/serial/ir-usb.c | |||
| @@ -125,11 +125,11 @@ static struct usb_device_id id_table [] = { | |||
| 125 | MODULE_DEVICE_TABLE (usb, id_table); | 125 | MODULE_DEVICE_TABLE (usb, id_table); |
| 126 | 126 | ||
| 127 | static struct usb_driver ir_driver = { | 127 | static struct usb_driver ir_driver = { |
| 128 | .owner = THIS_MODULE, | ||
| 129 | .name = "ir-usb", | 128 | .name = "ir-usb", |
| 130 | .probe = usb_serial_probe, | 129 | .probe = usb_serial_probe, |
| 131 | .disconnect = usb_serial_disconnect, | 130 | .disconnect = usb_serial_disconnect, |
| 132 | .id_table = id_table, | 131 | .id_table = id_table, |
| 132 | .no_dynamic_id = 1, | ||
| 133 | }; | 133 | }; |
| 134 | 134 | ||
| 135 | 135 | ||
diff --git a/drivers/usb/serial/keyspan.h b/drivers/usb/serial/keyspan.h index 5cfc13b5e56f..7472ed6bf626 100644 --- a/drivers/usb/serial/keyspan.h +++ b/drivers/usb/serial/keyspan.h | |||
| @@ -520,11 +520,11 @@ static struct usb_device_id keyspan_ids_combined[] = { | |||
| 520 | MODULE_DEVICE_TABLE(usb, keyspan_ids_combined); | 520 | MODULE_DEVICE_TABLE(usb, keyspan_ids_combined); |
| 521 | 521 | ||
| 522 | static struct usb_driver keyspan_driver = { | 522 | static struct usb_driver keyspan_driver = { |
| 523 | .owner = THIS_MODULE, | ||
| 524 | .name = "keyspan", | 523 | .name = "keyspan", |
| 525 | .probe = usb_serial_probe, | 524 | .probe = usb_serial_probe, |
| 526 | .disconnect = usb_serial_disconnect, | 525 | .disconnect = usb_serial_disconnect, |
| 527 | .id_table = keyspan_ids_combined, | 526 | .id_table = keyspan_ids_combined, |
| 527 | .no_dynamic_id = 1, | ||
| 528 | }; | 528 | }; |
| 529 | 529 | ||
| 530 | /* usb_device_id table for the pre-firmware download keyspan devices */ | 530 | /* usb_device_id table for the pre-firmware download keyspan devices */ |
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index cd4f48bd83b6..b0441c35f98f 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c | |||
| @@ -150,11 +150,11 @@ static struct usb_device_id id_table_combined [] = { | |||
| 150 | MODULE_DEVICE_TABLE (usb, id_table_combined); | 150 | MODULE_DEVICE_TABLE (usb, id_table_combined); |
| 151 | 151 | ||
| 152 | static struct usb_driver keyspan_pda_driver = { | 152 | static struct usb_driver keyspan_pda_driver = { |
| 153 | .owner = THIS_MODULE, | ||
| 154 | .name = "keyspan_pda", | 153 | .name = "keyspan_pda", |
| 155 | .probe = usb_serial_probe, | 154 | .probe = usb_serial_probe, |
| 156 | .disconnect = usb_serial_disconnect, | 155 | .disconnect = usb_serial_disconnect, |
| 157 | .id_table = id_table_combined, | 156 | .id_table = id_table_combined, |
| 157 | .no_dynamic_id = 1, | ||
| 158 | }; | 158 | }; |
| 159 | 159 | ||
| 160 | static struct usb_device_id id_table_std [] = { | 160 | static struct usb_device_id id_table_std [] = { |
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index a8951c0fd020..4e2f7dfb58b2 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c | |||
| @@ -116,11 +116,11 @@ static struct usb_device_id id_table [] = { | |||
| 116 | MODULE_DEVICE_TABLE (usb, id_table); | 116 | MODULE_DEVICE_TABLE (usb, id_table); |
| 117 | 117 | ||
| 118 | static struct usb_driver kl5kusb105d_driver = { | 118 | static struct usb_driver kl5kusb105d_driver = { |
| 119 | .owner = THIS_MODULE, | ||
| 120 | .name = "kl5kusb105d", | 119 | .name = "kl5kusb105d", |
| 121 | .probe = usb_serial_probe, | 120 | .probe = usb_serial_probe, |
| 122 | .disconnect = usb_serial_disconnect, | 121 | .disconnect = usb_serial_disconnect, |
| 123 | .id_table = id_table, | 122 | .id_table = id_table, |
| 123 | .no_dynamic_id = 1, | ||
| 124 | }; | 124 | }; |
| 125 | 125 | ||
| 126 | static struct usb_serial_driver kl5kusb105d_device = { | 126 | static struct usb_serial_driver kl5kusb105d_device = { |
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index 9456dd9dd136..d9c21e275130 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c | |||
| @@ -97,11 +97,11 @@ static struct usb_device_id id_table [] = { | |||
| 97 | MODULE_DEVICE_TABLE (usb, id_table); | 97 | MODULE_DEVICE_TABLE (usb, id_table); |
| 98 | 98 | ||
| 99 | static struct usb_driver kobil_driver = { | 99 | static struct usb_driver kobil_driver = { |
| 100 | .owner = THIS_MODULE, | ||
| 101 | .name = "kobil", | 100 | .name = "kobil", |
| 102 | .probe = usb_serial_probe, | 101 | .probe = usb_serial_probe, |
| 103 | .disconnect = usb_serial_disconnect, | 102 | .disconnect = usb_serial_disconnect, |
| 104 | .id_table = id_table, | 103 | .id_table = id_table, |
| 104 | .no_dynamic_id = 1, | ||
| 105 | }; | 105 | }; |
| 106 | 106 | ||
| 107 | 107 | ||
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index ca5dbadb9b7e..b6d6cab9c859 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c | |||
| @@ -125,11 +125,11 @@ static struct usb_device_id id_table_combined [] = { | |||
| 125 | MODULE_DEVICE_TABLE (usb, id_table_combined); | 125 | MODULE_DEVICE_TABLE (usb, id_table_combined); |
| 126 | 126 | ||
| 127 | static struct usb_driver mct_u232_driver = { | 127 | static struct usb_driver mct_u232_driver = { |
| 128 | .owner = THIS_MODULE, | ||
| 129 | .name = "mct_u232", | 128 | .name = "mct_u232", |
| 130 | .probe = usb_serial_probe, | 129 | .probe = usb_serial_probe, |
| 131 | .disconnect = usb_serial_disconnect, | 130 | .disconnect = usb_serial_disconnect, |
| 132 | .id_table = id_table_combined, | 131 | .id_table = id_table_combined, |
| 132 | .no_dynamic_id = 1, | ||
| 133 | }; | 133 | }; |
| 134 | 134 | ||
| 135 | static struct usb_serial_driver mct_u232_device = { | 135 | static struct usb_serial_driver mct_u232_device = { |
diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index 3caf97072ac0..762d8ff9a1e4 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c | |||
| @@ -80,11 +80,11 @@ static struct usb_device_id id_table [] = { | |||
| 80 | MODULE_DEVICE_TABLE (usb, id_table); | 80 | MODULE_DEVICE_TABLE (usb, id_table); |
| 81 | 81 | ||
| 82 | static struct usb_driver omninet_driver = { | 82 | static struct usb_driver omninet_driver = { |
| 83 | .owner = THIS_MODULE, | ||
| 84 | .name = "omninet", | 83 | .name = "omninet", |
| 85 | .probe = usb_serial_probe, | 84 | .probe = usb_serial_probe, |
| 86 | .disconnect = usb_serial_disconnect, | 85 | .disconnect = usb_serial_disconnect, |
| 87 | .id_table = id_table, | 86 | .id_table = id_table, |
| 87 | .no_dynamic_id = 1, | ||
| 88 | }; | 88 | }; |
| 89 | 89 | ||
| 90 | 90 | ||
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 7716000045b7..3fd2405304fd 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
| @@ -95,11 +95,11 @@ static struct usb_device_id option_ids[] = { | |||
| 95 | MODULE_DEVICE_TABLE(usb, option_ids); | 95 | MODULE_DEVICE_TABLE(usb, option_ids); |
| 96 | 96 | ||
| 97 | static struct usb_driver option_driver = { | 97 | static struct usb_driver option_driver = { |
| 98 | .owner = THIS_MODULE, | ||
| 99 | .name = "option", | 98 | .name = "option", |
| 100 | .probe = usb_serial_probe, | 99 | .probe = usb_serial_probe, |
| 101 | .disconnect = usb_serial_disconnect, | 100 | .disconnect = usb_serial_disconnect, |
| 102 | .id_table = option_ids, | 101 | .id_table = option_ids, |
| 102 | .no_dynamic_id = 1, | ||
| 103 | }; | 103 | }; |
| 104 | 104 | ||
| 105 | /* The card has three separate interfaces, wich the serial driver | 105 | /* The card has three separate interfaces, wich the serial driver |
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 41a45a5025b2..f03721056190 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
| @@ -82,11 +82,11 @@ static struct usb_device_id id_table [] = { | |||
| 82 | MODULE_DEVICE_TABLE (usb, id_table); | 82 | MODULE_DEVICE_TABLE (usb, id_table); |
| 83 | 83 | ||
| 84 | static struct usb_driver pl2303_driver = { | 84 | static struct usb_driver pl2303_driver = { |
| 85 | .owner = THIS_MODULE, | ||
| 86 | .name = "pl2303", | 85 | .name = "pl2303", |
| 87 | .probe = usb_serial_probe, | 86 | .probe = usb_serial_probe, |
| 88 | .disconnect = usb_serial_disconnect, | 87 | .disconnect = usb_serial_disconnect, |
| 89 | .id_table = id_table, | 88 | .id_table = id_table, |
| 89 | .no_dynamic_id = 1, | ||
| 90 | }; | 90 | }; |
| 91 | 91 | ||
| 92 | #define SET_LINE_REQUEST_TYPE 0x21 | 92 | #define SET_LINE_REQUEST_TYPE 0x21 |
| @@ -810,7 +810,7 @@ static void pl2303_update_line_status(struct usb_serial_port *port, | |||
| 810 | struct pl2303_private *priv = usb_get_serial_port_data(port); | 810 | struct pl2303_private *priv = usb_get_serial_port_data(port); |
| 811 | unsigned long flags; | 811 | unsigned long flags; |
| 812 | u8 status_idx = UART_STATE; | 812 | u8 status_idx = UART_STATE; |
| 813 | u8 length = UART_STATE; | 813 | u8 length = UART_STATE + 1; |
| 814 | 814 | ||
| 815 | if ((le16_to_cpu(port->serial->dev->descriptor.idVendor) == SIEMENS_VENDOR_ID) && | 815 | if ((le16_to_cpu(port->serial->dev->descriptor.idVendor) == SIEMENS_VENDOR_ID) && |
| 816 | (le16_to_cpu(port->serial->dev->descriptor.idProduct) == SIEMENS_PRODUCT_ID_X65 || | 816 | (le16_to_cpu(port->serial->dev->descriptor.idProduct) == SIEMENS_PRODUCT_ID_X65 || |
diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c index c22bdc0c4dfd..f0215f850d2d 100644 --- a/drivers/usb/serial/safe_serial.c +++ b/drivers/usb/serial/safe_serial.c | |||
| @@ -160,14 +160,14 @@ static struct usb_device_id id_table[] = { | |||
| 160 | MODULE_DEVICE_TABLE (usb, id_table); | 160 | MODULE_DEVICE_TABLE (usb, id_table); |
| 161 | 161 | ||
| 162 | static struct usb_driver safe_driver = { | 162 | static struct usb_driver safe_driver = { |
| 163 | .owner = THIS_MODULE, | ||
| 164 | .name = "safe_serial", | 163 | .name = "safe_serial", |
| 165 | .probe = usb_serial_probe, | 164 | .probe = usb_serial_probe, |
| 166 | .disconnect = usb_serial_disconnect, | 165 | .disconnect = usb_serial_disconnect, |
| 167 | .id_table = id_table, | 166 | .id_table = id_table, |
| 167 | .no_dynamic_id = 1, | ||
| 168 | }; | 168 | }; |
| 169 | 169 | ||
| 170 | static __u16 crc10_table[256] = { | 170 | static const __u16 crc10_table[256] = { |
| 171 | 0x000, 0x233, 0x255, 0x066, 0x299, 0x0aa, 0x0cc, 0x2ff, 0x301, 0x132, 0x154, 0x367, 0x198, 0x3ab, 0x3cd, 0x1fe, | 171 | 0x000, 0x233, 0x255, 0x066, 0x299, 0x0aa, 0x0cc, 0x2ff, 0x301, 0x132, 0x154, 0x367, 0x198, 0x3ab, 0x3cd, 0x1fe, |
| 172 | 0x031, 0x202, 0x264, 0x057, 0x2a8, 0x09b, 0x0fd, 0x2ce, 0x330, 0x103, 0x165, 0x356, 0x1a9, 0x39a, 0x3fc, 0x1cf, | 172 | 0x031, 0x202, 0x264, 0x057, 0x2a8, 0x09b, 0x0fd, 0x2ce, 0x330, 0x103, 0x165, 0x356, 0x1a9, 0x39a, 0x3fc, 0x1cf, |
| 173 | 0x062, 0x251, 0x237, 0x004, 0x2fb, 0x0c8, 0x0ae, 0x29d, 0x363, 0x150, 0x136, 0x305, 0x1fa, 0x3c9, 0x3af, 0x19c, | 173 | 0x062, 0x251, 0x237, 0x004, 0x2fb, 0x0c8, 0x0ae, 0x29d, 0x363, 0x150, 0x136, 0x305, 0x1fa, 0x3c9, 0x3af, 0x19c, |
| @@ -425,7 +425,7 @@ static int __init safe_init (void) | |||
| 425 | if (vendor || product) { | 425 | if (vendor || product) { |
| 426 | info ("vendor: %x product: %x\n", vendor, product); | 426 | info ("vendor: %x product: %x\n", vendor, product); |
| 427 | 427 | ||
| 428 | for (i = 0; i < (sizeof (id_table) / sizeof (struct usb_device_id)); i++) { | 428 | for (i = 0; i < ARRAY_SIZE(id_table); i++) { |
| 429 | if (!id_table[i].idVendor && !id_table[i].idProduct) { | 429 | if (!id_table[i].idVendor && !id_table[i].idProduct) { |
| 430 | id_table[i].idVendor = vendor; | 430 | id_table[i].idVendor = vendor; |
| 431 | id_table[i].idProduct = product; | 431 | id_table[i].idProduct = product; |
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index 205dbf7201da..abb830cb77bd 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c | |||
| @@ -248,11 +248,11 @@ static struct usb_device_id ti_id_table_combined[] = { | |||
| 248 | }; | 248 | }; |
| 249 | 249 | ||
| 250 | static struct usb_driver ti_usb_driver = { | 250 | static struct usb_driver ti_usb_driver = { |
| 251 | .owner = THIS_MODULE, | ||
| 252 | .name = "ti_usb_3410_5052", | 251 | .name = "ti_usb_3410_5052", |
| 253 | .probe = usb_serial_probe, | 252 | .probe = usb_serial_probe, |
| 254 | .disconnect = usb_serial_disconnect, | 253 | .disconnect = usb_serial_disconnect, |
| 255 | .id_table = ti_id_table_combined, | 254 | .id_table = ti_id_table_combined, |
| 255 | .no_dynamic_id = 1, | ||
| 256 | }; | 256 | }; |
| 257 | 257 | ||
| 258 | static struct usb_serial_driver ti_1port_device = { | 258 | static struct usb_serial_driver ti_1port_device = { |
| @@ -351,17 +351,14 @@ static int __init ti_init(void) | |||
| 351 | int i,j; | 351 | int i,j; |
| 352 | int ret; | 352 | int ret; |
| 353 | 353 | ||
| 354 | |||
| 355 | /* insert extra vendor and product ids */ | 354 | /* insert extra vendor and product ids */ |
| 356 | j = sizeof(ti_id_table_3410)/sizeof(struct usb_device_id) | 355 | j = ARRAY_SIZE(ti_id_table_3410) - TI_EXTRA_VID_PID_COUNT - 1; |
| 357 | - TI_EXTRA_VID_PID_COUNT - 1; | ||
| 358 | for (i=0; i<min(vendor_3410_count,product_3410_count); i++,j++) { | 356 | for (i=0; i<min(vendor_3410_count,product_3410_count); i++,j++) { |
| 359 | ti_id_table_3410[j].idVendor = vendor_3410[i]; | 357 | ti_id_table_3410[j].idVendor = vendor_3410[i]; |
| 360 | ti_id_table_3410[j].idProduct = product_3410[i]; | 358 | ti_id_table_3410[j].idProduct = product_3410[i]; |
| 361 | ti_id_table_3410[j].match_flags = USB_DEVICE_ID_MATCH_DEVICE; | 359 | ti_id_table_3410[j].match_flags = USB_DEVICE_ID_MATCH_DEVICE; |
| 362 | } | 360 | } |
| 363 | j = sizeof(ti_id_table_5052)/sizeof(struct usb_device_id) | 361 | j = ARRAY_SIZE(ti_id_table_5052) - TI_EXTRA_VID_PID_COUNT - 1; |
| 364 | - TI_EXTRA_VID_PID_COUNT - 1; | ||
| 365 | for (i=0; i<min(vendor_5052_count,product_5052_count); i++,j++) { | 362 | for (i=0; i<min(vendor_5052_count,product_5052_count); i++,j++) { |
| 366 | ti_id_table_5052[j].idVendor = vendor_5052[i]; | 363 | ti_id_table_5052[j].idVendor = vendor_5052[i]; |
| 367 | ti_id_table_5052[j].idProduct = product_5052[i]; | 364 | ti_id_table_5052[j].idProduct = product_5052[i]; |
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 0c4881d18cd5..8bc8337c99c4 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
| @@ -30,6 +30,7 @@ | |||
| 30 | #include <linux/list.h> | 30 | #include <linux/list.h> |
| 31 | #include <linux/smp_lock.h> | 31 | #include <linux/smp_lock.h> |
| 32 | #include <asm/uaccess.h> | 32 | #include <asm/uaccess.h> |
| 33 | #include <asm/semaphore.h> | ||
| 33 | #include <linux/usb.h> | 34 | #include <linux/usb.h> |
| 34 | #include "usb-serial.h" | 35 | #include "usb-serial.h" |
| 35 | #include "pl2303.h" | 36 | #include "pl2303.h" |
| @@ -42,10 +43,10 @@ | |||
| 42 | 43 | ||
| 43 | /* Driver structure we register with the USB core */ | 44 | /* Driver structure we register with the USB core */ |
| 44 | static struct usb_driver usb_serial_driver = { | 45 | static struct usb_driver usb_serial_driver = { |
| 45 | .owner = THIS_MODULE, | ||
| 46 | .name = "usbserial", | 46 | .name = "usbserial", |
| 47 | .probe = usb_serial_probe, | 47 | .probe = usb_serial_probe, |
| 48 | .disconnect = usb_serial_disconnect, | 48 | .disconnect = usb_serial_disconnect, |
| 49 | .no_dynamic_id = 1, | ||
| 49 | }; | 50 | }; |
| 50 | 51 | ||
| 51 | /* There is no MODULE_DEVICE_TABLE for usbserial.c. Instead | 52 | /* There is no MODULE_DEVICE_TABLE for usbserial.c. Instead |
| @@ -188,6 +189,11 @@ static int serial_open (struct tty_struct *tty, struct file * filp) | |||
| 188 | 189 | ||
| 189 | portNumber = tty->index - serial->minor; | 190 | portNumber = tty->index - serial->minor; |
| 190 | port = serial->port[portNumber]; | 191 | port = serial->port[portNumber]; |
| 192 | if (!port) | ||
| 193 | return -ENODEV; | ||
| 194 | |||
| 195 | if (down_interruptible(&port->sem)) | ||
| 196 | return -ERESTARTSYS; | ||
| 191 | 197 | ||
| 192 | ++port->open_count; | 198 | ++port->open_count; |
| 193 | 199 | ||
| @@ -213,6 +219,7 @@ static int serial_open (struct tty_struct *tty, struct file * filp) | |||
| 213 | goto bailout_module_put; | 219 | goto bailout_module_put; |
| 214 | } | 220 | } |
| 215 | 221 | ||
| 222 | up(&port->sem); | ||
| 216 | return 0; | 223 | return 0; |
| 217 | 224 | ||
| 218 | bailout_module_put: | 225 | bailout_module_put: |
| @@ -220,6 +227,7 @@ bailout_module_put: | |||
| 220 | bailout_kref_put: | 227 | bailout_kref_put: |
| 221 | kref_put(&serial->kref, destroy_serial); | 228 | kref_put(&serial->kref, destroy_serial); |
| 222 | port->open_count = 0; | 229 | port->open_count = 0; |
| 230 | up(&port->sem); | ||
| 223 | return retval; | 231 | return retval; |
| 224 | } | 232 | } |
| 225 | 233 | ||
| @@ -232,8 +240,10 @@ static void serial_close(struct tty_struct *tty, struct file * filp) | |||
| 232 | 240 | ||
| 233 | dbg("%s - port %d", __FUNCTION__, port->number); | 241 | dbg("%s - port %d", __FUNCTION__, port->number); |
| 234 | 242 | ||
| 243 | down(&port->sem); | ||
| 244 | |||
| 235 | if (port->open_count == 0) | 245 | if (port->open_count == 0) |
| 236 | return; | 246 | goto out; |
| 237 | 247 | ||
| 238 | --port->open_count; | 248 | --port->open_count; |
| 239 | if (port->open_count == 0) { | 249 | if (port->open_count == 0) { |
| @@ -251,6 +261,9 @@ static void serial_close(struct tty_struct *tty, struct file * filp) | |||
| 251 | } | 261 | } |
| 252 | 262 | ||
| 253 | kref_put(&port->serial->kref, destroy_serial); | 263 | kref_put(&port->serial->kref, destroy_serial); |
| 264 | |||
| 265 | out: | ||
| 266 | up(&port->sem); | ||
| 254 | } | 267 | } |
| 255 | 268 | ||
| 256 | static int serial_write (struct tty_struct * tty, const unsigned char *buf, int count) | 269 | static int serial_write (struct tty_struct * tty, const unsigned char *buf, int count) |
| @@ -258,6 +271,9 @@ static int serial_write (struct tty_struct * tty, const unsigned char *buf, int | |||
| 258 | struct usb_serial_port *port = tty->driver_data; | 271 | struct usb_serial_port *port = tty->driver_data; |
| 259 | int retval = -EINVAL; | 272 | int retval = -EINVAL; |
| 260 | 273 | ||
| 274 | if (!port) | ||
| 275 | goto exit; | ||
| 276 | |||
| 261 | dbg("%s - port %d, %d byte(s)", __FUNCTION__, port->number, count); | 277 | dbg("%s - port %d, %d byte(s)", __FUNCTION__, port->number, count); |
| 262 | 278 | ||
| 263 | if (!port->open_count) { | 279 | if (!port->open_count) { |
| @@ -277,6 +293,9 @@ static int serial_write_room (struct tty_struct *tty) | |||
| 277 | struct usb_serial_port *port = tty->driver_data; | 293 | struct usb_serial_port *port = tty->driver_data; |
| 278 | int retval = -EINVAL; | 294 | int retval = -EINVAL; |
| 279 | 295 | ||
| 296 | if (!port) | ||
| 297 | goto exit; | ||
| 298 | |||
| 280 | dbg("%s - port %d", __FUNCTION__, port->number); | 299 | dbg("%s - port %d", __FUNCTION__, port->number); |
| 281 | 300 | ||
| 282 | if (!port->open_count) { | 301 | if (!port->open_count) { |
| @@ -296,6 +315,9 @@ static int serial_chars_in_buffer (struct tty_struct *tty) | |||
| 296 | struct usb_serial_port *port = tty->driver_data; | 315 | struct usb_serial_port *port = tty->driver_data; |
| 297 | int retval = -EINVAL; | 316 | int retval = -EINVAL; |
| 298 | 317 | ||
| 318 | if (!port) | ||
| 319 | goto exit; | ||
| 320 | |||
| 299 | dbg("%s = port %d", __FUNCTION__, port->number); | 321 | dbg("%s = port %d", __FUNCTION__, port->number); |
| 300 | 322 | ||
| 301 | if (!port->open_count) { | 323 | if (!port->open_count) { |
| @@ -314,6 +336,9 @@ static void serial_throttle (struct tty_struct * tty) | |||
| 314 | { | 336 | { |
| 315 | struct usb_serial_port *port = tty->driver_data; | 337 | struct usb_serial_port *port = tty->driver_data; |
| 316 | 338 | ||
| 339 | if (!port) | ||
| 340 | return; | ||
| 341 | |||
| 317 | dbg("%s - port %d", __FUNCTION__, port->number); | 342 | dbg("%s - port %d", __FUNCTION__, port->number); |
| 318 | 343 | ||
| 319 | if (!port->open_count) { | 344 | if (!port->open_count) { |
| @@ -330,6 +355,9 @@ static void serial_unthrottle (struct tty_struct * tty) | |||
| 330 | { | 355 | { |
| 331 | struct usb_serial_port *port = tty->driver_data; | 356 | struct usb_serial_port *port = tty->driver_data; |
| 332 | 357 | ||
| 358 | if (!port) | ||
| 359 | return; | ||
| 360 | |||
| 333 | dbg("%s - port %d", __FUNCTION__, port->number); | 361 | dbg("%s - port %d", __FUNCTION__, port->number); |
| 334 | 362 | ||
| 335 | if (!port->open_count) { | 363 | if (!port->open_count) { |
| @@ -347,6 +375,9 @@ static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned in | |||
| 347 | struct usb_serial_port *port = tty->driver_data; | 375 | struct usb_serial_port *port = tty->driver_data; |
| 348 | int retval = -ENODEV; | 376 | int retval = -ENODEV; |
| 349 | 377 | ||
| 378 | if (!port) | ||
| 379 | goto exit; | ||
| 380 | |||
| 350 | dbg("%s - port %d, cmd 0x%.4x", __FUNCTION__, port->number, cmd); | 381 | dbg("%s - port %d, cmd 0x%.4x", __FUNCTION__, port->number, cmd); |
| 351 | 382 | ||
| 352 | if (!port->open_count) { | 383 | if (!port->open_count) { |
| @@ -368,6 +399,9 @@ static void serial_set_termios (struct tty_struct *tty, struct termios * old) | |||
| 368 | { | 399 | { |
| 369 | struct usb_serial_port *port = tty->driver_data; | 400 | struct usb_serial_port *port = tty->driver_data; |
| 370 | 401 | ||
| 402 | if (!port) | ||
| 403 | return; | ||
| 404 | |||
| 371 | dbg("%s - port %d", __FUNCTION__, port->number); | 405 | dbg("%s - port %d", __FUNCTION__, port->number); |
| 372 | 406 | ||
| 373 | if (!port->open_count) { | 407 | if (!port->open_count) { |
| @@ -384,6 +418,9 @@ static void serial_break (struct tty_struct *tty, int break_state) | |||
| 384 | { | 418 | { |
| 385 | struct usb_serial_port *port = tty->driver_data; | 419 | struct usb_serial_port *port = tty->driver_data; |
| 386 | 420 | ||
| 421 | if (!port) | ||
| 422 | return; | ||
| 423 | |||
| 387 | dbg("%s - port %d", __FUNCTION__, port->number); | 424 | dbg("%s - port %d", __FUNCTION__, port->number); |
| 388 | 425 | ||
| 389 | if (!port->open_count) { | 426 | if (!port->open_count) { |
| @@ -445,6 +482,9 @@ static int serial_tiocmget (struct tty_struct *tty, struct file *file) | |||
| 445 | { | 482 | { |
| 446 | struct usb_serial_port *port = tty->driver_data; | 483 | struct usb_serial_port *port = tty->driver_data; |
| 447 | 484 | ||
| 485 | if (!port) | ||
| 486 | goto exit; | ||
| 487 | |||
| 448 | dbg("%s - port %d", __FUNCTION__, port->number); | 488 | dbg("%s - port %d", __FUNCTION__, port->number); |
| 449 | 489 | ||
| 450 | if (!port->open_count) { | 490 | if (!port->open_count) { |
| @@ -464,6 +504,9 @@ static int serial_tiocmset (struct tty_struct *tty, struct file *file, | |||
| 464 | { | 504 | { |
| 465 | struct usb_serial_port *port = tty->driver_data; | 505 | struct usb_serial_port *port = tty->driver_data; |
| 466 | 506 | ||
| 507 | if (!port) | ||
| 508 | goto exit; | ||
| 509 | |||
| 467 | dbg("%s - port %d", __FUNCTION__, port->number); | 510 | dbg("%s - port %d", __FUNCTION__, port->number); |
| 468 | 511 | ||
| 469 | if (!port->open_count) { | 512 | if (!port->open_count) { |
| @@ -742,6 +785,7 @@ int usb_serial_probe(struct usb_interface *interface, | |||
| 742 | port->number = i + serial->minor; | 785 | port->number = i + serial->minor; |
| 743 | port->serial = serial; | 786 | port->serial = serial; |
| 744 | spin_lock_init(&port->lock); | 787 | spin_lock_init(&port->lock); |
| 788 | sema_init(&port->sem, 1); | ||
| 745 | INIT_WORK(&port->work, usb_serial_port_softint, port); | 789 | INIT_WORK(&port->work, usb_serial_port_softint, port); |
| 746 | serial->port[i] = port; | 790 | serial->port[i] = port; |
| 747 | } | 791 | } |
diff --git a/drivers/usb/serial/usb-serial.h b/drivers/usb/serial/usb-serial.h index 238a5a871ed6..d7d27c3385b3 100644 --- a/drivers/usb/serial/usb-serial.h +++ b/drivers/usb/serial/usb-serial.h | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | 16 | ||
| 17 | #include <linux/config.h> | 17 | #include <linux/config.h> |
| 18 | #include <linux/kref.h> | 18 | #include <linux/kref.h> |
| 19 | #include <asm/semaphore.h> | ||
| 19 | 20 | ||
| 20 | #define SERIAL_TTY_MAJOR 188 /* Nice legal number now */ | 21 | #define SERIAL_TTY_MAJOR 188 /* Nice legal number now */ |
| 21 | #define SERIAL_TTY_MINORS 255 /* loads of devices :) */ | 22 | #define SERIAL_TTY_MINORS 255 /* loads of devices :) */ |
| @@ -30,6 +31,8 @@ | |||
| 30 | * @serial: pointer back to the struct usb_serial owner of this port. | 31 | * @serial: pointer back to the struct usb_serial owner of this port. |
| 31 | * @tty: pointer to the corresponding tty for this port. | 32 | * @tty: pointer to the corresponding tty for this port. |
| 32 | * @lock: spinlock to grab when updating portions of this structure. | 33 | * @lock: spinlock to grab when updating portions of this structure. |
| 34 | * @sem: semaphore used to synchronize serial_open() and serial_close() | ||
| 35 | * access for this port. | ||
| 33 | * @number: the number of the port (the minor number). | 36 | * @number: the number of the port (the minor number). |
| 34 | * @interrupt_in_buffer: pointer to the interrupt in buffer for this port. | 37 | * @interrupt_in_buffer: pointer to the interrupt in buffer for this port. |
| 35 | * @interrupt_in_urb: pointer to the interrupt in struct urb for this port. | 38 | * @interrupt_in_urb: pointer to the interrupt in struct urb for this port. |
| @@ -60,6 +63,7 @@ struct usb_serial_port { | |||
| 60 | struct usb_serial * serial; | 63 | struct usb_serial * serial; |
| 61 | struct tty_struct * tty; | 64 | struct tty_struct * tty; |
| 62 | spinlock_t lock; | 65 | spinlock_t lock; |
| 66 | struct semaphore sem; | ||
| 63 | unsigned char number; | 67 | unsigned char number; |
| 64 | 68 | ||
| 65 | unsigned char * interrupt_in_buffer; | 69 | unsigned char * interrupt_in_buffer; |
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index a473c1c34559..49b1fbe61f25 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c | |||
| @@ -173,11 +173,11 @@ static struct usb_device_id id_table_combined [] = { | |||
| 173 | MODULE_DEVICE_TABLE (usb, id_table_combined); | 173 | MODULE_DEVICE_TABLE (usb, id_table_combined); |
| 174 | 174 | ||
| 175 | static struct usb_driver visor_driver = { | 175 | static struct usb_driver visor_driver = { |
| 176 | .owner = THIS_MODULE, | ||
| 177 | .name = "visor", | 176 | .name = "visor", |
| 178 | .probe = usb_serial_probe, | 177 | .probe = usb_serial_probe, |
| 179 | .disconnect = usb_serial_disconnect, | 178 | .disconnect = usb_serial_disconnect, |
| 180 | .id_table = id_table_combined, | 179 | .id_table = id_table_combined, |
| 180 | .no_dynamic_id = 1, | ||
| 181 | }; | 181 | }; |
| 182 | 182 | ||
| 183 | /* All of the device info needed for the Handspring Visor, and Palm 4.0 devices */ | 183 | /* All of the device info needed for the Handspring Visor, and Palm 4.0 devices */ |
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index 18c3183be769..a7c3c4734d83 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c | |||
| @@ -127,11 +127,11 @@ static struct usb_device_id id_table_combined [] = { | |||
| 127 | MODULE_DEVICE_TABLE (usb, id_table_combined); | 127 | MODULE_DEVICE_TABLE (usb, id_table_combined); |
| 128 | 128 | ||
| 129 | static struct usb_driver whiteheat_driver = { | 129 | static struct usb_driver whiteheat_driver = { |
| 130 | .owner = THIS_MODULE, | ||
| 131 | .name = "whiteheat", | 130 | .name = "whiteheat", |
| 132 | .probe = usb_serial_probe, | 131 | .probe = usb_serial_probe, |
| 133 | .disconnect = usb_serial_disconnect, | 132 | .disconnect = usb_serial_disconnect, |
| 134 | .id_table = id_table_combined, | 133 | .id_table = id_table_combined, |
| 134 | .no_dynamic_id = 1, | ||
| 135 | }; | 135 | }; |
| 136 | 136 | ||
| 137 | /* function prototypes for the Connect Tech WhiteHEAT prerenumeration device */ | 137 | /* function prototypes for the Connect Tech WhiteHEAT prerenumeration device */ |
diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig index c41d64dbb0f0..92be101feba7 100644 --- a/drivers/usb/storage/Kconfig +++ b/drivers/usb/storage/Kconfig | |||
| @@ -112,6 +112,15 @@ config USB_STORAGE_JUMPSHOT | |||
| 112 | Say Y here to include additional code to support the Lexar Jumpshot | 112 | Say Y here to include additional code to support the Lexar Jumpshot |
| 113 | USB CompactFlash reader. | 113 | USB CompactFlash reader. |
| 114 | 114 | ||
| 115 | config USB_STORAGE_ALAUDA | ||
| 116 | bool "Olympus MAUSB-10/Fuji DPC-R1 support (EXPERIMENTAL)" | ||
| 117 | depends on USB_STORAGE && EXPERIMENTAL | ||
| 118 | help | ||
| 119 | Say Y here to include additional code to support the Olympus MAUSB-10 | ||
| 120 | and Fujifilm DPC-R1 USB Card reader/writer devices. | ||
| 121 | |||
| 122 | These devices are based on the Alauda chip and support support both | ||
| 123 | XD and SmartMedia cards. | ||
| 115 | 124 | ||
| 116 | config USB_STORAGE_ONETOUCH | 125 | config USB_STORAGE_ONETOUCH |
| 117 | bool "Support OneTouch Button on Maxtor Hard Drives (EXPERIMENTAL)" | 126 | bool "Support OneTouch Button on Maxtor Hard Drives (EXPERIMENTAL)" |
| @@ -124,3 +133,17 @@ config USB_STORAGE_ONETOUCH | |||
| 124 | hard drive's as an input device. An action can be associated with | 133 | hard drive's as an input device. An action can be associated with |
| 125 | this input in any keybinding software. (e.g. gnome's keyboard short- | 134 | this input in any keybinding software. (e.g. gnome's keyboard short- |
| 126 | cuts) | 135 | cuts) |
| 136 | |||
| 137 | config USB_LIBUSUAL | ||
| 138 | bool "The shared table of common (or usual) storage devices" | ||
| 139 | depends on USB | ||
| 140 | help | ||
| 141 | This module contains a table of common (or usual) devices | ||
| 142 | for usb-storage and ub drivers, and allows to switch binding | ||
| 143 | of these devices without rebuilding modules. | ||
| 144 | |||
| 145 | Typical syntax of /etc/modprobe.conf is: | ||
| 146 | |||
| 147 | options libusual bias="ub" | ||
| 148 | |||
| 149 | If unsure, say N. | ||
diff --git a/drivers/usb/storage/Makefile b/drivers/usb/storage/Makefile index 44ab8f9978fe..8cbba22508a4 100644 --- a/drivers/usb/storage/Makefile +++ b/drivers/usb/storage/Makefile | |||
| @@ -18,7 +18,12 @@ usb-storage-obj-$(CONFIG_USB_STORAGE_DPCM) += dpcm.o | |||
| 18 | usb-storage-obj-$(CONFIG_USB_STORAGE_ISD200) += isd200.o | 18 | usb-storage-obj-$(CONFIG_USB_STORAGE_ISD200) += isd200.o |
| 19 | usb-storage-obj-$(CONFIG_USB_STORAGE_DATAFAB) += datafab.o | 19 | usb-storage-obj-$(CONFIG_USB_STORAGE_DATAFAB) += datafab.o |
| 20 | usb-storage-obj-$(CONFIG_USB_STORAGE_JUMPSHOT) += jumpshot.o | 20 | usb-storage-obj-$(CONFIG_USB_STORAGE_JUMPSHOT) += jumpshot.o |
| 21 | usb-storage-obj-$(CONFIG_USB_STORAGE_ALAUDA) += alauda.o | ||
| 21 | usb-storage-obj-$(CONFIG_USB_STORAGE_ONETOUCH) += onetouch.o | 22 | usb-storage-obj-$(CONFIG_USB_STORAGE_ONETOUCH) += onetouch.o |
| 22 | 23 | ||
| 23 | usb-storage-objs := scsiglue.o protocol.o transport.o usb.o \ | 24 | usb-storage-objs := scsiglue.o protocol.o transport.o usb.o \ |
| 24 | initializers.o $(usb-storage-obj-y) | 25 | initializers.o $(usb-storage-obj-y) |
| 26 | |||
| 27 | ifneq ($(CONFIG_USB_LIBUSUAL),) | ||
| 28 | obj-$(CONFIG_USB) += libusual.o | ||
| 29 | endif | ||
diff --git a/drivers/usb/storage/alauda.c b/drivers/usb/storage/alauda.c new file mode 100644 index 000000000000..4d3cbb12b713 --- /dev/null +++ b/drivers/usb/storage/alauda.c | |||
| @@ -0,0 +1,1119 @@ | |||
| 1 | /* | ||
| 2 | * Driver for Alauda-based card readers | ||
| 3 | * | ||
| 4 | * Current development and maintenance by: | ||
| 5 | * (c) 2005 Daniel Drake <dsd@gentoo.org> | ||
| 6 | * | ||
| 7 | * The 'Alauda' is a chip manufacturered by RATOC for OEM use. | ||
| 8 | * | ||
| 9 | * Alauda implements a vendor-specific command set to access two media reader | ||
| 10 | * ports (XD, SmartMedia). This driver converts SCSI commands to the commands | ||
| 11 | * which are accepted by these devices. | ||
| 12 | * | ||
| 13 | * The driver was developed through reverse-engineering, with the help of the | ||
| 14 | * sddr09 driver which has many similarities, and with some help from the | ||
| 15 | * (very old) vendor-supplied GPL sma03 driver. | ||
| 16 | * | ||
| 17 | * For protocol info, see http://alauda.sourceforge.net | ||
| 18 | * | ||
| 19 | * This program is free software; you can redistribute it and/or modify it | ||
| 20 | * under the terms of the GNU General Public License as published by the | ||
| 21 | * Free Software Foundation; either version 2, or (at your option) any | ||
| 22 | * later version. | ||
| 23 | * | ||
| 24 | * This program is distributed in the hope that it will be useful, but | ||
| 25 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 26 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 27 | * General Public License for more details. | ||
| 28 | * | ||
| 29 | * You should have received a copy of the GNU General Public License along | ||
| 30 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
| 31 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 32 | */ | ||
| 33 | |||
| 34 | #include <scsi/scsi.h> | ||
| 35 | #include <scsi/scsi_cmnd.h> | ||
| 36 | #include <scsi/scsi_device.h> | ||
| 37 | |||
| 38 | #include "usb.h" | ||
| 39 | #include "transport.h" | ||
| 40 | #include "protocol.h" | ||
| 41 | #include "debug.h" | ||
| 42 | #include "alauda.h" | ||
| 43 | |||
| 44 | #define short_pack(lsb,msb) ( ((u16)(lsb)) | ( ((u16)(msb))<<8 ) ) | ||
| 45 | #define LSB_of(s) ((s)&0xFF) | ||
| 46 | #define MSB_of(s) ((s)>>8) | ||
| 47 | |||
| 48 | #define MEDIA_PORT(us) us->srb->device->lun | ||
| 49 | #define MEDIA_INFO(us) ((struct alauda_info *)us->extra)->port[MEDIA_PORT(us)] | ||
| 50 | |||
| 51 | #define PBA_LO(pba) ((pba & 0xF) << 5) | ||
| 52 | #define PBA_HI(pba) (pba >> 3) | ||
| 53 | #define PBA_ZONE(pba) (pba >> 11) | ||
| 54 | |||
| 55 | /* | ||
| 56 | * Media handling | ||
| 57 | */ | ||
| 58 | |||
| 59 | struct alauda_card_info { | ||
| 60 | unsigned char id; /* id byte */ | ||
| 61 | unsigned char chipshift; /* 1<<cs bytes total capacity */ | ||
| 62 | unsigned char pageshift; /* 1<<ps bytes in a page */ | ||
| 63 | unsigned char blockshift; /* 1<<bs pages per block */ | ||
| 64 | unsigned char zoneshift; /* 1<<zs blocks per zone */ | ||
| 65 | }; | ||
| 66 | |||
| 67 | static struct alauda_card_info alauda_card_ids[] = { | ||
| 68 | /* NAND flash */ | ||
| 69 | { 0x6e, 20, 8, 4, 8}, /* 1 MB */ | ||
| 70 | { 0xe8, 20, 8, 4, 8}, /* 1 MB */ | ||
| 71 | { 0xec, 20, 8, 4, 8}, /* 1 MB */ | ||
| 72 | { 0x64, 21, 8, 4, 9}, /* 2 MB */ | ||
| 73 | { 0xea, 21, 8, 4, 9}, /* 2 MB */ | ||
| 74 | { 0x6b, 22, 9, 4, 9}, /* 4 MB */ | ||
| 75 | { 0xe3, 22, 9, 4, 9}, /* 4 MB */ | ||
| 76 | { 0xe5, 22, 9, 4, 9}, /* 4 MB */ | ||
| 77 | { 0xe6, 23, 9, 4, 10}, /* 8 MB */ | ||
| 78 | { 0x73, 24, 9, 5, 10}, /* 16 MB */ | ||
| 79 | { 0x75, 25, 9, 5, 10}, /* 32 MB */ | ||
| 80 | { 0x76, 26, 9, 5, 10}, /* 64 MB */ | ||
| 81 | { 0x79, 27, 9, 5, 10}, /* 128 MB */ | ||
| 82 | { 0x71, 28, 9, 5, 10}, /* 256 MB */ | ||
| 83 | |||
| 84 | /* MASK ROM */ | ||
| 85 | { 0x5d, 21, 9, 4, 8}, /* 2 MB */ | ||
| 86 | { 0xd5, 22, 9, 4, 9}, /* 4 MB */ | ||
| 87 | { 0xd6, 23, 9, 4, 10}, /* 8 MB */ | ||
| 88 | { 0x57, 24, 9, 4, 11}, /* 16 MB */ | ||
| 89 | { 0x58, 25, 9, 4, 12}, /* 32 MB */ | ||
| 90 | { 0,} | ||
| 91 | }; | ||
| 92 | |||
| 93 | static struct alauda_card_info *alauda_card_find_id(unsigned char id) { | ||
| 94 | int i; | ||
| 95 | |||
| 96 | for (i = 0; alauda_card_ids[i].id != 0; i++) | ||
| 97 | if (alauda_card_ids[i].id == id) | ||
| 98 | return &(alauda_card_ids[i]); | ||
| 99 | return NULL; | ||
| 100 | } | ||
| 101 | |||
| 102 | /* | ||
| 103 | * ECC computation. | ||
| 104 | */ | ||
| 105 | |||
| 106 | static unsigned char parity[256]; | ||
| 107 | static unsigned char ecc2[256]; | ||
| 108 | |||
| 109 | static void nand_init_ecc(void) { | ||
| 110 | int i, j, a; | ||
| 111 | |||
| 112 | parity[0] = 0; | ||
| 113 | for (i = 1; i < 256; i++) | ||
| 114 | parity[i] = (parity[i&(i-1)] ^ 1); | ||
| 115 | |||
| 116 | for (i = 0; i < 256; i++) { | ||
| 117 | a = 0; | ||
| 118 | for (j = 0; j < 8; j++) { | ||
| 119 | if (i & (1<<j)) { | ||
| 120 | if ((j & 1) == 0) | ||
| 121 | a ^= 0x04; | ||
| 122 | if ((j & 2) == 0) | ||
| 123 | a ^= 0x10; | ||
| 124 | if ((j & 4) == 0) | ||
| 125 | a ^= 0x40; | ||
| 126 | } | ||
| 127 | } | ||
| 128 | ecc2[i] = ~(a ^ (a<<1) ^ (parity[i] ? 0xa8 : 0)); | ||
| 129 | } | ||
| 130 | } | ||
| 131 | |||
| 132 | /* compute 3-byte ecc on 256 bytes */ | ||
| 133 | static void nand_compute_ecc(unsigned char *data, unsigned char *ecc) { | ||
| 134 | int i, j, a; | ||
| 135 | unsigned char par, bit, bits[8]; | ||
| 136 | |||
| 137 | par = 0; | ||
| 138 | for (j = 0; j < 8; j++) | ||
| 139 | bits[j] = 0; | ||
| 140 | |||
| 141 | /* collect 16 checksum bits */ | ||
| 142 | for (i = 0; i < 256; i++) { | ||
| 143 | par ^= data[i]; | ||
| 144 | bit = parity[data[i]]; | ||
| 145 | for (j = 0; j < 8; j++) | ||
| 146 | if ((i & (1<<j)) == 0) | ||
| 147 | bits[j] ^= bit; | ||
| 148 | } | ||
| 149 | |||
| 150 | /* put 4+4+4 = 12 bits in the ecc */ | ||
| 151 | a = (bits[3] << 6) + (bits[2] << 4) + (bits[1] << 2) + bits[0]; | ||
| 152 | ecc[0] = ~(a ^ (a<<1) ^ (parity[par] ? 0xaa : 0)); | ||
| 153 | |||
| 154 | a = (bits[7] << 6) + (bits[6] << 4) + (bits[5] << 2) + bits[4]; | ||
| 155 | ecc[1] = ~(a ^ (a<<1) ^ (parity[par] ? 0xaa : 0)); | ||
| 156 | |||
| 157 | ecc[2] = ecc2[par]; | ||
| 158 | } | ||
| 159 | |||
| 160 | static int nand_compare_ecc(unsigned char *data, unsigned char *ecc) { | ||
| 161 | return (data[0] == ecc[0] && data[1] == ecc[1] && data[2] == ecc[2]); | ||
| 162 | } | ||
| 163 | |||
| 164 | static void nand_store_ecc(unsigned char *data, unsigned char *ecc) { | ||
| 165 | memcpy(data, ecc, 3); | ||
| 166 | } | ||
| 167 | |||
| 168 | /* | ||
| 169 | * Alauda driver | ||
| 170 | */ | ||
| 171 | |||
| 172 | /* | ||
| 173 | * Forget our PBA <---> LBA mappings for a particular port | ||
| 174 | */ | ||
| 175 | static void alauda_free_maps (struct alauda_media_info *media_info) | ||
| 176 | { | ||
| 177 | unsigned int shift = media_info->zoneshift | ||
| 178 | + media_info->blockshift + media_info->pageshift; | ||
| 179 | unsigned int num_zones = media_info->capacity >> shift; | ||
| 180 | unsigned int i; | ||
| 181 | |||
| 182 | if (media_info->lba_to_pba != NULL) | ||
| 183 | for (i = 0; i < num_zones; i++) { | ||
| 184 | kfree(media_info->lba_to_pba[i]); | ||
| 185 | media_info->lba_to_pba[i] = NULL; | ||
| 186 | } | ||
| 187 | |||
| 188 | if (media_info->pba_to_lba != NULL) | ||
| 189 | for (i = 0; i < num_zones; i++) { | ||
| 190 | kfree(media_info->pba_to_lba[i]); | ||
| 191 | media_info->pba_to_lba[i] = NULL; | ||
| 192 | } | ||
| 193 | } | ||
| 194 | |||
| 195 | /* | ||
| 196 | * Returns 2 bytes of status data | ||
| 197 | * The first byte describes media status, and second byte describes door status | ||
| 198 | */ | ||
| 199 | static int alauda_get_media_status(struct us_data *us, unsigned char *data) | ||
| 200 | { | ||
| 201 | int rc; | ||
| 202 | unsigned char command; | ||
| 203 | |||
| 204 | if (MEDIA_PORT(us) == ALAUDA_PORT_XD) | ||
| 205 | command = ALAUDA_GET_XD_MEDIA_STATUS; | ||
| 206 | else | ||
| 207 | command = ALAUDA_GET_SM_MEDIA_STATUS; | ||
| 208 | |||
| 209 | rc = usb_stor_ctrl_transfer(us, us->recv_ctrl_pipe, | ||
| 210 | command, 0xc0, 0, 1, data, 2); | ||
| 211 | |||
| 212 | US_DEBUGP("alauda_get_media_status: Media status %02X %02X\n", | ||
| 213 | data[0], data[1]); | ||
| 214 | |||
| 215 | return rc; | ||
| 216 | } | ||
| 217 | |||
| 218 | /* | ||
| 219 | * Clears the "media was changed" bit so that we know when it changes again | ||
| 220 | * in the future. | ||
| 221 | */ | ||
| 222 | static int alauda_ack_media(struct us_data *us) | ||
| 223 | { | ||
| 224 | unsigned char command; | ||
| 225 | |||
| 226 | if (MEDIA_PORT(us) == ALAUDA_PORT_XD) | ||
| 227 | command = ALAUDA_ACK_XD_MEDIA_CHANGE; | ||
| 228 | else | ||
| 229 | command = ALAUDA_ACK_SM_MEDIA_CHANGE; | ||
| 230 | |||
| 231 | return usb_stor_ctrl_transfer(us, us->send_ctrl_pipe, | ||
| 232 | command, 0x40, 0, 1, NULL, 0); | ||
| 233 | } | ||
| 234 | |||
| 235 | /* | ||
| 236 | * Retrieves a 4-byte media signature, which indicates manufacturer, capacity, | ||
| 237 | * and some other details. | ||
| 238 | */ | ||
| 239 | static int alauda_get_media_signature(struct us_data *us, unsigned char *data) | ||
| 240 | { | ||
| 241 | unsigned char command; | ||
| 242 | |||
| 243 | if (MEDIA_PORT(us) == ALAUDA_PORT_XD) | ||
| 244 | command = ALAUDA_GET_XD_MEDIA_SIG; | ||
| 245 | else | ||
| 246 | command = ALAUDA_GET_SM_MEDIA_SIG; | ||
| 247 | |||
| 248 | return usb_stor_ctrl_transfer(us, us->recv_ctrl_pipe, | ||
| 249 | command, 0xc0, 0, 0, data, 4); | ||
| 250 | } | ||
| 251 | |||
| 252 | /* | ||
| 253 | * Resets the media status (but not the whole device?) | ||
| 254 | */ | ||
| 255 | static int alauda_reset_media(struct us_data *us) | ||
| 256 | { | ||
| 257 | unsigned char *command = us->iobuf; | ||
| 258 | |||
| 259 | memset(command, 0, 9); | ||
| 260 | command[0] = ALAUDA_BULK_CMD; | ||
| 261 | command[1] = ALAUDA_BULK_RESET_MEDIA; | ||
| 262 | command[8] = MEDIA_PORT(us); | ||
| 263 | |||
| 264 | return usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, | ||
| 265 | command, 9, NULL); | ||
| 266 | } | ||
| 267 | |||
| 268 | /* | ||
| 269 | * Examines the media and deduces capacity, etc. | ||
| 270 | */ | ||
| 271 | static int alauda_init_media(struct us_data *us) | ||
| 272 | { | ||
| 273 | unsigned char *data = us->iobuf; | ||
| 274 | int ready = 0; | ||
| 275 | struct alauda_card_info *media_info; | ||
| 276 | unsigned int num_zones; | ||
| 277 | |||
| 278 | while (ready == 0) { | ||
| 279 | msleep(20); | ||
| 280 | |||
| 281 | if (alauda_get_media_status(us, data) != USB_STOR_XFER_GOOD) | ||
| 282 | return USB_STOR_TRANSPORT_ERROR; | ||
| 283 | |||
| 284 | if (data[0] & 0x10) | ||
| 285 | ready = 1; | ||
| 286 | } | ||
| 287 | |||
| 288 | US_DEBUGP("alauda_init_media: We are ready for action!\n"); | ||
| 289 | |||
| 290 | if (alauda_ack_media(us) != USB_STOR_XFER_GOOD) | ||
| 291 | return USB_STOR_TRANSPORT_ERROR; | ||
| 292 | |||
| 293 | msleep(10); | ||
| 294 | |||
| 295 | if (alauda_get_media_status(us, data) != USB_STOR_XFER_GOOD) | ||
| 296 | return USB_STOR_TRANSPORT_ERROR; | ||
| 297 | |||
| 298 | if (data[0] != 0x14) { | ||
| 299 | US_DEBUGP("alauda_init_media: Media not ready after ack\n"); | ||
| 300 | return USB_STOR_TRANSPORT_ERROR; | ||
| 301 | } | ||
| 302 | |||
| 303 | if (alauda_get_media_signature(us, data) != USB_STOR_XFER_GOOD) | ||
| 304 | return USB_STOR_TRANSPORT_ERROR; | ||
| 305 | |||
| 306 | US_DEBUGP("alauda_init_media: Media signature: %02X %02X %02X %02X\n", | ||
| 307 | data[0], data[1], data[2], data[3]); | ||
| 308 | media_info = alauda_card_find_id(data[1]); | ||
| 309 | if (media_info == NULL) { | ||
| 310 | printk("alauda_init_media: Unrecognised media signature: " | ||
| 311 | "%02X %02X %02X %02X\n", | ||
| 312 | data[0], data[1], data[2], data[3]); | ||
| 313 | return USB_STOR_TRANSPORT_ERROR; | ||
| 314 | } | ||
| 315 | |||
| 316 | MEDIA_INFO(us).capacity = 1 << media_info->chipshift; | ||
| 317 | US_DEBUGP("Found media with capacity: %ldMB\n", | ||
| 318 | MEDIA_INFO(us).capacity >> 20); | ||
| 319 | |||
| 320 | MEDIA_INFO(us).pageshift = media_info->pageshift; | ||
| 321 | MEDIA_INFO(us).blockshift = media_info->blockshift; | ||
| 322 | MEDIA_INFO(us).zoneshift = media_info->zoneshift; | ||
| 323 | |||
| 324 | MEDIA_INFO(us).pagesize = 1 << media_info->pageshift; | ||
| 325 | MEDIA_INFO(us).blocksize = 1 << media_info->blockshift; | ||
| 326 | MEDIA_INFO(us).zonesize = 1 << media_info->zoneshift; | ||
| 327 | |||
| 328 | MEDIA_INFO(us).uzonesize = ((1 << media_info->zoneshift) / 128) * 125; | ||
| 329 | MEDIA_INFO(us).blockmask = MEDIA_INFO(us).blocksize - 1; | ||
| 330 | |||
| 331 | num_zones = MEDIA_INFO(us).capacity >> (MEDIA_INFO(us).zoneshift | ||
| 332 | + MEDIA_INFO(us).blockshift + MEDIA_INFO(us).pageshift); | ||
| 333 | MEDIA_INFO(us).pba_to_lba = kcalloc(num_zones, sizeof(u16*), GFP_NOIO); | ||
| 334 | MEDIA_INFO(us).lba_to_pba = kcalloc(num_zones, sizeof(u16*), GFP_NOIO); | ||
| 335 | |||
| 336 | if (alauda_reset_media(us) != USB_STOR_XFER_GOOD) | ||
| 337 | return USB_STOR_TRANSPORT_ERROR; | ||
| 338 | |||
| 339 | return USB_STOR_TRANSPORT_GOOD; | ||
| 340 | } | ||
| 341 | |||
| 342 | /* | ||
| 343 | * Examines the media status and does the right thing when the media has gone, | ||
| 344 | * appeared, or changed. | ||
| 345 | */ | ||
| 346 | static int alauda_check_media(struct us_data *us) | ||
| 347 | { | ||
| 348 | struct alauda_info *info = (struct alauda_info *) us->extra; | ||
| 349 | unsigned char status[2]; | ||
| 350 | int rc; | ||
| 351 | |||
| 352 | rc = alauda_get_media_status(us, status); | ||
| 353 | |||
| 354 | /* Check for no media or door open */ | ||
| 355 | if ((status[0] & 0x80) || ((status[0] & 0x1F) == 0x10) | ||
| 356 | || ((status[1] & 0x01) == 0)) { | ||
| 357 | US_DEBUGP("alauda_check_media: No media, or door open\n"); | ||
| 358 | alauda_free_maps(&MEDIA_INFO(us)); | ||
| 359 | info->sense_key = 0x02; | ||
| 360 | info->sense_asc = 0x3A; | ||
| 361 | info->sense_ascq = 0x00; | ||
| 362 | return USB_STOR_TRANSPORT_FAILED; | ||
| 363 | } | ||
| 364 | |||
| 365 | /* Check for media change */ | ||
| 366 | if (status[0] & 0x08) { | ||
| 367 | US_DEBUGP("alauda_check_media: Media change detected\n"); | ||
| 368 | alauda_free_maps(&MEDIA_INFO(us)); | ||
| 369 | alauda_init_media(us); | ||
| 370 | |||
| 371 | info->sense_key = UNIT_ATTENTION; | ||
| 372 | info->sense_asc = 0x28; | ||
| 373 | info->sense_ascq = 0x00; | ||
| 374 | return USB_STOR_TRANSPORT_FAILED; | ||
| 375 | } | ||
| 376 | |||
| 377 | return USB_STOR_TRANSPORT_GOOD; | ||
| 378 | } | ||
| 379 | |||
| 380 | /* | ||
| 381 | * Checks the status from the 2nd status register | ||
| 382 | * Returns 3 bytes of status data, only the first is known | ||
| 383 | */ | ||
| 384 | static int alauda_check_status2(struct us_data *us) | ||
| 385 | { | ||
| 386 | int rc; | ||
| 387 | unsigned char command[] = { | ||
| 388 | ALAUDA_BULK_CMD, ALAUDA_BULK_GET_STATUS2, | ||
| 389 | 0, 0, 0, 0, 3, 0, MEDIA_PORT(us) | ||
| 390 | }; | ||
| 391 | unsigned char data[3]; | ||
| 392 | |||
| 393 | rc = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, | ||
| 394 | command, 9, NULL); | ||
| 395 | if (rc != USB_STOR_XFER_GOOD) | ||
| 396 | return rc; | ||
| 397 | |||
| 398 | rc = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, | ||
| 399 | data, 3, NULL); | ||
| 400 | if (rc != USB_STOR_XFER_GOOD) | ||
| 401 | return rc; | ||
| 402 | |||
| 403 | US_DEBUGP("alauda_check_status2: %02X %02X %02X\n", data[0], data[1], data[2]); | ||
| 404 | if (data[0] & ALAUDA_STATUS_ERROR) | ||
| 405 | return USB_STOR_XFER_ERROR; | ||
| 406 | |||
| 407 | return USB_STOR_XFER_GOOD; | ||
| 408 | } | ||
| 409 | |||
| 410 | /* | ||
| 411 | * Gets the redundancy data for the first page of a PBA | ||
| 412 | * Returns 16 bytes. | ||
| 413 | */ | ||
| 414 | static int alauda_get_redu_data(struct us_data *us, u16 pba, unsigned char *data) | ||
| 415 | { | ||
| 416 | int rc; | ||
| 417 | unsigned char command[] = { | ||
| 418 | ALAUDA_BULK_CMD, ALAUDA_BULK_GET_REDU_DATA, | ||
| 419 | PBA_HI(pba), PBA_ZONE(pba), 0, PBA_LO(pba), 0, 0, MEDIA_PORT(us) | ||
| 420 | }; | ||
| 421 | |||
| 422 | rc = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, | ||
| 423 | command, 9, NULL); | ||
| 424 | if (rc != USB_STOR_XFER_GOOD) | ||
| 425 | return rc; | ||
| 426 | |||
| 427 | return usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, | ||
| 428 | data, 16, NULL); | ||
| 429 | } | ||
| 430 | |||
| 431 | /* | ||
| 432 | * Finds the first unused PBA in a zone | ||
| 433 | * Returns the absolute PBA of an unused PBA, or 0 if none found. | ||
| 434 | */ | ||
| 435 | static u16 alauda_find_unused_pba(struct alauda_media_info *info, | ||
| 436 | unsigned int zone) | ||
| 437 | { | ||
| 438 | u16 *pba_to_lba = info->pba_to_lba[zone]; | ||
| 439 | unsigned int i; | ||
| 440 | |||
| 441 | for (i = 0; i < info->zonesize; i++) | ||
| 442 | if (pba_to_lba[i] == UNDEF) | ||
| 443 | return (zone << info->zoneshift) + i; | ||
| 444 | |||
| 445 | return 0; | ||
| 446 | } | ||
| 447 | |||
| 448 | /* | ||
| 449 | * Reads the redundancy data for all PBA's in a zone | ||
| 450 | * Produces lba <--> pba mappings | ||
| 451 | */ | ||
| 452 | static int alauda_read_map(struct us_data *us, unsigned int zone) | ||
| 453 | { | ||
| 454 | unsigned char *data = us->iobuf; | ||
| 455 | int result; | ||
| 456 | int i, j; | ||
| 457 | unsigned int zonesize = MEDIA_INFO(us).zonesize; | ||
| 458 | unsigned int uzonesize = MEDIA_INFO(us).uzonesize; | ||
| 459 | unsigned int lba_offset, lba_real, blocknum; | ||
| 460 | unsigned int zone_base_lba = zone * uzonesize; | ||
| 461 | unsigned int zone_base_pba = zone * zonesize; | ||
| 462 | u16 *lba_to_pba = kcalloc(zonesize, sizeof(u16), GFP_NOIO); | ||
| 463 | u16 *pba_to_lba = kcalloc(zonesize, sizeof(u16), GFP_NOIO); | ||
| 464 | if (lba_to_pba == NULL || pba_to_lba == NULL) { | ||
| 465 | result = USB_STOR_TRANSPORT_ERROR; | ||
| 466 | goto error; | ||
| 467 | } | ||
| 468 | |||
| 469 | US_DEBUGP("alauda_read_map: Mapping blocks for zone %d\n", zone); | ||
| 470 | |||
| 471 | /* 1024 PBA's per zone */ | ||
| 472 | for (i = 0; i < zonesize; i++) | ||
| 473 | lba_to_pba[i] = pba_to_lba[i] = UNDEF; | ||
| 474 | |||
| 475 | for (i = 0; i < zonesize; i++) { | ||
| 476 | blocknum = zone_base_pba + i; | ||
| 477 | |||
| 478 | result = alauda_get_redu_data(us, blocknum, data); | ||
| 479 | if (result != USB_STOR_XFER_GOOD) { | ||
| 480 | result = USB_STOR_TRANSPORT_ERROR; | ||
| 481 | goto error; | ||
| 482 | } | ||
| 483 | |||
| 484 | /* special PBAs have control field 0^16 */ | ||
| 485 | for (j = 0; j < 16; j++) | ||
| 486 | if (data[j] != 0) | ||
| 487 | goto nonz; | ||
| 488 | pba_to_lba[i] = UNUSABLE; | ||
| 489 | US_DEBUGP("alauda_read_map: PBA %d has no logical mapping\n", blocknum); | ||
| 490 | continue; | ||
| 491 | |||
| 492 | nonz: | ||
| 493 | /* unwritten PBAs have control field FF^16 */ | ||
| 494 | for (j = 0; j < 16; j++) | ||
| 495 | if (data[j] != 0xff) | ||
| 496 | goto nonff; | ||
| 497 | continue; | ||
| 498 | |||
| 499 | nonff: | ||
| 500 | /* normal PBAs start with six FFs */ | ||
| 501 | if (j < 6) { | ||
| 502 | US_DEBUGP("alauda_read_map: PBA %d has no logical mapping: " | ||
| 503 | "reserved area = %02X%02X%02X%02X " | ||
| 504 | "data status %02X block status %02X\n", | ||
| 505 | blocknum, data[0], data[1], data[2], data[3], | ||
| 506 | data[4], data[5]); | ||
| 507 | pba_to_lba[i] = UNUSABLE; | ||
| 508 | continue; | ||
| 509 | } | ||
| 510 | |||
| 511 | if ((data[6] >> 4) != 0x01) { | ||
| 512 | US_DEBUGP("alauda_read_map: PBA %d has invalid address " | ||
| 513 | "field %02X%02X/%02X%02X\n", | ||
| 514 | blocknum, data[6], data[7], data[11], data[12]); | ||
| 515 | pba_to_lba[i] = UNUSABLE; | ||
| 516 | continue; | ||
| 517 | } | ||
| 518 | |||
| 519 | /* check even parity */ | ||
| 520 | if (parity[data[6] ^ data[7]]) { | ||
| 521 | printk("alauda_read_map: Bad parity in LBA for block %d" | ||
| 522 | " (%02X %02X)\n", i, data[6], data[7]); | ||
| 523 | pba_to_lba[i] = UNUSABLE; | ||
| 524 | continue; | ||
| 525 | } | ||
| 526 | |||
| 527 | lba_offset = short_pack(data[7], data[6]); | ||
| 528 | lba_offset = (lba_offset & 0x07FF) >> 1; | ||
| 529 | lba_real = lba_offset + zone_base_lba; | ||
| 530 | |||
| 531 | /* | ||
| 532 | * Every 1024 physical blocks ("zone"), the LBA numbers | ||
| 533 | * go back to zero, but are within a higher block of LBA's. | ||
| 534 | * Also, there is a maximum of 1000 LBA's per zone. | ||
| 535 | * In other words, in PBA 1024-2047 you will find LBA 0-999 | ||
| 536 | * which are really LBA 1000-1999. This allows for 24 bad | ||
| 537 | * or special physical blocks per zone. | ||
| 538 | */ | ||
| 539 | |||
| 540 | if (lba_offset >= uzonesize) { | ||
| 541 | printk("alauda_read_map: Bad low LBA %d for block %d\n", | ||
| 542 | lba_real, blocknum); | ||
| 543 | continue; | ||
| 544 | } | ||
| 545 | |||
| 546 | if (lba_to_pba[lba_offset] != UNDEF) { | ||
| 547 | printk("alauda_read_map: LBA %d seen for PBA %d and %d\n", | ||
| 548 | lba_real, lba_to_pba[lba_offset], blocknum); | ||
| 549 | continue; | ||
| 550 | } | ||
| 551 | |||
| 552 | pba_to_lba[i] = lba_real; | ||
| 553 | lba_to_pba[lba_offset] = blocknum; | ||
| 554 | continue; | ||
| 555 | } | ||
| 556 | |||
| 557 | MEDIA_INFO(us).lba_to_pba[zone] = lba_to_pba; | ||
| 558 | MEDIA_INFO(us).pba_to_lba[zone] = pba_to_lba; | ||
| 559 | result = 0; | ||
| 560 | goto out; | ||
| 561 | |||
| 562 | error: | ||
| 563 | kfree(lba_to_pba); | ||
| 564 | kfree(pba_to_lba); | ||
| 565 | out: | ||
| 566 | return result; | ||
| 567 | } | ||
| 568 | |||
| 569 | /* | ||
| 570 | * Checks to see whether we have already mapped a certain zone | ||
| 571 | * If we haven't, the map is generated | ||
| 572 | */ | ||
| 573 | static void alauda_ensure_map_for_zone(struct us_data *us, unsigned int zone) | ||
| 574 | { | ||
| 575 | if (MEDIA_INFO(us).lba_to_pba[zone] == NULL | ||
| 576 | || MEDIA_INFO(us).pba_to_lba[zone] == NULL) | ||
| 577 | alauda_read_map(us, zone); | ||
| 578 | } | ||
| 579 | |||
| 580 | /* | ||
| 581 | * Erases an entire block | ||
| 582 | */ | ||
| 583 | static int alauda_erase_block(struct us_data *us, u16 pba) | ||
| 584 | { | ||
| 585 | int rc; | ||
| 586 | unsigned char command[] = { | ||
| 587 | ALAUDA_BULK_CMD, ALAUDA_BULK_ERASE_BLOCK, PBA_HI(pba), | ||
| 588 | PBA_ZONE(pba), 0, PBA_LO(pba), 0x02, 0, MEDIA_PORT(us) | ||
| 589 | }; | ||
| 590 | unsigned char buf[2]; | ||
| 591 | |||
| 592 | US_DEBUGP("alauda_erase_block: Erasing PBA %d\n", pba); | ||
| 593 | |||
| 594 | rc = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, | ||
| 595 | command, 9, NULL); | ||
| 596 | if (rc != USB_STOR_XFER_GOOD) | ||
| 597 | return rc; | ||
| 598 | |||
| 599 | rc = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, | ||
| 600 | buf, 2, NULL); | ||
| 601 | if (rc != USB_STOR_XFER_GOOD) | ||
| 602 | return rc; | ||
| 603 | |||
| 604 | US_DEBUGP("alauda_erase_block: Erase result: %02X %02X\n", | ||
| 605 | buf[0], buf[1]); | ||
| 606 | return rc; | ||
| 607 | } | ||
| 608 | |||
| 609 | /* | ||
| 610 | * Reads data from a certain offset page inside a PBA, including interleaved | ||
| 611 | * redundancy data. Returns (pagesize+64)*pages bytes in data. | ||
| 612 | */ | ||
| 613 | static int alauda_read_block_raw(struct us_data *us, u16 pba, | ||
| 614 | unsigned int page, unsigned int pages, unsigned char *data) | ||
| 615 | { | ||
| 616 | int rc; | ||
| 617 | unsigned char command[] = { | ||
| 618 | ALAUDA_BULK_CMD, ALAUDA_BULK_READ_BLOCK, PBA_HI(pba), | ||
| 619 | PBA_ZONE(pba), 0, PBA_LO(pba) + page, pages, 0, MEDIA_PORT(us) | ||
| 620 | }; | ||
| 621 | |||
| 622 | US_DEBUGP("alauda_read_block: pba %d page %d count %d\n", | ||
| 623 | pba, page, pages); | ||
| 624 | |||
| 625 | rc = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, | ||
| 626 | command, 9, NULL); | ||
| 627 | if (rc != USB_STOR_XFER_GOOD) | ||
| 628 | return rc; | ||
| 629 | |||
| 630 | return usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, | ||
| 631 | data, (MEDIA_INFO(us).pagesize + 64) * pages, NULL); | ||
| 632 | } | ||
| 633 | |||
| 634 | /* | ||
| 635 | * Reads data from a certain offset page inside a PBA, excluding redundancy | ||
| 636 | * data. Returns pagesize*pages bytes in data. Note that data must be big enough | ||
| 637 | * to hold (pagesize+64)*pages bytes of data, but you can ignore those 'extra' | ||
| 638 | * trailing bytes outside this function. | ||
| 639 | */ | ||
| 640 | static int alauda_read_block(struct us_data *us, u16 pba, | ||
| 641 | unsigned int page, unsigned int pages, unsigned char *data) | ||
| 642 | { | ||
| 643 | int i, rc; | ||
| 644 | unsigned int pagesize = MEDIA_INFO(us).pagesize; | ||
| 645 | |||
| 646 | rc = alauda_read_block_raw(us, pba, page, pages, data); | ||
| 647 | if (rc != USB_STOR_XFER_GOOD) | ||
| 648 | return rc; | ||
| 649 | |||
| 650 | /* Cut out the redundancy data */ | ||
| 651 | for (i = 0; i < pages; i++) { | ||
| 652 | int dest_offset = i * pagesize; | ||
| 653 | int src_offset = i * (pagesize + 64); | ||
| 654 | memmove(data + dest_offset, data + src_offset, pagesize); | ||
| 655 | } | ||
| 656 | |||
| 657 | return rc; | ||
| 658 | } | ||
| 659 | |||
| 660 | /* | ||
| 661 | * Writes an entire block of data and checks status after write. | ||
| 662 | * Redundancy data must be already included in data. Data should be | ||
| 663 | * (pagesize+64)*blocksize bytes in length. | ||
| 664 | */ | ||
| 665 | static int alauda_write_block(struct us_data *us, u16 pba, unsigned char *data) | ||
| 666 | { | ||
| 667 | int rc; | ||
| 668 | struct alauda_info *info = (struct alauda_info *) us->extra; | ||
| 669 | unsigned char command[] = { | ||
| 670 | ALAUDA_BULK_CMD, ALAUDA_BULK_WRITE_BLOCK, PBA_HI(pba), | ||
| 671 | PBA_ZONE(pba), 0, PBA_LO(pba), 32, 0, MEDIA_PORT(us) | ||
| 672 | }; | ||
| 673 | |||
| 674 | US_DEBUGP("alauda_write_block: pba %d\n", pba); | ||
| 675 | |||
| 676 | rc = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, | ||
| 677 | command, 9, NULL); | ||
| 678 | if (rc != USB_STOR_XFER_GOOD) | ||
| 679 | return rc; | ||
| 680 | |||
| 681 | rc = usb_stor_bulk_transfer_buf(us, info->wr_ep, data, | ||
| 682 | (MEDIA_INFO(us).pagesize + 64) * MEDIA_INFO(us).blocksize, | ||
| 683 | NULL); | ||
| 684 | if (rc != USB_STOR_XFER_GOOD) | ||
| 685 | return rc; | ||
| 686 | |||
| 687 | return alauda_check_status2(us); | ||
| 688 | } | ||
| 689 | |||
| 690 | /* | ||
| 691 | * Write some data to a specific LBA. | ||
| 692 | */ | ||
| 693 | static int alauda_write_lba(struct us_data *us, u16 lba, | ||
| 694 | unsigned int page, unsigned int pages, | ||
| 695 | unsigned char *ptr, unsigned char *blockbuffer) | ||
| 696 | { | ||
| 697 | u16 pba, lbap, new_pba; | ||
| 698 | unsigned char *bptr, *cptr, *xptr; | ||
| 699 | unsigned char ecc[3]; | ||
| 700 | int i, result; | ||
| 701 | unsigned int uzonesize = MEDIA_INFO(us).uzonesize; | ||
| 702 | unsigned int zonesize = MEDIA_INFO(us).zonesize; | ||
| 703 | unsigned int pagesize = MEDIA_INFO(us).pagesize; | ||
| 704 | unsigned int blocksize = MEDIA_INFO(us).blocksize; | ||
| 705 | unsigned int lba_offset = lba % uzonesize; | ||
| 706 | unsigned int new_pba_offset; | ||
| 707 | unsigned int zone = lba / uzonesize; | ||
| 708 | |||
| 709 | alauda_ensure_map_for_zone(us, zone); | ||
| 710 | |||
| 711 | pba = MEDIA_INFO(us).lba_to_pba[zone][lba_offset]; | ||
| 712 | if (pba == 1) { | ||
| 713 | /* Maybe it is impossible to write to PBA 1. | ||
| 714 | Fake success, but don't do anything. */ | ||
| 715 | printk("alauda_write_lba: avoid writing to pba 1\n"); | ||
| 716 | return USB_STOR_TRANSPORT_GOOD; | ||
| 717 | } | ||
| 718 | |||
| 719 | new_pba = alauda_find_unused_pba(&MEDIA_INFO(us), zone); | ||
| 720 | if (!new_pba) { | ||
| 721 | printk("alauda_write_lba: Out of unused blocks\n"); | ||
| 722 | return USB_STOR_TRANSPORT_ERROR; | ||
| 723 | } | ||
| 724 | |||
| 725 | /* read old contents */ | ||
| 726 | if (pba != UNDEF) { | ||
| 727 | result = alauda_read_block_raw(us, pba, 0, | ||
| 728 | blocksize, blockbuffer); | ||
| 729 | if (result != USB_STOR_XFER_GOOD) | ||
| 730 | return result; | ||
| 731 | } else { | ||
| 732 | memset(blockbuffer, 0, blocksize * (pagesize + 64)); | ||
| 733 | } | ||
| 734 | |||
| 735 | lbap = (lba_offset << 1) | 0x1000; | ||
| 736 | if (parity[MSB_of(lbap) ^ LSB_of(lbap)]) | ||
| 737 | lbap ^= 1; | ||
| 738 | |||
| 739 | /* check old contents and fill lba */ | ||
| 740 | for (i = 0; i < blocksize; i++) { | ||
| 741 | bptr = blockbuffer + (i * (pagesize + 64)); | ||
| 742 | cptr = bptr + pagesize; | ||
| 743 | nand_compute_ecc(bptr, ecc); | ||
| 744 | if (!nand_compare_ecc(cptr+13, ecc)) { | ||
| 745 | US_DEBUGP("Warning: bad ecc in page %d- of pba %d\n", | ||
| 746 | i, pba); | ||
| 747 | nand_store_ecc(cptr+13, ecc); | ||
| 748 | } | ||
| 749 | nand_compute_ecc(bptr + (pagesize / 2), ecc); | ||
| 750 | if (!nand_compare_ecc(cptr+8, ecc)) { | ||
| 751 | US_DEBUGP("Warning: bad ecc in page %d+ of pba %d\n", | ||
| 752 | i, pba); | ||
| 753 | nand_store_ecc(cptr+8, ecc); | ||
| 754 | } | ||
| 755 | cptr[6] = cptr[11] = MSB_of(lbap); | ||
| 756 | cptr[7] = cptr[12] = LSB_of(lbap); | ||
| 757 | } | ||
| 758 | |||
| 759 | /* copy in new stuff and compute ECC */ | ||
| 760 | xptr = ptr; | ||
| 761 | for (i = page; i < page+pages; i++) { | ||
| 762 | bptr = blockbuffer + (i * (pagesize + 64)); | ||
| 763 | cptr = bptr + pagesize; | ||
| 764 | memcpy(bptr, xptr, pagesize); | ||
| 765 | xptr += pagesize; | ||
| 766 | nand_compute_ecc(bptr, ecc); | ||
| 767 | nand_store_ecc(cptr+13, ecc); | ||
| 768 | nand_compute_ecc(bptr + (pagesize / 2), ecc); | ||
| 769 | nand_store_ecc(cptr+8, ecc); | ||
| 770 | } | ||
| 771 | |||
| 772 | result = alauda_write_block(us, new_pba, blockbuffer); | ||
| 773 | if (result != USB_STOR_XFER_GOOD) | ||
| 774 | return result; | ||
| 775 | |||
| 776 | new_pba_offset = new_pba - (zone * zonesize); | ||
| 777 | MEDIA_INFO(us).pba_to_lba[zone][new_pba_offset] = lba; | ||
| 778 | MEDIA_INFO(us).lba_to_pba[zone][lba_offset] = new_pba; | ||
| 779 | US_DEBUGP("alauda_write_lba: Remapped LBA %d to PBA %d\n", | ||
| 780 | lba, new_pba); | ||
| 781 | |||
| 782 | if (pba != UNDEF) { | ||
| 783 | unsigned int pba_offset = pba - (zone * zonesize); | ||
| 784 | result = alauda_erase_block(us, pba); | ||
| 785 | if (result != USB_STOR_XFER_GOOD) | ||
| 786 | return result; | ||
| 787 | MEDIA_INFO(us).pba_to_lba[zone][pba_offset] = UNDEF; | ||
| 788 | } | ||
| 789 | |||
| 790 | return USB_STOR_TRANSPORT_GOOD; | ||
| 791 | } | ||
| 792 | |||
| 793 | /* | ||
| 794 | * Read data from a specific sector address | ||
| 795 | */ | ||
| 796 | static int alauda_read_data(struct us_data *us, unsigned long address, | ||
| 797 | unsigned int sectors) | ||
| 798 | { | ||
| 799 | unsigned char *buffer; | ||
| 800 | u16 lba, max_lba; | ||
| 801 | unsigned int page, len, index, offset; | ||
| 802 | unsigned int blockshift = MEDIA_INFO(us).blockshift; | ||
| 803 | unsigned int pageshift = MEDIA_INFO(us).pageshift; | ||
| 804 | unsigned int blocksize = MEDIA_INFO(us).blocksize; | ||
| 805 | unsigned int pagesize = MEDIA_INFO(us).pagesize; | ||
| 806 | unsigned int uzonesize = MEDIA_INFO(us).uzonesize; | ||
| 807 | int result; | ||
| 808 | |||
| 809 | /* | ||
| 810 | * Since we only read in one block at a time, we have to create | ||
| 811 | * a bounce buffer and move the data a piece at a time between the | ||
| 812 | * bounce buffer and the actual transfer buffer. | ||
| 813 | * We make this buffer big enough to hold temporary redundancy data, | ||
| 814 | * which we use when reading the data blocks. | ||
| 815 | */ | ||
| 816 | |||
| 817 | len = min(sectors, blocksize) * (pagesize + 64); | ||
| 818 | buffer = kmalloc(len, GFP_NOIO); | ||
| 819 | if (buffer == NULL) { | ||
| 820 | printk("alauda_read_data: Out of memory\n"); | ||
| 821 | return USB_STOR_TRANSPORT_ERROR; | ||
| 822 | } | ||
| 823 | |||
| 824 | /* Figure out the initial LBA and page */ | ||
| 825 | lba = address >> blockshift; | ||
| 826 | page = (address & MEDIA_INFO(us).blockmask); | ||
| 827 | max_lba = MEDIA_INFO(us).capacity >> (blockshift + pageshift); | ||
| 828 | |||
| 829 | result = USB_STOR_TRANSPORT_GOOD; | ||
| 830 | index = offset = 0; | ||
| 831 | |||
| 832 | while (sectors > 0) { | ||
| 833 | unsigned int zone = lba / uzonesize; /* integer division */ | ||
| 834 | unsigned int lba_offset = lba - (zone * uzonesize); | ||
| 835 | unsigned int pages; | ||
| 836 | u16 pba; | ||
| 837 | alauda_ensure_map_for_zone(us, zone); | ||
| 838 | |||
| 839 | /* Not overflowing capacity? */ | ||
| 840 | if (lba >= max_lba) { | ||
| 841 | US_DEBUGP("Error: Requested lba %u exceeds " | ||
| 842 | "maximum %u\n", lba, max_lba); | ||
| 843 | result = USB_STOR_TRANSPORT_ERROR; | ||
| 844 | break; | ||
| 845 | } | ||
| 846 | |||
| 847 | /* Find number of pages we can read in this block */ | ||
| 848 | pages = min(sectors, blocksize - page); | ||
| 849 | len = pages << pageshift; | ||
| 850 | |||
| 851 | /* Find where this lba lives on disk */ | ||
| 852 | pba = MEDIA_INFO(us).lba_to_pba[zone][lba_offset]; | ||
| 853 | |||
| 854 | if (pba == UNDEF) { /* this lba was never written */ | ||
| 855 | US_DEBUGP("Read %d zero pages (LBA %d) page %d\n", | ||
| 856 | pages, lba, page); | ||
| 857 | |||
| 858 | /* This is not really an error. It just means | ||
| 859 | that the block has never been written. | ||
| 860 | Instead of returning USB_STOR_TRANSPORT_ERROR | ||
| 861 | it is better to return all zero data. */ | ||
| 862 | |||
| 863 | memset(buffer, 0, len); | ||
| 864 | } else { | ||
| 865 | US_DEBUGP("Read %d pages, from PBA %d" | ||
| 866 | " (LBA %d) page %d\n", | ||
| 867 | pages, pba, lba, page); | ||
| 868 | |||
| 869 | result = alauda_read_block(us, pba, page, pages, buffer); | ||
| 870 | if (result != USB_STOR_TRANSPORT_GOOD) | ||
| 871 | break; | ||
| 872 | } | ||
| 873 | |||
| 874 | /* Store the data in the transfer buffer */ | ||
| 875 | usb_stor_access_xfer_buf(buffer, len, us->srb, | ||
| 876 | &index, &offset, TO_XFER_BUF); | ||
| 877 | |||
| 878 | page = 0; | ||
| 879 | lba++; | ||
| 880 | sectors -= pages; | ||
| 881 | } | ||
| 882 | |||
| 883 | kfree(buffer); | ||
| 884 | return result; | ||
| 885 | } | ||
| 886 | |||
| 887 | /* | ||
| 888 | * Write data to a specific sector address | ||
| 889 | */ | ||
| 890 | static int alauda_write_data(struct us_data *us, unsigned long address, | ||
| 891 | unsigned int sectors) | ||
| 892 | { | ||
| 893 | unsigned char *buffer, *blockbuffer; | ||
| 894 | unsigned int page, len, index, offset; | ||
| 895 | unsigned int blockshift = MEDIA_INFO(us).blockshift; | ||
| 896 | unsigned int pageshift = MEDIA_INFO(us).pageshift; | ||
| 897 | unsigned int blocksize = MEDIA_INFO(us).blocksize; | ||
| 898 | unsigned int pagesize = MEDIA_INFO(us).pagesize; | ||
| 899 | u16 lba, max_lba; | ||
| 900 | int result; | ||
| 901 | |||
| 902 | /* | ||
| 903 | * Since we don't write the user data directly to the device, | ||
| 904 | * we have to create a bounce buffer and move the data a piece | ||
| 905 | * at a time between the bounce buffer and the actual transfer buffer. | ||
| 906 | */ | ||
| 907 | |||
| 908 | len = min(sectors, blocksize) * pagesize; | ||
| 909 | buffer = kmalloc(len, GFP_NOIO); | ||
| 910 | if (buffer == NULL) { | ||
| 911 | printk("alauda_write_data: Out of memory\n"); | ||
| 912 | return USB_STOR_TRANSPORT_ERROR; | ||
| 913 | } | ||
| 914 | |||
| 915 | /* | ||
| 916 | * We also need a temporary block buffer, where we read in the old data, | ||
| 917 | * overwrite parts with the new data, and manipulate the redundancy data | ||
| 918 | */ | ||
| 919 | blockbuffer = kmalloc((pagesize + 64) * blocksize, GFP_NOIO); | ||
| 920 | if (blockbuffer == NULL) { | ||
| 921 | printk("alauda_write_data: Out of memory\n"); | ||
| 922 | kfree(buffer); | ||
| 923 | return USB_STOR_TRANSPORT_ERROR; | ||
| 924 | } | ||
| 925 | |||
| 926 | /* Figure out the initial LBA and page */ | ||
| 927 | lba = address >> blockshift; | ||
| 928 | page = (address & MEDIA_INFO(us).blockmask); | ||
| 929 | max_lba = MEDIA_INFO(us).capacity >> (pageshift + blockshift); | ||
| 930 | |||
| 931 | result = USB_STOR_TRANSPORT_GOOD; | ||
| 932 | index = offset = 0; | ||
| 933 | |||
| 934 | while (sectors > 0) { | ||
| 935 | /* Write as many sectors as possible in this block */ | ||
| 936 | unsigned int pages = min(sectors, blocksize - page); | ||
| 937 | len = pages << pageshift; | ||
| 938 | |||
| 939 | /* Not overflowing capacity? */ | ||
| 940 | if (lba >= max_lba) { | ||
| 941 | US_DEBUGP("alauda_write_data: Requested lba %u exceeds " | ||
| 942 | "maximum %u\n", lba, max_lba); | ||
| 943 | result = USB_STOR_TRANSPORT_ERROR; | ||
| 944 | break; | ||
| 945 | } | ||
| 946 | |||
| 947 | /* Get the data from the transfer buffer */ | ||
| 948 | usb_stor_access_xfer_buf(buffer, len, us->srb, | ||
| 949 | &index, &offset, FROM_XFER_BUF); | ||
| 950 | |||
| 951 | result = alauda_write_lba(us, lba, page, pages, buffer, | ||
| 952 | blockbuffer); | ||
| 953 | if (result != USB_STOR_TRANSPORT_GOOD) | ||
| 954 | break; | ||
| 955 | |||
| 956 | page = 0; | ||
| 957 | lba++; | ||
| 958 | sectors -= pages; | ||
| 959 | } | ||
| 960 | |||
| 961 | kfree(buffer); | ||
| 962 | kfree(blockbuffer); | ||
| 963 | return result; | ||
| 964 | } | ||
| 965 | |||
| 966 | /* | ||
| 967 | * Our interface with the rest of the world | ||
| 968 | */ | ||
| 969 | |||
| 970 | static void alauda_info_destructor(void *extra) | ||
| 971 | { | ||
| 972 | struct alauda_info *info = (struct alauda_info *) extra; | ||
| 973 | int port; | ||
| 974 | |||
| 975 | if (!info) | ||
| 976 | return; | ||
| 977 | |||
| 978 | for (port = 0; port < 2; port++) { | ||
| 979 | struct alauda_media_info *media_info = &info->port[port]; | ||
| 980 | |||
| 981 | alauda_free_maps(media_info); | ||
| 982 | kfree(media_info->lba_to_pba); | ||
| 983 | kfree(media_info->pba_to_lba); | ||
| 984 | } | ||
| 985 | } | ||
| 986 | |||
| 987 | /* | ||
| 988 | * Initialize alauda_info struct and find the data-write endpoint | ||
| 989 | */ | ||
| 990 | int init_alauda(struct us_data *us) | ||
| 991 | { | ||
| 992 | struct alauda_info *info; | ||
| 993 | struct usb_host_interface *altsetting = us->pusb_intf->cur_altsetting; | ||
| 994 | nand_init_ecc(); | ||
| 995 | |||
| 996 | us->extra = kzalloc(sizeof(struct alauda_info), GFP_NOIO); | ||
| 997 | if (!us->extra) { | ||
| 998 | US_DEBUGP("init_alauda: Gah! Can't allocate storage for" | ||
| 999 | "alauda info struct!\n"); | ||
| 1000 | return USB_STOR_TRANSPORT_ERROR; | ||
| 1001 | } | ||
| 1002 | info = (struct alauda_info *) us->extra; | ||
| 1003 | us->extra_destructor = alauda_info_destructor; | ||
| 1004 | |||
| 1005 | info->wr_ep = usb_sndbulkpipe(us->pusb_dev, | ||
| 1006 | altsetting->endpoint[0].desc.bEndpointAddress | ||
| 1007 | & USB_ENDPOINT_NUMBER_MASK); | ||
| 1008 | |||
| 1009 | return USB_STOR_TRANSPORT_GOOD; | ||
| 1010 | } | ||
| 1011 | |||
| 1012 | int alauda_transport(struct scsi_cmnd *srb, struct us_data *us) | ||
| 1013 | { | ||
| 1014 | int rc; | ||
| 1015 | struct alauda_info *info = (struct alauda_info *) us->extra; | ||
| 1016 | unsigned char *ptr = us->iobuf; | ||
| 1017 | static unsigned char inquiry_response[36] = { | ||
| 1018 | 0x00, 0x80, 0x00, 0x01, 0x1F, 0x00, 0x00, 0x00 | ||
| 1019 | }; | ||
| 1020 | |||
| 1021 | if (srb->cmnd[0] == INQUIRY) { | ||
| 1022 | US_DEBUGP("alauda_transport: INQUIRY. " | ||
| 1023 | "Returning bogus response.\n"); | ||
| 1024 | memcpy(ptr, inquiry_response, sizeof(inquiry_response)); | ||
| 1025 | fill_inquiry_response(us, ptr, 36); | ||
| 1026 | return USB_STOR_TRANSPORT_GOOD; | ||
| 1027 | } | ||
| 1028 | |||
| 1029 | if (srb->cmnd[0] == TEST_UNIT_READY) { | ||
| 1030 | US_DEBUGP("alauda_transport: TEST_UNIT_READY.\n"); | ||
| 1031 | return alauda_check_media(us); | ||
| 1032 | } | ||
| 1033 | |||
| 1034 | if (srb->cmnd[0] == READ_CAPACITY) { | ||
| 1035 | unsigned int num_zones; | ||
| 1036 | unsigned long capacity; | ||
| 1037 | |||
| 1038 | rc = alauda_check_media(us); | ||
| 1039 | if (rc != USB_STOR_TRANSPORT_GOOD) | ||
| 1040 | return rc; | ||
| 1041 | |||
| 1042 | num_zones = MEDIA_INFO(us).capacity >> (MEDIA_INFO(us).zoneshift | ||
| 1043 | + MEDIA_INFO(us).blockshift + MEDIA_INFO(us).pageshift); | ||
| 1044 | |||
| 1045 | capacity = num_zones * MEDIA_INFO(us).uzonesize | ||
| 1046 | * MEDIA_INFO(us).blocksize; | ||
| 1047 | |||
| 1048 | /* Report capacity and page size */ | ||
| 1049 | ((__be32 *) ptr)[0] = cpu_to_be32(capacity - 1); | ||
| 1050 | ((__be32 *) ptr)[1] = cpu_to_be32(512); | ||
| 1051 | |||
| 1052 | usb_stor_set_xfer_buf(ptr, 8, srb); | ||
| 1053 | return USB_STOR_TRANSPORT_GOOD; | ||
| 1054 | } | ||
| 1055 | |||
| 1056 | if (srb->cmnd[0] == READ_10) { | ||
| 1057 | unsigned int page, pages; | ||
| 1058 | |||
| 1059 | rc = alauda_check_media(us); | ||
| 1060 | if (rc != USB_STOR_TRANSPORT_GOOD) | ||
| 1061 | return rc; | ||
| 1062 | |||
| 1063 | page = short_pack(srb->cmnd[3], srb->cmnd[2]); | ||
| 1064 | page <<= 16; | ||
| 1065 | page |= short_pack(srb->cmnd[5], srb->cmnd[4]); | ||
| 1066 | pages = short_pack(srb->cmnd[8], srb->cmnd[7]); | ||
| 1067 | |||
| 1068 | US_DEBUGP("alauda_transport: READ_10: page %d pagect %d\n", | ||
| 1069 | page, pages); | ||
| 1070 | |||
| 1071 | return alauda_read_data(us, page, pages); | ||
| 1072 | } | ||
| 1073 | |||
| 1074 | if (srb->cmnd[0] == WRITE_10) { | ||
| 1075 | unsigned int page, pages; | ||
| 1076 | |||
| 1077 | rc = alauda_check_media(us); | ||
| 1078 | if (rc != USB_STOR_TRANSPORT_GOOD) | ||
| 1079 | return rc; | ||
| 1080 | |||
| 1081 | page = short_pack(srb->cmnd[3], srb->cmnd[2]); | ||
| 1082 | page <<= 16; | ||
| 1083 | page |= short_pack(srb->cmnd[5], srb->cmnd[4]); | ||
| 1084 | pages = short_pack(srb->cmnd[8], srb->cmnd[7]); | ||
| 1085 | |||
| 1086 | US_DEBUGP("alauda_transport: WRITE_10: page %d pagect %d\n", | ||
| 1087 | page, pages); | ||
| 1088 | |||
| 1089 | return alauda_write_data(us, page, pages); | ||
| 1090 | } | ||
| 1091 | |||
| 1092 | if (srb->cmnd[0] == REQUEST_SENSE) { | ||
| 1093 | US_DEBUGP("alauda_transport: REQUEST_SENSE.\n"); | ||
| 1094 | |||
| 1095 | memset(ptr, 0, 18); | ||
| 1096 | ptr[0] = 0xF0; | ||
| 1097 | ptr[2] = info->sense_key; | ||
| 1098 | ptr[7] = 11; | ||
| 1099 | ptr[12] = info->sense_asc; | ||
| 1100 | ptr[13] = info->sense_ascq; | ||
| 1101 | usb_stor_set_xfer_buf(ptr, 18, srb); | ||
| 1102 | |||
| 1103 | return USB_STOR_TRANSPORT_GOOD; | ||
| 1104 | } | ||
| 1105 | |||
| 1106 | if (srb->cmnd[0] == ALLOW_MEDIUM_REMOVAL) { | ||
| 1107 | /* sure. whatever. not like we can stop the user from popping | ||
| 1108 | the media out of the device (no locking doors, etc) */ | ||
| 1109 | return USB_STOR_TRANSPORT_GOOD; | ||
| 1110 | } | ||
| 1111 | |||
| 1112 | US_DEBUGP("alauda_transport: Gah! Unknown command: %d (0x%x)\n", | ||
| 1113 | srb->cmnd[0], srb->cmnd[0]); | ||
| 1114 | info->sense_key = 0x05; | ||
| 1115 | info->sense_asc = 0x20; | ||
| 1116 | info->sense_ascq = 0x00; | ||
| 1117 | return USB_STOR_TRANSPORT_FAILED; | ||
| 1118 | } | ||
| 1119 | |||
diff --git a/drivers/usb/storage/alauda.h b/drivers/usb/storage/alauda.h new file mode 100644 index 000000000000..a700f87d0803 --- /dev/null +++ b/drivers/usb/storage/alauda.h | |||
| @@ -0,0 +1,100 @@ | |||
| 1 | /* | ||
| 2 | * Driver for Alauda-based card readers | ||
| 3 | * | ||
| 4 | * Current development and maintenance by: | ||
| 5 | * (c) 2005 Daniel Drake <dsd@gentoo.org> | ||
| 6 | * | ||
| 7 | * See alauda.c for more explanation. | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify it | ||
| 10 | * under the terms of the GNU General Public License as published by the | ||
| 11 | * Free Software Foundation; either version 2, or (at your option) any | ||
| 12 | * later version. | ||
| 13 | * | ||
| 14 | * This program is distributed in the hope that it will be useful, but | ||
| 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 17 | * General Public License for more details. | ||
| 18 | * | ||
| 19 | * You should have received a copy of the GNU General Public License along | ||
| 20 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
| 21 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 22 | */ | ||
| 23 | |||
| 24 | #ifndef _USB_ALAUDA_H | ||
| 25 | #define _USB_ALAUDA_H | ||
| 26 | |||
| 27 | /* | ||
| 28 | * Status bytes | ||
| 29 | */ | ||
| 30 | #define ALAUDA_STATUS_ERROR 0x01 | ||
| 31 | #define ALAUDA_STATUS_READY 0x40 | ||
| 32 | |||
| 33 | /* | ||
| 34 | * Control opcodes (for request field) | ||
| 35 | */ | ||
| 36 | #define ALAUDA_GET_XD_MEDIA_STATUS 0x08 | ||
| 37 | #define ALAUDA_GET_SM_MEDIA_STATUS 0x98 | ||
| 38 | #define ALAUDA_ACK_XD_MEDIA_CHANGE 0x0a | ||
| 39 | #define ALAUDA_ACK_SM_MEDIA_CHANGE 0x9a | ||
| 40 | #define ALAUDA_GET_XD_MEDIA_SIG 0x86 | ||
| 41 | #define ALAUDA_GET_SM_MEDIA_SIG 0x96 | ||
| 42 | |||
| 43 | /* | ||
| 44 | * Bulk command identity (byte 0) | ||
| 45 | */ | ||
| 46 | #define ALAUDA_BULK_CMD 0x40 | ||
| 47 | |||
| 48 | /* | ||
| 49 | * Bulk opcodes (byte 1) | ||
| 50 | */ | ||
| 51 | #define ALAUDA_BULK_GET_REDU_DATA 0x85 | ||
| 52 | #define ALAUDA_BULK_READ_BLOCK 0x94 | ||
| 53 | #define ALAUDA_BULK_ERASE_BLOCK 0xa3 | ||
| 54 | #define ALAUDA_BULK_WRITE_BLOCK 0xb4 | ||
| 55 | #define ALAUDA_BULK_GET_STATUS2 0xb7 | ||
| 56 | #define ALAUDA_BULK_RESET_MEDIA 0xe0 | ||
| 57 | |||
| 58 | /* | ||
| 59 | * Port to operate on (byte 8) | ||
| 60 | */ | ||
| 61 | #define ALAUDA_PORT_XD 0x00 | ||
| 62 | #define ALAUDA_PORT_SM 0x01 | ||
| 63 | |||
| 64 | /* | ||
| 65 | * LBA and PBA are unsigned ints. Special values. | ||
| 66 | */ | ||
| 67 | #define UNDEF 0xffff | ||
| 68 | #define SPARE 0xfffe | ||
| 69 | #define UNUSABLE 0xfffd | ||
| 70 | |||
| 71 | int init_alauda(struct us_data *us); | ||
| 72 | int alauda_transport(struct scsi_cmnd *srb, struct us_data *us); | ||
| 73 | |||
| 74 | struct alauda_media_info { | ||
| 75 | unsigned long capacity; /* total media size in bytes */ | ||
| 76 | unsigned int pagesize; /* page size in bytes */ | ||
| 77 | unsigned int blocksize; /* number of pages per block */ | ||
| 78 | unsigned int uzonesize; /* number of usable blocks per zone */ | ||
| 79 | unsigned int zonesize; /* number of blocks per zone */ | ||
| 80 | unsigned int blockmask; /* mask to get page from address */ | ||
| 81 | |||
| 82 | unsigned char pageshift; | ||
| 83 | unsigned char blockshift; | ||
| 84 | unsigned char zoneshift; | ||
| 85 | |||
| 86 | u16 **lba_to_pba; /* logical to physical block map */ | ||
| 87 | u16 **pba_to_lba; /* physical to logical block map */ | ||
| 88 | }; | ||
| 89 | |||
| 90 | struct alauda_info { | ||
| 91 | struct alauda_media_info port[2]; | ||
| 92 | int wr_ep; /* endpoint to write data out of */ | ||
| 93 | |||
| 94 | unsigned char sense_key; | ||
| 95 | unsigned long sense_asc; /* additional sense code */ | ||
| 96 | unsigned long sense_ascq; /* additional sense code qualifier */ | ||
| 97 | }; | ||
| 98 | |||
| 99 | #endif | ||
| 100 | |||
diff --git a/drivers/usb/storage/debug.c b/drivers/usb/storage/debug.c index 5a9321705a74..01e430654a13 100644 --- a/drivers/usb/storage/debug.c +++ b/drivers/usb/storage/debug.c | |||
| @@ -132,6 +132,7 @@ void usb_stor_show_command(struct scsi_cmnd *srb) | |||
| 132 | case 0x5C: what = "READ BUFFER CAPACITY"; break; | 132 | case 0x5C: what = "READ BUFFER CAPACITY"; break; |
| 133 | case 0x5D: what = "SEND CUE SHEET"; break; | 133 | case 0x5D: what = "SEND CUE SHEET"; break; |
| 134 | case GPCMD_BLANK: what = "BLANK"; break; | 134 | case GPCMD_BLANK: what = "BLANK"; break; |
| 135 | case REPORT_LUNS: what = "REPORT LUNS"; break; | ||
| 135 | case MOVE_MEDIUM: what = "MOVE_MEDIUM or PLAY AUDIO (12)"; break; | 136 | case MOVE_MEDIUM: what = "MOVE_MEDIUM or PLAY AUDIO (12)"; break; |
| 136 | case READ_12: what = "READ_12"; break; | 137 | case READ_12: what = "READ_12"; break; |
| 137 | case WRITE_12: what = "WRITE_12"; break; | 138 | case WRITE_12: what = "WRITE_12"; break; |
diff --git a/drivers/usb/storage/initializers.h b/drivers/usb/storage/initializers.h index 7372386f33d5..4c1b2bd2e2e4 100644 --- a/drivers/usb/storage/initializers.h +++ b/drivers/usb/storage/initializers.h | |||
| @@ -45,10 +45,6 @@ | |||
| 45 | * mode */ | 45 | * mode */ |
| 46 | int usb_stor_euscsi_init(struct us_data *us); | 46 | int usb_stor_euscsi_init(struct us_data *us); |
| 47 | 47 | ||
| 48 | #ifdef CONFIG_USB_STORAGE_SDDR09 | ||
| 49 | int sddr09_init(struct us_data *us); | ||
| 50 | #endif | ||
| 51 | |||
| 52 | /* This function is required to activate all four slots on the UCR-61S2B | 48 | /* This function is required to activate all four slots on the UCR-61S2B |
| 53 | * flash reader */ | 49 | * flash reader */ |
| 54 | int usb_stor_ucr61s2b_init(struct us_data *us); | 50 | int usb_stor_ucr61s2b_init(struct us_data *us); |
diff --git a/drivers/usb/storage/libusual.c b/drivers/usb/storage/libusual.c new file mode 100644 index 000000000000..b28151d1b609 --- /dev/null +++ b/drivers/usb/storage/libusual.c | |||
| @@ -0,0 +1,266 @@ | |||
| 1 | /* | ||
| 2 | * libusual | ||
| 3 | * | ||
| 4 | * The libusual contains the table of devices common for ub and usb-storage. | ||
| 5 | */ | ||
| 6 | #include <linux/kernel.h> | ||
| 7 | #include <linux/module.h> | ||
| 8 | #include <linux/usb.h> | ||
| 9 | #include <linux/usb_usual.h> | ||
| 10 | #include <linux/vmalloc.h> | ||
| 11 | |||
| 12 | /* | ||
| 13 | */ | ||
| 14 | #define USU_MOD_FL_THREAD 1 /* Thread is running */ | ||
| 15 | #define USU_MOD_FL_PRESENT 2 /* The module is loaded */ | ||
| 16 | |||
| 17 | struct mod_status { | ||
| 18 | unsigned long fls; | ||
| 19 | }; | ||
| 20 | |||
| 21 | static struct mod_status stat[3]; | ||
| 22 | static DEFINE_SPINLOCK(usu_lock); | ||
| 23 | |||
| 24 | /* | ||
| 25 | */ | ||
| 26 | #define USB_US_DEFAULT_BIAS USB_US_TYPE_STOR | ||
| 27 | static atomic_t usu_bias = ATOMIC_INIT(USB_US_DEFAULT_BIAS); | ||
| 28 | |||
| 29 | #define BIAS_NAME_SIZE (sizeof("usb-storage")) | ||
| 30 | static const char *bias_names[3] = { "none", "usb-storage", "ub" }; | ||
| 31 | |||
| 32 | static DECLARE_MUTEX_LOCKED(usu_init_notify); | ||
| 33 | static DECLARE_COMPLETION(usu_end_notify); | ||
| 34 | static atomic_t total_threads = ATOMIC_INIT(0); | ||
| 35 | |||
| 36 | static int usu_probe_thread(void *arg); | ||
| 37 | |||
| 38 | /* | ||
| 39 | * The table. | ||
| 40 | */ | ||
| 41 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
| 42 | vendorName, productName,useProtocol, useTransport, \ | ||
| 43 | initFunction, flags) \ | ||
| 44 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax), \ | ||
| 45 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } | ||
| 46 | |||
| 47 | #define USUAL_DEV(useProto, useTrans, useType) \ | ||
| 48 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \ | ||
| 49 | .driver_info = ((useType)<<24) } | ||
| 50 | |||
| 51 | struct usb_device_id storage_usb_ids [] = { | ||
| 52 | # include "unusual_devs.h" | ||
| 53 | { } /* Terminating entry */ | ||
| 54 | }; | ||
| 55 | |||
| 56 | #undef USUAL_DEV | ||
| 57 | #undef UNUSUAL_DEV | ||
| 58 | |||
| 59 | MODULE_DEVICE_TABLE(usb, storage_usb_ids); | ||
| 60 | EXPORT_SYMBOL_GPL(storage_usb_ids); | ||
| 61 | |||
| 62 | /* | ||
| 63 | * @type: the module type as an integer | ||
| 64 | */ | ||
| 65 | void usb_usual_set_present(int type) | ||
| 66 | { | ||
| 67 | struct mod_status *st; | ||
| 68 | unsigned long flags; | ||
| 69 | |||
| 70 | if (type <= 0 || type >= 3) | ||
| 71 | return; | ||
| 72 | st = &stat[type]; | ||
| 73 | spin_lock_irqsave(&usu_lock, flags); | ||
| 74 | st->fls |= USU_MOD_FL_PRESENT; | ||
| 75 | spin_unlock_irqrestore(&usu_lock, flags); | ||
| 76 | } | ||
| 77 | EXPORT_SYMBOL_GPL(usb_usual_set_present); | ||
| 78 | |||
| 79 | void usb_usual_clear_present(int type) | ||
| 80 | { | ||
| 81 | struct mod_status *st; | ||
| 82 | unsigned long flags; | ||
| 83 | |||
| 84 | if (type <= 0 || type >= 3) | ||
| 85 | return; | ||
| 86 | st = &stat[type]; | ||
| 87 | spin_lock_irqsave(&usu_lock, flags); | ||
| 88 | st->fls &= ~USU_MOD_FL_PRESENT; | ||
| 89 | spin_unlock_irqrestore(&usu_lock, flags); | ||
| 90 | } | ||
| 91 | EXPORT_SYMBOL_GPL(usb_usual_clear_present); | ||
| 92 | |||
| 93 | /* | ||
| 94 | * Match the calling driver type against the table. | ||
| 95 | * Returns: 0 if the device matches. | ||
| 96 | */ | ||
| 97 | int usb_usual_check_type(const struct usb_device_id *id, int caller_type) | ||
| 98 | { | ||
| 99 | int id_type = USB_US_TYPE(id->driver_info); | ||
| 100 | |||
| 101 | if (caller_type <= 0 || caller_type >= 3) | ||
| 102 | return -EINVAL; | ||
| 103 | |||
| 104 | /* Drivers grab fixed assignment devices */ | ||
| 105 | if (id_type == caller_type) | ||
| 106 | return 0; | ||
| 107 | /* Drivers grab devices biased to them */ | ||
| 108 | if (id_type == USB_US_TYPE_NONE && caller_type == atomic_read(&usu_bias)) | ||
| 109 | return 0; | ||
| 110 | return -ENODEV; | ||
| 111 | } | ||
| 112 | EXPORT_SYMBOL_GPL(usb_usual_check_type); | ||
| 113 | |||
| 114 | /* | ||
| 115 | */ | ||
| 116 | static int usu_probe(struct usb_interface *intf, | ||
| 117 | const struct usb_device_id *id) | ||
| 118 | { | ||
| 119 | int type; | ||
| 120 | int rc; | ||
| 121 | unsigned long flags; | ||
| 122 | |||
| 123 | type = USB_US_TYPE(id->driver_info); | ||
| 124 | if (type == 0) | ||
| 125 | type = atomic_read(&usu_bias); | ||
| 126 | |||
| 127 | spin_lock_irqsave(&usu_lock, flags); | ||
| 128 | if ((stat[type].fls & (USU_MOD_FL_THREAD|USU_MOD_FL_PRESENT)) != 0) { | ||
| 129 | spin_unlock_irqrestore(&usu_lock, flags); | ||
| 130 | return -ENXIO; | ||
| 131 | } | ||
| 132 | stat[type].fls |= USU_MOD_FL_THREAD; | ||
| 133 | spin_unlock_irqrestore(&usu_lock, flags); | ||
| 134 | |||
| 135 | rc = kernel_thread(usu_probe_thread, (void*)type, CLONE_VM); | ||
| 136 | if (rc < 0) { | ||
| 137 | printk(KERN_WARNING "libusual: " | ||
| 138 | "Unable to start the thread for %s: %d\n", | ||
| 139 | bias_names[type], rc); | ||
| 140 | spin_lock_irqsave(&usu_lock, flags); | ||
| 141 | stat[type].fls &= ~USU_MOD_FL_THREAD; | ||
| 142 | spin_unlock_irqrestore(&usu_lock, flags); | ||
| 143 | return rc; /* Not being -ENXIO causes a message printed */ | ||
| 144 | } | ||
| 145 | atomic_inc(&total_threads); | ||
| 146 | |||
| 147 | return -ENXIO; | ||
| 148 | } | ||
| 149 | |||
| 150 | static void usu_disconnect(struct usb_interface *intf) | ||
| 151 | { | ||
| 152 | ; /* We should not be here. */ | ||
| 153 | } | ||
| 154 | |||
| 155 | static struct usb_driver usu_driver = { | ||
| 156 | .name = "libusual", | ||
| 157 | .probe = usu_probe, | ||
| 158 | .disconnect = usu_disconnect, | ||
| 159 | .id_table = storage_usb_ids, | ||
| 160 | }; | ||
| 161 | |||
| 162 | /* | ||
| 163 | * A whole new thread for a purpose of request_module seems quite stupid. | ||
| 164 | * The request_module forks once inside again. However, if we attempt | ||
| 165 | * to load a storage module from our own modprobe thread, that module | ||
| 166 | * references our symbols, which cannot be resolved until our module is | ||
| 167 | * initialized. I wish there was a way to wait for the end of initialization. | ||
| 168 | * The module notifier reports MODULE_STATE_COMING only. | ||
| 169 | * So, we wait until module->init ends as the next best thing. | ||
| 170 | */ | ||
| 171 | static int usu_probe_thread(void *arg) | ||
| 172 | { | ||
| 173 | int type = (unsigned long) arg; | ||
| 174 | struct mod_status *st = &stat[type]; | ||
| 175 | int rc; | ||
| 176 | unsigned long flags; | ||
| 177 | |||
| 178 | daemonize("libusual_%d", type); /* "usb-storage" is kinda too long */ | ||
| 179 | |||
| 180 | /* A completion does not work here because it's counted. */ | ||
| 181 | down(&usu_init_notify); | ||
| 182 | up(&usu_init_notify); | ||
| 183 | |||
| 184 | rc = request_module(bias_names[type]); | ||
| 185 | spin_lock_irqsave(&usu_lock, flags); | ||
| 186 | if (rc == 0 && (st->fls & USU_MOD_FL_PRESENT) == 0) { | ||
| 187 | /* | ||
| 188 | * This should not happen, but let us keep tabs on it. | ||
| 189 | */ | ||
| 190 | printk(KERN_NOTICE "libusual: " | ||
| 191 | "modprobe for %s succeeded, but module is not present\n", | ||
| 192 | bias_names[type]); | ||
| 193 | } | ||
| 194 | st->fls &= ~USU_MOD_FL_THREAD; | ||
| 195 | spin_unlock_irqrestore(&usu_lock, flags); | ||
| 196 | |||
| 197 | complete_and_exit(&usu_end_notify, 0); | ||
| 198 | } | ||
| 199 | |||
| 200 | /* | ||
| 201 | */ | ||
| 202 | static int __init usb_usual_init(void) | ||
| 203 | { | ||
| 204 | int rc; | ||
| 205 | |||
| 206 | rc = usb_register(&usu_driver); | ||
| 207 | up(&usu_init_notify); | ||
| 208 | return rc; | ||
| 209 | } | ||
| 210 | |||
| 211 | static void __exit usb_usual_exit(void) | ||
| 212 | { | ||
| 213 | /* | ||
| 214 | * We do not check for any drivers present, because | ||
| 215 | * they keep us pinned with symbol references. | ||
| 216 | */ | ||
| 217 | |||
| 218 | usb_deregister(&usu_driver); | ||
| 219 | |||
| 220 | while (atomic_read(&total_threads) > 0) { | ||
| 221 | wait_for_completion(&usu_end_notify); | ||
| 222 | atomic_dec(&total_threads); | ||
| 223 | } | ||
| 224 | } | ||
| 225 | |||
| 226 | /* | ||
| 227 | * Validate and accept the bias parameter. | ||
| 228 | */ | ||
| 229 | static int usu_set_bias(const char *bias_s, struct kernel_param *kp) | ||
| 230 | { | ||
| 231 | int i; | ||
| 232 | int len; | ||
| 233 | int bias_n = 0; | ||
| 234 | |||
| 235 | len = strlen(bias_s); | ||
| 236 | if (len == 0) | ||
| 237 | return -EDOM; | ||
| 238 | if (bias_s[len-1] == '\n') | ||
| 239 | --len; | ||
| 240 | |||
| 241 | for (i = 1; i < 3; i++) { | ||
| 242 | if (strncmp(bias_s, bias_names[i], len) == 0) { | ||
| 243 | bias_n = i; | ||
| 244 | break; | ||
| 245 | } | ||
| 246 | } | ||
| 247 | if (bias_n == 0) | ||
| 248 | return -EINVAL; | ||
| 249 | |||
| 250 | atomic_set(&usu_bias, bias_n); | ||
| 251 | return 0; | ||
| 252 | } | ||
| 253 | |||
| 254 | static int usu_get_bias(char *buffer, struct kernel_param *kp) | ||
| 255 | { | ||
| 256 | return strlen(strcpy(buffer, bias_names[atomic_read(&usu_bias)])); | ||
| 257 | } | ||
| 258 | |||
| 259 | module_init(usb_usual_init); | ||
| 260 | module_exit(usb_usual_exit); | ||
| 261 | |||
| 262 | module_param_call(bias, usu_set_bias, usu_get_bias, NULL, S_IRUGO|S_IWUSR); | ||
| 263 | __MODULE_PARM_TYPE(bias, "string"); | ||
| 264 | MODULE_PARM_DESC(bias, "Bias to usb-storage or ub"); | ||
| 265 | |||
| 266 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c index 89401a59f952..55ee2d36d585 100644 --- a/drivers/usb/storage/onetouch.c +++ b/drivers/usb/storage/onetouch.c | |||
| @@ -52,6 +52,7 @@ struct usb_onetouch { | |||
| 52 | struct urb *irq; /* urb for interrupt in report */ | 52 | struct urb *irq; /* urb for interrupt in report */ |
| 53 | unsigned char *data; /* input data */ | 53 | unsigned char *data; /* input data */ |
| 54 | dma_addr_t data_dma; | 54 | dma_addr_t data_dma; |
| 55 | unsigned int is_open:1; | ||
| 55 | }; | 56 | }; |
| 56 | 57 | ||
| 57 | static void usb_onetouch_irq(struct urb *urb, struct pt_regs *regs) | 58 | static void usb_onetouch_irq(struct urb *urb, struct pt_regs *regs) |
| @@ -89,6 +90,7 @@ static int usb_onetouch_open(struct input_dev *dev) | |||
| 89 | { | 90 | { |
| 90 | struct usb_onetouch *onetouch = dev->private; | 91 | struct usb_onetouch *onetouch = dev->private; |
| 91 | 92 | ||
| 93 | onetouch->is_open = 1; | ||
| 92 | onetouch->irq->dev = onetouch->udev; | 94 | onetouch->irq->dev = onetouch->udev; |
| 93 | if (usb_submit_urb(onetouch->irq, GFP_KERNEL)) { | 95 | if (usb_submit_urb(onetouch->irq, GFP_KERNEL)) { |
| 94 | err("usb_submit_urb failed"); | 96 | err("usb_submit_urb failed"); |
| @@ -103,8 +105,30 @@ static void usb_onetouch_close(struct input_dev *dev) | |||
| 103 | struct usb_onetouch *onetouch = dev->private; | 105 | struct usb_onetouch *onetouch = dev->private; |
| 104 | 106 | ||
| 105 | usb_kill_urb(onetouch->irq); | 107 | usb_kill_urb(onetouch->irq); |
| 108 | onetouch->is_open = 0; | ||
| 106 | } | 109 | } |
| 107 | 110 | ||
| 111 | #ifdef CONFIG_PM | ||
| 112 | static void usb_onetouch_pm_hook(struct us_data *us, int action) | ||
| 113 | { | ||
| 114 | struct usb_onetouch *onetouch = (struct usb_onetouch *) us->extra; | ||
| 115 | |||
| 116 | if (onetouch->is_open) { | ||
| 117 | switch (action) { | ||
| 118 | case US_SUSPEND: | ||
| 119 | usb_kill_urb(onetouch->irq); | ||
| 120 | break; | ||
| 121 | case US_RESUME: | ||
| 122 | if (usb_submit_urb(onetouch->irq, GFP_KERNEL) != 0) | ||
| 123 | err("usb_submit_urb failed"); | ||
| 124 | break; | ||
| 125 | default: | ||
| 126 | break; | ||
| 127 | } | ||
| 128 | } | ||
| 129 | } | ||
| 130 | #endif /* CONFIG_PM */ | ||
| 131 | |||
| 108 | int onetouch_connect_input(struct us_data *ss) | 132 | int onetouch_connect_input(struct us_data *ss) |
| 109 | { | 133 | { |
| 110 | struct usb_device *udev = ss->pusb_dev; | 134 | struct usb_device *udev = ss->pusb_dev; |
| @@ -185,6 +209,9 @@ int onetouch_connect_input(struct us_data *ss) | |||
| 185 | 209 | ||
| 186 | ss->extra_destructor = onetouch_release_input; | 210 | ss->extra_destructor = onetouch_release_input; |
| 187 | ss->extra = onetouch; | 211 | ss->extra = onetouch; |
| 212 | #ifdef CONFIG_PM | ||
| 213 | ss->suspend_resume_hook = usb_onetouch_pm_hook; | ||
| 214 | #endif | ||
| 188 | 215 | ||
| 189 | input_register_device(onetouch->dev); | 216 | input_register_device(onetouch->dev); |
| 190 | 217 | ||
diff --git a/drivers/usb/storage/protocol.h b/drivers/usb/storage/protocol.h index 02bff01ab09c..845bed4b8031 100644 --- a/drivers/usb/storage/protocol.h +++ b/drivers/usb/storage/protocol.h | |||
| @@ -41,20 +41,6 @@ | |||
| 41 | #ifndef _PROTOCOL_H_ | 41 | #ifndef _PROTOCOL_H_ |
| 42 | #define _PROTOCOL_H_ | 42 | #define _PROTOCOL_H_ |
| 43 | 43 | ||
| 44 | /* Sub Classes */ | ||
| 45 | |||
| 46 | #define US_SC_RBC 0x01 /* Typically, flash devices */ | ||
| 47 | #define US_SC_8020 0x02 /* CD-ROM */ | ||
| 48 | #define US_SC_QIC 0x03 /* QIC-157 Tapes */ | ||
| 49 | #define US_SC_UFI 0x04 /* Floppy */ | ||
| 50 | #define US_SC_8070 0x05 /* Removable media */ | ||
| 51 | #define US_SC_SCSI 0x06 /* Transparent */ | ||
| 52 | #define US_SC_ISD200 0x07 /* ISD200 ATA */ | ||
| 53 | #define US_SC_MIN US_SC_RBC | ||
| 54 | #define US_SC_MAX US_SC_ISD200 | ||
| 55 | |||
| 56 | #define US_SC_DEVICE 0xff /* Use device's value */ | ||
| 57 | |||
| 58 | /* Protocol handling routines */ | 44 | /* Protocol handling routines */ |
| 59 | extern void usb_stor_ATAPI_command(struct scsi_cmnd*, struct us_data*); | 45 | extern void usb_stor_ATAPI_command(struct scsi_cmnd*, struct us_data*); |
| 60 | extern void usb_stor_qic157_command(struct scsi_cmnd*, struct us_data*); | 46 | extern void usb_stor_qic157_command(struct scsi_cmnd*, struct us_data*); |
diff --git a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c index 0ea2f5ab66ba..fb8bacaae27c 100644 --- a/drivers/usb/storage/sddr09.c +++ b/drivers/usb/storage/sddr09.c | |||
| @@ -133,13 +133,11 @@ static struct nand_flash_dev nand_flash_ids[] = { | |||
| 133 | { 0,} | 133 | { 0,} |
| 134 | }; | 134 | }; |
| 135 | 135 | ||
| 136 | #define SIZE(a) (sizeof(a)/sizeof((a)[0])) | ||
| 137 | |||
| 138 | static struct nand_flash_dev * | 136 | static struct nand_flash_dev * |
| 139 | nand_find_id(unsigned char id) { | 137 | nand_find_id(unsigned char id) { |
| 140 | int i; | 138 | int i; |
| 141 | 139 | ||
| 142 | for (i = 0; i < SIZE(nand_flash_ids); i++) | 140 | for (i = 0; i < ARRAY_SIZE(nand_flash_ids); i++) |
| 143 | if (nand_flash_ids[i].model_id == id) | 141 | if (nand_flash_ids[i].model_id == id) |
| 144 | return &(nand_flash_ids[i]); | 142 | return &(nand_flash_ids[i]); |
| 145 | return NULL; | 143 | return NULL; |
| @@ -214,6 +212,20 @@ static void nand_store_ecc(unsigned char *data, unsigned char *ecc) { | |||
| 214 | * The actual driver starts here. | 212 | * The actual driver starts here. |
| 215 | */ | 213 | */ |
| 216 | 214 | ||
| 215 | struct sddr09_card_info { | ||
| 216 | unsigned long capacity; /* Size of card in bytes */ | ||
| 217 | int pagesize; /* Size of page in bytes */ | ||
| 218 | int pageshift; /* log2 of pagesize */ | ||
| 219 | int blocksize; /* Size of block in pages */ | ||
| 220 | int blockshift; /* log2 of blocksize */ | ||
| 221 | int blockmask; /* 2^blockshift - 1 */ | ||
| 222 | int *lba_to_pba; /* logical to physical map */ | ||
| 223 | int *pba_to_lba; /* physical to logical map */ | ||
| 224 | int lbact; /* number of available pages */ | ||
| 225 | int flags; | ||
| 226 | #define SDDR09_WP 1 /* write protected */ | ||
| 227 | }; | ||
| 228 | |||
| 217 | /* | 229 | /* |
| 218 | * On my 16MB card, control blocks have size 64 (16 real control bytes, | 230 | * On my 16MB card, control blocks have size 64 (16 real control bytes, |
| 219 | * and 48 junk bytes). In reality of course the card uses 16 control bytes, | 231 | * and 48 junk bytes). In reality of course the card uses 16 control bytes, |
| @@ -237,7 +249,7 @@ static void nand_store_ecc(unsigned char *data, unsigned char *ecc) { | |||
| 237 | #define SPARE 0xfffffffe | 249 | #define SPARE 0xfffffffe |
| 238 | #define UNUSABLE 0xfffffffd | 250 | #define UNUSABLE 0xfffffffd |
| 239 | 251 | ||
| 240 | static int erase_bad_lba_entries = 0; | 252 | static const int erase_bad_lba_entries = 0; |
| 241 | 253 | ||
| 242 | /* send vendor interface command (0x41) */ | 254 | /* send vendor interface command (0x41) */ |
| 243 | /* called for requests 0, 1, 8 */ | 255 | /* called for requests 0, 1, 8 */ |
| @@ -260,8 +272,11 @@ sddr09_send_command(struct us_data *us, | |||
| 260 | 272 | ||
| 261 | rc = usb_stor_ctrl_transfer(us, pipe, request, requesttype, | 273 | rc = usb_stor_ctrl_transfer(us, pipe, request, requesttype, |
| 262 | 0, 0, xfer_data, xfer_len); | 274 | 0, 0, xfer_data, xfer_len); |
| 263 | return (rc == USB_STOR_XFER_GOOD ? USB_STOR_TRANSPORT_GOOD : | 275 | switch (rc) { |
| 264 | USB_STOR_TRANSPORT_ERROR); | 276 | case USB_STOR_XFER_GOOD: return 0; |
| 277 | case USB_STOR_XFER_STALLED: return -EPIPE; | ||
| 278 | default: return -EIO; | ||
| 279 | } | ||
| 265 | } | 280 | } |
| 266 | 281 | ||
| 267 | static int | 282 | static int |
| @@ -308,20 +323,12 @@ sddr09_request_sense(struct us_data *us, unsigned char *sensebuf, int buflen) { | |||
| 308 | command[4] = buflen; | 323 | command[4] = buflen; |
| 309 | 324 | ||
| 310 | result = sddr09_send_scsi_command(us, command, 12); | 325 | result = sddr09_send_scsi_command(us, command, 12); |
| 311 | if (result != USB_STOR_TRANSPORT_GOOD) { | 326 | if (result) |
| 312 | US_DEBUGP("request sense failed\n"); | ||
| 313 | return result; | 327 | return result; |
| 314 | } | ||
| 315 | 328 | ||
| 316 | result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, | 329 | result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, |
| 317 | sensebuf, buflen, NULL); | 330 | sensebuf, buflen, NULL); |
| 318 | if (result != USB_STOR_XFER_GOOD) { | 331 | return (result == USB_STOR_XFER_GOOD ? 0 : -EIO); |
| 319 | US_DEBUGP("request sense bulk in failed\n"); | ||
| 320 | return USB_STOR_TRANSPORT_ERROR; | ||
| 321 | } else { | ||
| 322 | US_DEBUGP("request sense worked\n"); | ||
| 323 | return USB_STOR_TRANSPORT_GOOD; | ||
| 324 | } | ||
| 325 | } | 332 | } |
| 326 | 333 | ||
| 327 | /* | 334 | /* |
| @@ -369,7 +376,7 @@ sddr09_readX(struct us_data *us, int x, unsigned long fromaddress, | |||
| 369 | 376 | ||
| 370 | result = sddr09_send_scsi_command(us, command, 12); | 377 | result = sddr09_send_scsi_command(us, command, 12); |
| 371 | 378 | ||
| 372 | if (result != USB_STOR_TRANSPORT_GOOD) { | 379 | if (result) { |
| 373 | US_DEBUGP("Result for send_control in sddr09_read2%d %d\n", | 380 | US_DEBUGP("Result for send_control in sddr09_read2%d %d\n", |
| 374 | x, result); | 381 | x, result); |
| 375 | return result; | 382 | return result; |
| @@ -381,9 +388,9 @@ sddr09_readX(struct us_data *us, int x, unsigned long fromaddress, | |||
| 381 | if (result != USB_STOR_XFER_GOOD) { | 388 | if (result != USB_STOR_XFER_GOOD) { |
| 382 | US_DEBUGP("Result for bulk_transfer in sddr09_read2%d %d\n", | 389 | US_DEBUGP("Result for bulk_transfer in sddr09_read2%d %d\n", |
| 383 | x, result); | 390 | x, result); |
| 384 | return USB_STOR_TRANSPORT_ERROR; | 391 | return -EIO; |
| 385 | } | 392 | } |
| 386 | return USB_STOR_TRANSPORT_GOOD; | 393 | return 0; |
| 387 | } | 394 | } |
| 388 | 395 | ||
| 389 | /* | 396 | /* |
| @@ -497,7 +504,7 @@ sddr09_erase(struct us_data *us, unsigned long Eaddress) { | |||
| 497 | 504 | ||
| 498 | result = sddr09_send_scsi_command(us, command, 12); | 505 | result = sddr09_send_scsi_command(us, command, 12); |
| 499 | 506 | ||
| 500 | if (result != USB_STOR_TRANSPORT_GOOD) | 507 | if (result) |
| 501 | US_DEBUGP("Result for send_control in sddr09_erase %d\n", | 508 | US_DEBUGP("Result for send_control in sddr09_erase %d\n", |
| 502 | result); | 509 | result); |
| 503 | 510 | ||
| @@ -555,7 +562,7 @@ sddr09_writeX(struct us_data *us, | |||
| 555 | 562 | ||
| 556 | result = sddr09_send_scsi_command(us, command, 12); | 563 | result = sddr09_send_scsi_command(us, command, 12); |
| 557 | 564 | ||
| 558 | if (result != USB_STOR_TRANSPORT_GOOD) { | 565 | if (result) { |
| 559 | US_DEBUGP("Result for send_control in sddr09_writeX %d\n", | 566 | US_DEBUGP("Result for send_control in sddr09_writeX %d\n", |
| 560 | result); | 567 | result); |
| 561 | return result; | 568 | return result; |
| @@ -567,9 +574,9 @@ sddr09_writeX(struct us_data *us, | |||
| 567 | if (result != USB_STOR_XFER_GOOD) { | 574 | if (result != USB_STOR_XFER_GOOD) { |
| 568 | US_DEBUGP("Result for bulk_transfer in sddr09_writeX %d\n", | 575 | US_DEBUGP("Result for bulk_transfer in sddr09_writeX %d\n", |
| 569 | result); | 576 | result); |
| 570 | return USB_STOR_TRANSPORT_ERROR; | 577 | return -EIO; |
| 571 | } | 578 | } |
| 572 | return USB_STOR_TRANSPORT_GOOD; | 579 | return 0; |
| 573 | } | 580 | } |
| 574 | 581 | ||
| 575 | /* erase address, write same address */ | 582 | /* erase address, write same address */ |
| @@ -633,7 +640,7 @@ sddr09_read_sg_test_only(struct us_data *us) { | |||
| 633 | 640 | ||
| 634 | result = sddr09_send_scsi_command(us, command, 4*nsg+3); | 641 | result = sddr09_send_scsi_command(us, command, 4*nsg+3); |
| 635 | 642 | ||
| 636 | if (result != USB_STOR_TRANSPORT_GOOD) { | 643 | if (result) { |
| 637 | US_DEBUGP("Result for send_control in sddr09_read_sg %d\n", | 644 | US_DEBUGP("Result for send_control in sddr09_read_sg %d\n", |
| 638 | result); | 645 | result); |
| 639 | return result; | 646 | return result; |
| @@ -641,7 +648,7 @@ sddr09_read_sg_test_only(struct us_data *us) { | |||
| 641 | 648 | ||
| 642 | buf = (unsigned char *) kmalloc(bulklen, GFP_NOIO); | 649 | buf = (unsigned char *) kmalloc(bulklen, GFP_NOIO); |
| 643 | if (!buf) | 650 | if (!buf) |
| 644 | return USB_STOR_TRANSPORT_ERROR; | 651 | return -ENOMEM; |
| 645 | 652 | ||
| 646 | result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, | 653 | result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, |
| 647 | buf, bulklen, NULL); | 654 | buf, bulklen, NULL); |
| @@ -649,10 +656,10 @@ sddr09_read_sg_test_only(struct us_data *us) { | |||
| 649 | if (result != USB_STOR_XFER_GOOD) { | 656 | if (result != USB_STOR_XFER_GOOD) { |
| 650 | US_DEBUGP("Result for bulk_transfer in sddr09_read_sg %d\n", | 657 | US_DEBUGP("Result for bulk_transfer in sddr09_read_sg %d\n", |
| 651 | result); | 658 | result); |
| 652 | return USB_STOR_TRANSPORT_ERROR; | 659 | return -EIO; |
| 653 | } | 660 | } |
| 654 | 661 | ||
| 655 | return USB_STOR_TRANSPORT_GOOD; | 662 | return 0; |
| 656 | } | 663 | } |
| 657 | #endif | 664 | #endif |
| 658 | 665 | ||
| @@ -681,14 +688,13 @@ sddr09_read_status(struct us_data *us, unsigned char *status) { | |||
| 681 | command[1] = LUNBITS; | 688 | command[1] = LUNBITS; |
| 682 | 689 | ||
| 683 | result = sddr09_send_scsi_command(us, command, 12); | 690 | result = sddr09_send_scsi_command(us, command, 12); |
| 684 | if (result != USB_STOR_TRANSPORT_GOOD) | 691 | if (result) |
| 685 | return result; | 692 | return result; |
| 686 | 693 | ||
| 687 | result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, | 694 | result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, |
| 688 | data, 64, NULL); | 695 | data, 64, NULL); |
| 689 | *status = data[0]; | 696 | *status = data[0]; |
| 690 | return (result == USB_STOR_XFER_GOOD ? | 697 | return (result == USB_STOR_XFER_GOOD ? 0 : -EIO); |
| 691 | USB_STOR_TRANSPORT_GOOD : USB_STOR_TRANSPORT_ERROR); | ||
| 692 | } | 698 | } |
| 693 | 699 | ||
| 694 | static int | 700 | static int |
| @@ -703,6 +709,13 @@ sddr09_read_data(struct us_data *us, | |||
| 703 | unsigned int len, index, offset; | 709 | unsigned int len, index, offset; |
| 704 | int result; | 710 | int result; |
| 705 | 711 | ||
| 712 | // Figure out the initial LBA and page | ||
| 713 | lba = address >> info->blockshift; | ||
| 714 | page = (address & info->blockmask); | ||
| 715 | maxlba = info->capacity >> (info->pageshift + info->blockshift); | ||
| 716 | if (lba >= maxlba) | ||
| 717 | return -EIO; | ||
| 718 | |||
| 706 | // Since we only read in one block at a time, we have to create | 719 | // Since we only read in one block at a time, we have to create |
| 707 | // a bounce buffer and move the data a piece at a time between the | 720 | // a bounce buffer and move the data a piece at a time between the |
| 708 | // bounce buffer and the actual transfer buffer. | 721 | // bounce buffer and the actual transfer buffer. |
| @@ -711,18 +724,13 @@ sddr09_read_data(struct us_data *us, | |||
| 711 | buffer = kmalloc(len, GFP_NOIO); | 724 | buffer = kmalloc(len, GFP_NOIO); |
| 712 | if (buffer == NULL) { | 725 | if (buffer == NULL) { |
| 713 | printk("sddr09_read_data: Out of memory\n"); | 726 | printk("sddr09_read_data: Out of memory\n"); |
| 714 | return USB_STOR_TRANSPORT_ERROR; | 727 | return -ENOMEM; |
| 715 | } | 728 | } |
| 716 | 729 | ||
| 717 | // Figure out the initial LBA and page | ||
| 718 | lba = address >> info->blockshift; | ||
| 719 | page = (address & info->blockmask); | ||
| 720 | maxlba = info->capacity >> (info->pageshift + info->blockshift); | ||
| 721 | |||
| 722 | // This could be made much more efficient by checking for | 730 | // This could be made much more efficient by checking for |
| 723 | // contiguous LBA's. Another exercise left to the student. | 731 | // contiguous LBA's. Another exercise left to the student. |
| 724 | 732 | ||
| 725 | result = USB_STOR_TRANSPORT_GOOD; | 733 | result = 0; |
| 726 | index = offset = 0; | 734 | index = offset = 0; |
| 727 | 735 | ||
| 728 | while (sectors > 0) { | 736 | while (sectors > 0) { |
| @@ -735,7 +743,7 @@ sddr09_read_data(struct us_data *us, | |||
| 735 | if (lba >= maxlba) { | 743 | if (lba >= maxlba) { |
| 736 | US_DEBUGP("Error: Requested lba %u exceeds " | 744 | US_DEBUGP("Error: Requested lba %u exceeds " |
| 737 | "maximum %u\n", lba, maxlba); | 745 | "maximum %u\n", lba, maxlba); |
| 738 | result = USB_STOR_TRANSPORT_ERROR; | 746 | result = -EIO; |
| 739 | break; | 747 | break; |
| 740 | } | 748 | } |
| 741 | 749 | ||
| @@ -749,7 +757,7 @@ sddr09_read_data(struct us_data *us, | |||
| 749 | 757 | ||
| 750 | /* This is not really an error. It just means | 758 | /* This is not really an error. It just means |
| 751 | that the block has never been written. | 759 | that the block has never been written. |
| 752 | Instead of returning USB_STOR_TRANSPORT_ERROR | 760 | Instead of returning an error |
| 753 | it is better to return all zero data. */ | 761 | it is better to return all zero data. */ |
| 754 | 762 | ||
| 755 | memset(buffer, 0, len); | 763 | memset(buffer, 0, len); |
| @@ -764,7 +772,7 @@ sddr09_read_data(struct us_data *us, | |||
| 764 | 772 | ||
| 765 | result = sddr09_read20(us, address>>1, | 773 | result = sddr09_read20(us, address>>1, |
| 766 | pages, info->pageshift, buffer, 0); | 774 | pages, info->pageshift, buffer, 0); |
| 767 | if (result != USB_STOR_TRANSPORT_GOOD) | 775 | if (result) |
| 768 | break; | 776 | break; |
| 769 | } | 777 | } |
| 770 | 778 | ||
| @@ -830,7 +838,7 @@ sddr09_write_lba(struct us_data *us, unsigned int lba, | |||
| 830 | pba = sddr09_find_unused_pba(info, lba); | 838 | pba = sddr09_find_unused_pba(info, lba); |
| 831 | if (!pba) { | 839 | if (!pba) { |
| 832 | printk("sddr09_write_lba: Out of unused blocks\n"); | 840 | printk("sddr09_write_lba: Out of unused blocks\n"); |
| 833 | return USB_STOR_TRANSPORT_ERROR; | 841 | return -ENOSPC; |
| 834 | } | 842 | } |
| 835 | info->pba_to_lba[pba] = lba; | 843 | info->pba_to_lba[pba] = lba; |
| 836 | info->lba_to_pba[lba] = pba; | 844 | info->lba_to_pba[lba] = pba; |
| @@ -841,7 +849,7 @@ sddr09_write_lba(struct us_data *us, unsigned int lba, | |||
| 841 | /* Maybe it is impossible to write to PBA 1. | 849 | /* Maybe it is impossible to write to PBA 1. |
| 842 | Fake success, but don't do anything. */ | 850 | Fake success, but don't do anything. */ |
| 843 | printk("sddr09: avoid writing to pba 1\n"); | 851 | printk("sddr09: avoid writing to pba 1\n"); |
| 844 | return USB_STOR_TRANSPORT_GOOD; | 852 | return 0; |
| 845 | } | 853 | } |
| 846 | 854 | ||
| 847 | pagelen = (1 << info->pageshift) + (1 << CONTROL_SHIFT); | 855 | pagelen = (1 << info->pageshift) + (1 << CONTROL_SHIFT); |
| @@ -850,7 +858,7 @@ sddr09_write_lba(struct us_data *us, unsigned int lba, | |||
| 850 | address = (pba << (info->pageshift + info->blockshift)); | 858 | address = (pba << (info->pageshift + info->blockshift)); |
| 851 | result = sddr09_read22(us, address>>1, info->blocksize, | 859 | result = sddr09_read22(us, address>>1, info->blocksize, |
| 852 | info->pageshift, blockbuffer, 0); | 860 | info->pageshift, blockbuffer, 0); |
| 853 | if (result != USB_STOR_TRANSPORT_GOOD) | 861 | if (result) |
| 854 | return result; | 862 | return result; |
| 855 | 863 | ||
| 856 | /* check old contents and fill lba */ | 864 | /* check old contents and fill lba */ |
| @@ -897,7 +905,7 @@ sddr09_write_lba(struct us_data *us, unsigned int lba, | |||
| 897 | { | 905 | { |
| 898 | unsigned char status = 0; | 906 | unsigned char status = 0; |
| 899 | int result2 = sddr09_read_status(us, &status); | 907 | int result2 = sddr09_read_status(us, &status); |
| 900 | if (result2 != USB_STOR_TRANSPORT_GOOD) | 908 | if (result2) |
| 901 | US_DEBUGP("sddr09_write_inplace: cannot read status\n"); | 909 | US_DEBUGP("sddr09_write_inplace: cannot read status\n"); |
| 902 | else if (status != 0xc0) | 910 | else if (status != 0xc0) |
| 903 | US_DEBUGP("sddr09_write_inplace: status after write: 0x%x\n", | 911 | US_DEBUGP("sddr09_write_inplace: status after write: 0x%x\n", |
| @@ -920,13 +928,20 @@ sddr09_write_data(struct us_data *us, | |||
| 920 | unsigned int sectors) { | 928 | unsigned int sectors) { |
| 921 | 929 | ||
| 922 | struct sddr09_card_info *info = (struct sddr09_card_info *) us->extra; | 930 | struct sddr09_card_info *info = (struct sddr09_card_info *) us->extra; |
| 923 | unsigned int lba, page, pages; | 931 | unsigned int lba, maxlba, page, pages; |
| 924 | unsigned int pagelen, blocklen; | 932 | unsigned int pagelen, blocklen; |
| 925 | unsigned char *blockbuffer; | 933 | unsigned char *blockbuffer; |
| 926 | unsigned char *buffer; | 934 | unsigned char *buffer; |
| 927 | unsigned int len, index, offset; | 935 | unsigned int len, index, offset; |
| 928 | int result; | 936 | int result; |
| 929 | 937 | ||
| 938 | // Figure out the initial LBA and page | ||
| 939 | lba = address >> info->blockshift; | ||
| 940 | page = (address & info->blockmask); | ||
| 941 | maxlba = info->capacity >> (info->pageshift + info->blockshift); | ||
| 942 | if (lba >= maxlba) | ||
| 943 | return -EIO; | ||
| 944 | |||
| 930 | // blockbuffer is used for reading in the old data, overwriting | 945 | // blockbuffer is used for reading in the old data, overwriting |
| 931 | // with the new data, and performing ECC calculations | 946 | // with the new data, and performing ECC calculations |
| 932 | 947 | ||
| @@ -938,7 +953,7 @@ sddr09_write_data(struct us_data *us, | |||
| 938 | blockbuffer = kmalloc(blocklen, GFP_NOIO); | 953 | blockbuffer = kmalloc(blocklen, GFP_NOIO); |
| 939 | if (!blockbuffer) { | 954 | if (!blockbuffer) { |
| 940 | printk("sddr09_write_data: Out of memory\n"); | 955 | printk("sddr09_write_data: Out of memory\n"); |
| 941 | return USB_STOR_TRANSPORT_ERROR; | 956 | return -ENOMEM; |
| 942 | } | 957 | } |
| 943 | 958 | ||
| 944 | // Since we don't write the user data directly to the device, | 959 | // Since we don't write the user data directly to the device, |
| @@ -950,14 +965,10 @@ sddr09_write_data(struct us_data *us, | |||
| 950 | if (buffer == NULL) { | 965 | if (buffer == NULL) { |
| 951 | printk("sddr09_write_data: Out of memory\n"); | 966 | printk("sddr09_write_data: Out of memory\n"); |
| 952 | kfree(blockbuffer); | 967 | kfree(blockbuffer); |
| 953 | return USB_STOR_TRANSPORT_ERROR; | 968 | return -ENOMEM; |
| 954 | } | 969 | } |
| 955 | 970 | ||
| 956 | // Figure out the initial LBA and page | 971 | result = 0; |
| 957 | lba = address >> info->blockshift; | ||
| 958 | page = (address & info->blockmask); | ||
| 959 | |||
| 960 | result = USB_STOR_TRANSPORT_GOOD; | ||
| 961 | index = offset = 0; | 972 | index = offset = 0; |
| 962 | 973 | ||
| 963 | while (sectors > 0) { | 974 | while (sectors > 0) { |
| @@ -967,13 +978,21 @@ sddr09_write_data(struct us_data *us, | |||
| 967 | pages = min(sectors, info->blocksize - page); | 978 | pages = min(sectors, info->blocksize - page); |
| 968 | len = (pages << info->pageshift); | 979 | len = (pages << info->pageshift); |
| 969 | 980 | ||
| 981 | /* Not overflowing capacity? */ | ||
| 982 | if (lba >= maxlba) { | ||
| 983 | US_DEBUGP("Error: Requested lba %u exceeds " | ||
| 984 | "maximum %u\n", lba, maxlba); | ||
| 985 | result = -EIO; | ||
| 986 | break; | ||
| 987 | } | ||
| 988 | |||
| 970 | // Get the data from the transfer buffer | 989 | // Get the data from the transfer buffer |
| 971 | usb_stor_access_xfer_buf(buffer, len, us->srb, | 990 | usb_stor_access_xfer_buf(buffer, len, us->srb, |
| 972 | &index, &offset, FROM_XFER_BUF); | 991 | &index, &offset, FROM_XFER_BUF); |
| 973 | 992 | ||
| 974 | result = sddr09_write_lba(us, lba, page, pages, | 993 | result = sddr09_write_lba(us, lba, page, pages, |
| 975 | buffer, blockbuffer); | 994 | buffer, blockbuffer); |
| 976 | if (result != USB_STOR_TRANSPORT_GOOD) | 995 | if (result) |
| 977 | break; | 996 | break; |
| 978 | 997 | ||
| 979 | page = 0; | 998 | page = 0; |
| @@ -1022,7 +1041,7 @@ sddr09_read_deviceID(struct us_data *us, unsigned char *deviceID) { | |||
| 1022 | command[1] = LUNBITS; | 1041 | command[1] = LUNBITS; |
| 1023 | 1042 | ||
| 1024 | result = sddr09_send_scsi_command(us, command, 12); | 1043 | result = sddr09_send_scsi_command(us, command, 12); |
| 1025 | if (result != USB_STOR_TRANSPORT_GOOD) | 1044 | if (result) |
| 1026 | return result; | 1045 | return result; |
| 1027 | 1046 | ||
| 1028 | result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, | 1047 | result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, |
| @@ -1031,8 +1050,7 @@ sddr09_read_deviceID(struct us_data *us, unsigned char *deviceID) { | |||
| 1031 | for (i = 0; i < 4; i++) | 1050 | for (i = 0; i < 4; i++) |
| 1032 | deviceID[i] = content[i]; | 1051 | deviceID[i] = content[i]; |
| 1033 | 1052 | ||
| 1034 | return (result == USB_STOR_XFER_GOOD ? | 1053 | return (result == USB_STOR_XFER_GOOD ? 0 : -EIO); |
| 1035 | USB_STOR_TRANSPORT_GOOD : USB_STOR_TRANSPORT_ERROR); | ||
| 1036 | } | 1054 | } |
| 1037 | 1055 | ||
| 1038 | static int | 1056 | static int |
| @@ -1041,7 +1059,7 @@ sddr09_get_wp(struct us_data *us, struct sddr09_card_info *info) { | |||
| 1041 | unsigned char status; | 1059 | unsigned char status; |
| 1042 | 1060 | ||
| 1043 | result = sddr09_read_status(us, &status); | 1061 | result = sddr09_read_status(us, &status); |
| 1044 | if (result != USB_STOR_TRANSPORT_GOOD) { | 1062 | if (result) { |
| 1045 | US_DEBUGP("sddr09_get_wp: read_status fails\n"); | 1063 | US_DEBUGP("sddr09_get_wp: read_status fails\n"); |
| 1046 | return result; | 1064 | return result; |
| 1047 | } | 1065 | } |
| @@ -1057,7 +1075,7 @@ sddr09_get_wp(struct us_data *us, struct sddr09_card_info *info) { | |||
| 1057 | if (status & 0x1) | 1075 | if (status & 0x1) |
| 1058 | US_DEBUGP(" Error"); | 1076 | US_DEBUGP(" Error"); |
| 1059 | US_DEBUGP("\n"); | 1077 | US_DEBUGP("\n"); |
| 1060 | return USB_STOR_TRANSPORT_GOOD; | 1078 | return 0; |
| 1061 | } | 1079 | } |
| 1062 | 1080 | ||
| 1063 | #if 0 | 1081 | #if 0 |
| @@ -1089,7 +1107,7 @@ sddr09_get_cardinfo(struct us_data *us, unsigned char flags) { | |||
| 1089 | 1107 | ||
| 1090 | result = sddr09_read_deviceID(us, deviceID); | 1108 | result = sddr09_read_deviceID(us, deviceID); |
| 1091 | 1109 | ||
| 1092 | if (result != USB_STOR_TRANSPORT_GOOD) { | 1110 | if (result) { |
| 1093 | US_DEBUGP("Result of read_deviceID is %d\n", result); | 1111 | US_DEBUGP("Result of read_deviceID is %d\n", result); |
| 1094 | printk("sddr09: could not read card info\n"); | 1112 | printk("sddr09: could not read card info\n"); |
| 1095 | return NULL; | 1113 | return NULL; |
| @@ -1200,7 +1218,7 @@ sddr09_read_map(struct us_data *us) { | |||
| 1200 | us, address>>1, | 1218 | us, address>>1, |
| 1201 | min(alloc_blocks, numblocks - i), | 1219 | min(alloc_blocks, numblocks - i), |
| 1202 | buffer, 0); | 1220 | buffer, 0); |
| 1203 | if (result != USB_STOR_TRANSPORT_GOOD) { | 1221 | if (result) { |
| 1204 | result = -1; | 1222 | result = -1; |
| 1205 | goto done; | 1223 | goto done; |
| 1206 | } | 1224 | } |
| @@ -1342,29 +1360,53 @@ sddr09_card_info_destructor(void *extra) { | |||
| 1342 | kfree(info->pba_to_lba); | 1360 | kfree(info->pba_to_lba); |
| 1343 | } | 1361 | } |
| 1344 | 1362 | ||
| 1345 | static void | 1363 | static int |
| 1346 | sddr09_init_card_info(struct us_data *us) { | 1364 | sddr09_common_init(struct us_data *us) { |
| 1347 | if (!us->extra) { | 1365 | int result; |
| 1348 | us->extra = kmalloc(sizeof(struct sddr09_card_info), GFP_NOIO); | 1366 | |
| 1349 | if (us->extra) { | 1367 | /* set the configuration -- STALL is an acceptable response here */ |
| 1350 | memset(us->extra, 0, sizeof(struct sddr09_card_info)); | 1368 | if (us->pusb_dev->actconfig->desc.bConfigurationValue != 1) { |
| 1351 | us->extra_destructor = sddr09_card_info_destructor; | 1369 | US_DEBUGP("active config #%d != 1 ??\n", us->pusb_dev |
| 1352 | } | 1370 | ->actconfig->desc.bConfigurationValue); |
| 1371 | return -EINVAL; | ||
| 1372 | } | ||
| 1373 | |||
| 1374 | result = usb_reset_configuration(us->pusb_dev); | ||
| 1375 | US_DEBUGP("Result of usb_reset_configuration is %d\n", result); | ||
| 1376 | if (result == -EPIPE) { | ||
| 1377 | US_DEBUGP("-- stall on control interface\n"); | ||
| 1378 | } else if (result != 0) { | ||
| 1379 | /* it's not a stall, but another error -- time to bail */ | ||
| 1380 | US_DEBUGP("-- Unknown error. Rejecting device\n"); | ||
| 1381 | return -EINVAL; | ||
| 1353 | } | 1382 | } |
| 1383 | |||
| 1384 | us->extra = kzalloc(sizeof(struct sddr09_card_info), GFP_NOIO); | ||
| 1385 | if (!us->extra) | ||
| 1386 | return -ENOMEM; | ||
| 1387 | us->extra_destructor = sddr09_card_info_destructor; | ||
| 1388 | |||
| 1389 | nand_init_ecc(); | ||
| 1390 | return 0; | ||
| 1354 | } | 1391 | } |
| 1355 | 1392 | ||
| 1393 | |||
| 1356 | /* | 1394 | /* |
| 1357 | * This is needed at a very early stage. If this is not listed in the | 1395 | * This is needed at a very early stage. If this is not listed in the |
| 1358 | * unusual devices list but called from here then LUN 0 of the combo reader | 1396 | * unusual devices list but called from here then LUN 0 of the combo reader |
| 1359 | * is not recognized. But I do not know what precisely these calls do. | 1397 | * is not recognized. But I do not know what precisely these calls do. |
| 1360 | */ | 1398 | */ |
| 1361 | int | 1399 | int |
| 1362 | sddr09_init(struct us_data *us) { | 1400 | usb_stor_sddr09_dpcm_init(struct us_data *us) { |
| 1363 | int result; | 1401 | int result; |
| 1364 | unsigned char *data = us->iobuf; | 1402 | unsigned char *data = us->iobuf; |
| 1365 | 1403 | ||
| 1404 | result = sddr09_common_init(us); | ||
| 1405 | if (result) | ||
| 1406 | return result; | ||
| 1407 | |||
| 1366 | result = sddr09_send_command(us, 0x01, USB_DIR_IN, data, 2); | 1408 | result = sddr09_send_command(us, 0x01, USB_DIR_IN, data, 2); |
| 1367 | if (result != USB_STOR_TRANSPORT_GOOD) { | 1409 | if (result) { |
| 1368 | US_DEBUGP("sddr09_init: send_command fails\n"); | 1410 | US_DEBUGP("sddr09_init: send_command fails\n"); |
| 1369 | return result; | 1411 | return result; |
| 1370 | } | 1412 | } |
| @@ -1373,7 +1415,7 @@ sddr09_init(struct us_data *us) { | |||
| 1373 | // get 07 02 | 1415 | // get 07 02 |
| 1374 | 1416 | ||
| 1375 | result = sddr09_send_command(us, 0x08, USB_DIR_IN, data, 2); | 1417 | result = sddr09_send_command(us, 0x08, USB_DIR_IN, data, 2); |
| 1376 | if (result != USB_STOR_TRANSPORT_GOOD) { | 1418 | if (result) { |
| 1377 | US_DEBUGP("sddr09_init: 2nd send_command fails\n"); | 1419 | US_DEBUGP("sddr09_init: 2nd send_command fails\n"); |
| 1378 | return result; | 1420 | return result; |
| 1379 | } | 1421 | } |
| @@ -1382,7 +1424,7 @@ sddr09_init(struct us_data *us) { | |||
| 1382 | // get 07 00 | 1424 | // get 07 00 |
| 1383 | 1425 | ||
| 1384 | result = sddr09_request_sense(us, data, 18); | 1426 | result = sddr09_request_sense(us, data, 18); |
| 1385 | if (result == USB_STOR_TRANSPORT_GOOD && data[2] != 0) { | 1427 | if (result == 0 && data[2] != 0) { |
| 1386 | int j; | 1428 | int j; |
| 1387 | for (j=0; j<18; j++) | 1429 | for (j=0; j<18; j++) |
| 1388 | printk(" %02X", data[j]); | 1430 | printk(" %02X", data[j]); |
| @@ -1398,7 +1440,7 @@ sddr09_init(struct us_data *us) { | |||
| 1398 | 1440 | ||
| 1399 | // test unit ready | 1441 | // test unit ready |
| 1400 | 1442 | ||
| 1401 | return USB_STOR_TRANSPORT_GOOD; /* not result */ | 1443 | return 0; /* not result */ |
| 1402 | } | 1444 | } |
| 1403 | 1445 | ||
| 1404 | /* | 1446 | /* |
| @@ -1427,13 +1469,6 @@ int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
| 1427 | }; | 1469 | }; |
| 1428 | 1470 | ||
| 1429 | info = (struct sddr09_card_info *)us->extra; | 1471 | info = (struct sddr09_card_info *)us->extra; |
| 1430 | if (!info) { | ||
| 1431 | nand_init_ecc(); | ||
| 1432 | sddr09_init_card_info(us); | ||
| 1433 | info = (struct sddr09_card_info *)us->extra; | ||
| 1434 | if (!info) | ||
| 1435 | return USB_STOR_TRANSPORT_ERROR; | ||
| 1436 | } | ||
| 1437 | 1472 | ||
| 1438 | if (srb->cmnd[0] == REQUEST_SENSE && havefakesense) { | 1473 | if (srb->cmnd[0] == REQUEST_SENSE && havefakesense) { |
| 1439 | /* for a faked command, we have to follow with a faked sense */ | 1474 | /* for a faked command, we have to follow with a faked sense */ |
| @@ -1536,7 +1571,9 @@ int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
| 1536 | US_DEBUGP("READ_10: read page %d pagect %d\n", | 1571 | US_DEBUGP("READ_10: read page %d pagect %d\n", |
| 1537 | page, pages); | 1572 | page, pages); |
| 1538 | 1573 | ||
| 1539 | return sddr09_read_data(us, page, pages); | 1574 | result = sddr09_read_data(us, page, pages); |
| 1575 | return (result == 0 ? USB_STOR_TRANSPORT_GOOD : | ||
| 1576 | USB_STOR_TRANSPORT_ERROR); | ||
| 1540 | } | 1577 | } |
| 1541 | 1578 | ||
| 1542 | if (srb->cmnd[0] == WRITE_10) { | 1579 | if (srb->cmnd[0] == WRITE_10) { |
| @@ -1549,7 +1586,9 @@ int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
| 1549 | US_DEBUGP("WRITE_10: write page %d pagect %d\n", | 1586 | US_DEBUGP("WRITE_10: write page %d pagect %d\n", |
| 1550 | page, pages); | 1587 | page, pages); |
| 1551 | 1588 | ||
| 1552 | return sddr09_write_data(us, page, pages); | 1589 | result = sddr09_write_data(us, page, pages); |
| 1590 | return (result == 0 ? USB_STOR_TRANSPORT_GOOD : | ||
| 1591 | USB_STOR_TRANSPORT_ERROR); | ||
| 1553 | } | 1592 | } |
| 1554 | 1593 | ||
| 1555 | /* catch-all for all other commands, except | 1594 | /* catch-all for all other commands, except |
| @@ -1575,10 +1614,10 @@ int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
| 1575 | US_DEBUGP("SDDR09: Send control for command %s\n", ptr); | 1614 | US_DEBUGP("SDDR09: Send control for command %s\n", ptr); |
| 1576 | 1615 | ||
| 1577 | result = sddr09_send_scsi_command(us, srb->cmnd, 12); | 1616 | result = sddr09_send_scsi_command(us, srb->cmnd, 12); |
| 1578 | if (result != USB_STOR_TRANSPORT_GOOD) { | 1617 | if (result) { |
| 1579 | US_DEBUGP("sddr09_transport: sddr09_send_scsi_command " | 1618 | US_DEBUGP("sddr09_transport: sddr09_send_scsi_command " |
| 1580 | "returns %d\n", result); | 1619 | "returns %d\n", result); |
| 1581 | return result; | 1620 | return USB_STOR_TRANSPORT_ERROR; |
| 1582 | } | 1621 | } |
| 1583 | 1622 | ||
| 1584 | if (srb->request_bufflen == 0) | 1623 | if (srb->request_bufflen == 0) |
| @@ -1606,3 +1645,10 @@ int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
| 1606 | return USB_STOR_TRANSPORT_GOOD; | 1645 | return USB_STOR_TRANSPORT_GOOD; |
| 1607 | } | 1646 | } |
| 1608 | 1647 | ||
| 1648 | /* | ||
| 1649 | * Initialization routine for the sddr09 subdriver | ||
| 1650 | */ | ||
| 1651 | int | ||
| 1652 | usb_stor_sddr09_init(struct us_data *us) { | ||
| 1653 | return sddr09_common_init(us); | ||
| 1654 | } | ||
diff --git a/drivers/usb/storage/sddr09.h b/drivers/usb/storage/sddr09.h index c9d78d6188b1..c03089a9ec38 100644 --- a/drivers/usb/storage/sddr09.h +++ b/drivers/usb/storage/sddr09.h | |||
| @@ -31,18 +31,7 @@ | |||
| 31 | 31 | ||
| 32 | extern int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us); | 32 | extern int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us); |
| 33 | 33 | ||
| 34 | struct sddr09_card_info { | 34 | extern int usb_stor_sddr09_dpcm_init(struct us_data *us); |
| 35 | unsigned long capacity; /* Size of card in bytes */ | 35 | extern int usb_stor_sddr09_init(struct us_data *us); |
| 36 | int pagesize; /* Size of page in bytes */ | ||
| 37 | int pageshift; /* log2 of pagesize */ | ||
| 38 | int blocksize; /* Size of block in pages */ | ||
| 39 | int blockshift; /* log2 of blocksize */ | ||
| 40 | int blockmask; /* 2^blockshift - 1 */ | ||
| 41 | int *lba_to_pba; /* logical to physical map */ | ||
| 42 | int *pba_to_lba; /* physical to logical map */ | ||
| 43 | int lbact; /* number of available pages */ | ||
| 44 | int flags; | ||
| 45 | #define SDDR09_WP 1 /* write protected */ | ||
| 46 | }; | ||
| 47 | 36 | ||
| 48 | #endif | 37 | #endif |
diff --git a/drivers/usb/storage/transport.h b/drivers/usb/storage/transport.h index 0a362cc781ad..633a715850a4 100644 --- a/drivers/usb/storage/transport.h +++ b/drivers/usb/storage/transport.h | |||
| @@ -41,39 +41,8 @@ | |||
| 41 | #ifndef _TRANSPORT_H_ | 41 | #ifndef _TRANSPORT_H_ |
| 42 | #define _TRANSPORT_H_ | 42 | #define _TRANSPORT_H_ |
| 43 | 43 | ||
| 44 | #include <linux/config.h> | ||
| 45 | #include <linux/blkdev.h> | 44 | #include <linux/blkdev.h> |
| 46 | 45 | ||
| 47 | /* Protocols */ | ||
| 48 | |||
| 49 | #define US_PR_CBI 0x00 /* Control/Bulk/Interrupt */ | ||
| 50 | #define US_PR_CB 0x01 /* Control/Bulk w/o interrupt */ | ||
| 51 | #define US_PR_BULK 0x50 /* bulk only */ | ||
| 52 | #ifdef CONFIG_USB_STORAGE_USBAT | ||
| 53 | #define US_PR_USBAT 0x80 /* SCM-ATAPI bridge */ | ||
| 54 | #endif | ||
| 55 | #ifdef CONFIG_USB_STORAGE_SDDR09 | ||
| 56 | #define US_PR_EUSB_SDDR09 0x81 /* SCM-SCSI bridge for SDDR-09 */ | ||
| 57 | #endif | ||
| 58 | #ifdef CONFIG_USB_STORAGE_SDDR55 | ||
| 59 | #define US_PR_SDDR55 0x82 /* SDDR-55 (made up) */ | ||
| 60 | #endif | ||
| 61 | #define US_PR_DPCM_USB 0xf0 /* Combination CB/SDDR09 */ | ||
| 62 | |||
| 63 | #ifdef CONFIG_USB_STORAGE_FREECOM | ||
| 64 | #define US_PR_FREECOM 0xf1 /* Freecom */ | ||
| 65 | #endif | ||
| 66 | |||
| 67 | #ifdef CONFIG_USB_STORAGE_DATAFAB | ||
| 68 | #define US_PR_DATAFAB 0xf2 /* Datafab chipsets */ | ||
| 69 | #endif | ||
| 70 | |||
| 71 | #ifdef CONFIG_USB_STORAGE_JUMPSHOT | ||
| 72 | #define US_PR_JUMPSHOT 0xf3 /* Lexar Jumpshot */ | ||
| 73 | #endif | ||
| 74 | |||
| 75 | #define US_PR_DEVICE 0xff /* Use device's value */ | ||
| 76 | |||
| 77 | /* | 46 | /* |
| 78 | * Bulk only data structures | 47 | * Bulk only data structures |
| 79 | */ | 48 | */ |
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index f5f47a34b168..dc301e567cfc 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
| @@ -79,13 +79,6 @@ UNUSUAL_DEV( 0x03f0, 0x0307, 0x0001, 0x0001, | |||
| 79 | US_SC_8070, US_PR_USBAT, init_usbat, 0), | 79 | US_SC_8070, US_PR_USBAT, init_usbat, 0), |
| 80 | #endif | 80 | #endif |
| 81 | 81 | ||
| 82 | /* Patch submitted by Mihnea-Costin Grigore <mihnea@zulu.ro> */ | ||
| 83 | UNUSUAL_DEV( 0x040d, 0x6205, 0x0003, 0x0003, | ||
| 84 | "VIA Technologies Inc.", | ||
| 85 | "USB 2.0 Card Reader", | ||
| 86 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
| 87 | US_FL_IGNORE_RESIDUE ), | ||
| 88 | |||
| 89 | /* Reported by Sebastian Kapfer <sebastian_kapfer@gmx.net> | 82 | /* Reported by Sebastian Kapfer <sebastian_kapfer@gmx.net> |
| 90 | * and Olaf Hering <olh@suse.de> (different bcd's, same vendor/product) | 83 | * and Olaf Hering <olh@suse.de> (different bcd's, same vendor/product) |
| 91 | * for USB floppies that need the SINGLE_LUN enforcement. | 84 | * for USB floppies that need the SINGLE_LUN enforcement. |
| @@ -96,6 +89,13 @@ UNUSUAL_DEV( 0x0409, 0x0040, 0x0000, 0x9999, | |||
| 96 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 89 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
| 97 | US_FL_SINGLE_LUN ), | 90 | US_FL_SINGLE_LUN ), |
| 98 | 91 | ||
| 92 | /* Patch submitted by Mihnea-Costin Grigore <mihnea@zulu.ro> */ | ||
| 93 | UNUSUAL_DEV( 0x040d, 0x6205, 0x0003, 0x0003, | ||
| 94 | "VIA Technologies Inc.", | ||
| 95 | "USB 2.0 Card Reader", | ||
| 96 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
| 97 | US_FL_IGNORE_RESIDUE ), | ||
| 98 | |||
| 99 | /* Deduced by Jonathan Woithe <jwoithe@physics.adelaide.edu.au> | 99 | /* Deduced by Jonathan Woithe <jwoithe@physics.adelaide.edu.au> |
| 100 | * Entry needed for flags: US_FL_FIX_INQUIRY because initial inquiry message | 100 | * Entry needed for flags: US_FL_FIX_INQUIRY because initial inquiry message |
| 101 | * always fails and confuses drive. | 101 | * always fails and confuses drive. |
| @@ -187,6 +187,14 @@ UNUSUAL_DEV( 0x04b0, 0x0405, 0x0100, 0x0100, | |||
| 187 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 187 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
| 188 | US_FL_FIX_CAPACITY), | 188 | US_FL_FIX_CAPACITY), |
| 189 | 189 | ||
| 190 | /* Patch for Nikon coolpix 2000 | ||
| 191 | * Submitted by Fabien Cosse <fabien.cosse@wanadoo.fr>*/ | ||
| 192 | UNUSUAL_DEV( 0x04b0, 0x0301, 0x0010, 0x0010, | ||
| 193 | "NIKON", | ||
| 194 | "NIKON DSC E2000", | ||
| 195 | US_SC_DEVICE, US_PR_DEVICE,NULL, | ||
| 196 | US_FL_NOT_LOCKABLE ), | ||
| 197 | |||
| 190 | /* BENQ DC5330 | 198 | /* BENQ DC5330 |
| 191 | * Reported by Manuel Fombuena <mfombuena@ya.com> and | 199 | * Reported by Manuel Fombuena <mfombuena@ya.com> and |
| 192 | * Frank Copeland <fjc@thingy.apana.org.au> */ | 200 | * Frank Copeland <fjc@thingy.apana.org.au> */ |
| @@ -276,14 +284,14 @@ UNUSUAL_DEV( 0x04e6, 0x0002, 0x0100, 0x0100, | |||
| 276 | UNUSUAL_DEV( 0x04e6, 0x0003, 0x0000, 0x9999, | 284 | UNUSUAL_DEV( 0x04e6, 0x0003, 0x0000, 0x9999, |
| 277 | "Sandisk", | 285 | "Sandisk", |
| 278 | "ImageMate SDDR09", | 286 | "ImageMate SDDR09", |
| 279 | US_SC_SCSI, US_PR_EUSB_SDDR09, NULL, | 287 | US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init, |
| 280 | US_FL_SINGLE_LUN ), | 288 | 0), |
| 281 | 289 | ||
| 282 | /* This entry is from Andries.Brouwer@cwi.nl */ | 290 | /* This entry is from Andries.Brouwer@cwi.nl */ |
| 283 | UNUSUAL_DEV( 0x04e6, 0x0005, 0x0100, 0x0208, | 291 | UNUSUAL_DEV( 0x04e6, 0x0005, 0x0100, 0x0208, |
| 284 | "SCM Microsystems", | 292 | "SCM Microsystems", |
| 285 | "eUSB SmartMedia / CompactFlash Adapter", | 293 | "eUSB SmartMedia / CompactFlash Adapter", |
| 286 | US_SC_SCSI, US_PR_DPCM_USB, sddr09_init, | 294 | US_SC_SCSI, US_PR_DPCM_USB, usb_stor_sddr09_dpcm_init, |
| 287 | 0), | 295 | 0), |
| 288 | #endif | 296 | #endif |
| 289 | 297 | ||
| @@ -527,6 +535,13 @@ UNUSUAL_DEV( 0x057b, 0x0022, 0x0000, 0x9999, | |||
| 527 | "Silicon Media R/W", | 535 | "Silicon Media R/W", |
| 528 | US_SC_DEVICE, US_PR_DEVICE, NULL, 0), | 536 | US_SC_DEVICE, US_PR_DEVICE, NULL, 0), |
| 529 | 537 | ||
| 538 | #ifdef CONFIG_USB_STORAGE_ALAUDA | ||
| 539 | UNUSUAL_DEV( 0x0584, 0x0008, 0x0102, 0x0102, | ||
| 540 | "Fujifilm", | ||
| 541 | "DPC-R1 (Alauda)", | ||
| 542 | US_SC_SCSI, US_PR_ALAUDA, init_alauda, 0 ), | ||
| 543 | #endif | ||
| 544 | |||
| 530 | /* Fabrizio Fellini <fello@libero.it> */ | 545 | /* Fabrizio Fellini <fello@libero.it> */ |
| 531 | UNUSUAL_DEV( 0x0595, 0x4343, 0x0000, 0x2210, | 546 | UNUSUAL_DEV( 0x0595, 0x4343, 0x0000, 0x2210, |
| 532 | "Fujifilm", | 547 | "Fujifilm", |
| @@ -673,8 +688,8 @@ UNUSUAL_DEV( 0x0644, 0x0000, 0x0100, 0x0100, | |||
| 673 | UNUSUAL_DEV( 0x066b, 0x0105, 0x0100, 0x0100, | 688 | UNUSUAL_DEV( 0x066b, 0x0105, 0x0100, 0x0100, |
| 674 | "Olympus", | 689 | "Olympus", |
| 675 | "Camedia MAUSB-2", | 690 | "Camedia MAUSB-2", |
| 676 | US_SC_SCSI, US_PR_EUSB_SDDR09, NULL, | 691 | US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init, |
| 677 | US_FL_SINGLE_LUN ), | 692 | 0), |
| 678 | #endif | 693 | #endif |
| 679 | 694 | ||
| 680 | /* Reported by Darsen Lu <darsen@micro.ee.nthu.edu.tw> */ | 695 | /* Reported by Darsen Lu <darsen@micro.ee.nthu.edu.tw> */ |
| @@ -739,8 +754,8 @@ UNUSUAL_DEV( 0x0781, 0x0100, 0x0100, 0x0100, | |||
| 739 | UNUSUAL_DEV( 0x0781, 0x0200, 0x0000, 0x9999, | 754 | UNUSUAL_DEV( 0x0781, 0x0200, 0x0000, 0x9999, |
| 740 | "Sandisk", | 755 | "Sandisk", |
| 741 | "ImageMate SDDR-09", | 756 | "ImageMate SDDR-09", |
| 742 | US_SC_SCSI, US_PR_EUSB_SDDR09, NULL, | 757 | US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init, |
| 743 | US_FL_SINGLE_LUN ), | 758 | 0), |
| 744 | #endif | 759 | #endif |
| 745 | 760 | ||
| 746 | #ifdef CONFIG_USB_STORAGE_FREECOM | 761 | #ifdef CONFIG_USB_STORAGE_FREECOM |
| @@ -776,6 +791,13 @@ UNUSUAL_DEV( 0x07af, 0x0006, 0x0100, 0x0100, | |||
| 776 | US_SC_SCSI, US_PR_DPCM_USB, NULL, 0 ), | 791 | US_SC_SCSI, US_PR_DPCM_USB, NULL, 0 ), |
| 777 | #endif | 792 | #endif |
| 778 | 793 | ||
| 794 | #ifdef CONFIG_USB_STORAGE_ALAUDA | ||
| 795 | UNUSUAL_DEV( 0x07b4, 0x010a, 0x0102, 0x0102, | ||
| 796 | "Olympus", | ||
| 797 | "MAUSB-10 (Alauda)", | ||
| 798 | US_SC_SCSI, US_PR_ALAUDA, init_alauda, 0 ), | ||
| 799 | #endif | ||
| 800 | |||
| 779 | #ifdef CONFIG_USB_STORAGE_DATAFAB | 801 | #ifdef CONFIG_USB_STORAGE_DATAFAB |
| 780 | UNUSUAL_DEV( 0x07c4, 0xa000, 0x0000, 0x0015, | 802 | UNUSUAL_DEV( 0x07c4, 0xa000, 0x0000, 0x0015, |
| 781 | "Datafab", | 803 | "Datafab", |
| @@ -1134,3 +1156,27 @@ UNUSUAL_DEV( 0x55aa, 0xa103, 0x0000, 0x9999, | |||
| 1134 | US_SC_SCSI, US_PR_SDDR55, NULL, | 1156 | US_SC_SCSI, US_PR_SDDR55, NULL, |
| 1135 | US_FL_SINGLE_LUN), | 1157 | US_FL_SINGLE_LUN), |
| 1136 | #endif | 1158 | #endif |
| 1159 | |||
| 1160 | /* Control/Bulk transport for all SubClass values */ | ||
| 1161 | USUAL_DEV(US_SC_RBC, US_PR_CB, USB_US_TYPE_STOR), | ||
| 1162 | USUAL_DEV(US_SC_8020, US_PR_CB, USB_US_TYPE_STOR), | ||
| 1163 | USUAL_DEV(US_SC_QIC, US_PR_CB, USB_US_TYPE_STOR), | ||
| 1164 | USUAL_DEV(US_SC_UFI, US_PR_CB, USB_US_TYPE_STOR), | ||
| 1165 | USUAL_DEV(US_SC_8070, US_PR_CB, USB_US_TYPE_STOR), | ||
| 1166 | USUAL_DEV(US_SC_SCSI, US_PR_CB, USB_US_TYPE_STOR), | ||
| 1167 | |||
| 1168 | /* Control/Bulk/Interrupt transport for all SubClass values */ | ||
| 1169 | USUAL_DEV(US_SC_RBC, US_PR_CBI, USB_US_TYPE_STOR), | ||
| 1170 | USUAL_DEV(US_SC_8020, US_PR_CBI, USB_US_TYPE_STOR), | ||
| 1171 | USUAL_DEV(US_SC_QIC, US_PR_CBI, USB_US_TYPE_STOR), | ||
| 1172 | USUAL_DEV(US_SC_UFI, US_PR_CBI, USB_US_TYPE_STOR), | ||
| 1173 | USUAL_DEV(US_SC_8070, US_PR_CBI, USB_US_TYPE_STOR), | ||
| 1174 | USUAL_DEV(US_SC_SCSI, US_PR_CBI, USB_US_TYPE_STOR), | ||
| 1175 | |||
| 1176 | /* Bulk-only transport for all SubClass values */ | ||
| 1177 | USUAL_DEV(US_SC_RBC, US_PR_BULK, USB_US_TYPE_STOR), | ||
| 1178 | USUAL_DEV(US_SC_8020, US_PR_BULK, USB_US_TYPE_STOR), | ||
| 1179 | USUAL_DEV(US_SC_QIC, US_PR_BULK, USB_US_TYPE_STOR), | ||
| 1180 | USUAL_DEV(US_SC_UFI, US_PR_BULK, USB_US_TYPE_STOR), | ||
| 1181 | USUAL_DEV(US_SC_8070, US_PR_BULK, USB_US_TYPE_STOR), | ||
| 1182 | USUAL_DEV(US_SC_SCSI, US_PR_BULK, 0), | ||
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 3847ebed2aa4..dbcf23980ff1 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c | |||
| @@ -94,6 +94,9 @@ | |||
| 94 | #ifdef CONFIG_USB_STORAGE_ONETOUCH | 94 | #ifdef CONFIG_USB_STORAGE_ONETOUCH |
| 95 | #include "onetouch.h" | 95 | #include "onetouch.h" |
| 96 | #endif | 96 | #endif |
| 97 | #ifdef CONFIG_USB_STORAGE_ALAUDA | ||
| 98 | #include "alauda.h" | ||
| 99 | #endif | ||
| 97 | 100 | ||
| 98 | /* Some informational data */ | 101 | /* Some informational data */ |
| 99 | MODULE_AUTHOR("Matthew Dharm <mdharm-usb@one-eyed-alien.net>"); | 102 | MODULE_AUTHOR("Matthew Dharm <mdharm-usb@one-eyed-alien.net>"); |
| @@ -112,49 +115,33 @@ static atomic_t total_threads = ATOMIC_INIT(0); | |||
| 112 | static DECLARE_COMPLETION(threads_gone); | 115 | static DECLARE_COMPLETION(threads_gone); |
| 113 | 116 | ||
| 114 | 117 | ||
| 115 | /* The entries in this table, except for final ones here | 118 | /* |
| 116 | * (USB_MASS_STORAGE_CLASS and the empty entry), correspond, | 119 | * The entries in this table correspond, line for line, |
| 117 | * line for line with the entries of us_unsuaul_dev_list[]. | 120 | * with the entries of us_unusual_dev_list[]. |
| 118 | */ | 121 | */ |
| 122 | #ifndef CONFIG_USB_LIBUSUAL | ||
| 119 | 123 | ||
| 120 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | 124 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ |
| 121 | vendorName, productName,useProtocol, useTransport, \ | 125 | vendorName, productName,useProtocol, useTransport, \ |
| 122 | initFunction, flags) \ | 126 | initFunction, flags) \ |
| 123 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax) } | 127 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax), \ |
| 128 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } | ||
| 129 | |||
| 130 | #define USUAL_DEV(useProto, useTrans, useType) \ | ||
| 131 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \ | ||
| 132 | .driver_info = (USB_US_TYPE_STOR<<24) } | ||
| 124 | 133 | ||
| 125 | static struct usb_device_id storage_usb_ids [] = { | 134 | static struct usb_device_id storage_usb_ids [] = { |
| 126 | 135 | ||
| 127 | # include "unusual_devs.h" | 136 | # include "unusual_devs.h" |
| 128 | #undef UNUSUAL_DEV | 137 | #undef UNUSUAL_DEV |
| 129 | /* Control/Bulk transport for all SubClass values */ | 138 | #undef USUAL_DEV |
| 130 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_RBC, US_PR_CB) }, | ||
| 131 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8020, US_PR_CB) }, | ||
| 132 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_QIC, US_PR_CB) }, | ||
| 133 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_UFI, US_PR_CB) }, | ||
| 134 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8070, US_PR_CB) }, | ||
| 135 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_CB) }, | ||
| 136 | |||
| 137 | /* Control/Bulk/Interrupt transport for all SubClass values */ | ||
| 138 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_RBC, US_PR_CBI) }, | ||
| 139 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8020, US_PR_CBI) }, | ||
| 140 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_QIC, US_PR_CBI) }, | ||
| 141 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_UFI, US_PR_CBI) }, | ||
| 142 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8070, US_PR_CBI) }, | ||
| 143 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_CBI) }, | ||
| 144 | |||
| 145 | /* Bulk-only transport for all SubClass values */ | ||
| 146 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_RBC, US_PR_BULK) }, | ||
| 147 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8020, US_PR_BULK) }, | ||
| 148 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_QIC, US_PR_BULK) }, | ||
| 149 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_UFI, US_PR_BULK) }, | ||
| 150 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8070, US_PR_BULK) }, | ||
| 151 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_BULK) }, | ||
| 152 | |||
| 153 | /* Terminating entry */ | 139 | /* Terminating entry */ |
| 154 | { } | 140 | { } |
| 155 | }; | 141 | }; |
| 156 | 142 | ||
| 157 | MODULE_DEVICE_TABLE (usb, storage_usb_ids); | 143 | MODULE_DEVICE_TABLE (usb, storage_usb_ids); |
| 144 | #endif /* CONFIG_USB_LIBUSUAL */ | ||
| 158 | 145 | ||
| 159 | /* This is the list of devices we recognize, along with their flag data */ | 146 | /* This is the list of devices we recognize, along with their flag data */ |
| 160 | 147 | ||
| @@ -167,7 +154,6 @@ MODULE_DEVICE_TABLE (usb, storage_usb_ids); | |||
| 167 | * are free to use as many characters as you like. | 154 | * are free to use as many characters as you like. |
| 168 | */ | 155 | */ |
| 169 | 156 | ||
| 170 | #undef UNUSUAL_DEV | ||
| 171 | #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \ | 157 | #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \ |
| 172 | vendor_name, product_name, use_protocol, use_transport, \ | 158 | vendor_name, product_name, use_protocol, use_transport, \ |
| 173 | init_function, Flags) \ | 159 | init_function, Flags) \ |
| @@ -177,53 +163,18 @@ MODULE_DEVICE_TABLE (usb, storage_usb_ids); | |||
| 177 | .useProtocol = use_protocol, \ | 163 | .useProtocol = use_protocol, \ |
| 178 | .useTransport = use_transport, \ | 164 | .useTransport = use_transport, \ |
| 179 | .initFunction = init_function, \ | 165 | .initFunction = init_function, \ |
| 180 | .flags = Flags, \ | 166 | } |
| 167 | |||
| 168 | #define USUAL_DEV(use_protocol, use_transport, use_type) \ | ||
| 169 | { \ | ||
| 170 | .useProtocol = use_protocol, \ | ||
| 171 | .useTransport = use_transport, \ | ||
| 181 | } | 172 | } |
| 182 | 173 | ||
| 183 | static struct us_unusual_dev us_unusual_dev_list[] = { | 174 | static struct us_unusual_dev us_unusual_dev_list[] = { |
| 184 | # include "unusual_devs.h" | 175 | # include "unusual_devs.h" |
| 185 | # undef UNUSUAL_DEV | 176 | # undef UNUSUAL_DEV |
| 186 | /* Control/Bulk transport for all SubClass values */ | 177 | # undef USUAL_DEV |
| 187 | { .useProtocol = US_SC_RBC, | ||
| 188 | .useTransport = US_PR_CB}, | ||
| 189 | { .useProtocol = US_SC_8020, | ||
| 190 | .useTransport = US_PR_CB}, | ||
| 191 | { .useProtocol = US_SC_QIC, | ||
| 192 | .useTransport = US_PR_CB}, | ||
| 193 | { .useProtocol = US_SC_UFI, | ||
| 194 | .useTransport = US_PR_CB}, | ||
| 195 | { .useProtocol = US_SC_8070, | ||
| 196 | .useTransport = US_PR_CB}, | ||
| 197 | { .useProtocol = US_SC_SCSI, | ||
| 198 | .useTransport = US_PR_CB}, | ||
| 199 | |||
| 200 | /* Control/Bulk/Interrupt transport for all SubClass values */ | ||
| 201 | { .useProtocol = US_SC_RBC, | ||
| 202 | .useTransport = US_PR_CBI}, | ||
| 203 | { .useProtocol = US_SC_8020, | ||
| 204 | .useTransport = US_PR_CBI}, | ||
| 205 | { .useProtocol = US_SC_QIC, | ||
| 206 | .useTransport = US_PR_CBI}, | ||
| 207 | { .useProtocol = US_SC_UFI, | ||
| 208 | .useTransport = US_PR_CBI}, | ||
| 209 | { .useProtocol = US_SC_8070, | ||
| 210 | .useTransport = US_PR_CBI}, | ||
| 211 | { .useProtocol = US_SC_SCSI, | ||
| 212 | .useTransport = US_PR_CBI}, | ||
| 213 | |||
| 214 | /* Bulk-only transport for all SubClass values */ | ||
| 215 | { .useProtocol = US_SC_RBC, | ||
| 216 | .useTransport = US_PR_BULK}, | ||
| 217 | { .useProtocol = US_SC_8020, | ||
| 218 | .useTransport = US_PR_BULK}, | ||
| 219 | { .useProtocol = US_SC_QIC, | ||
| 220 | .useTransport = US_PR_BULK}, | ||
| 221 | { .useProtocol = US_SC_UFI, | ||
| 222 | .useTransport = US_PR_BULK}, | ||
| 223 | { .useProtocol = US_SC_8070, | ||
| 224 | .useTransport = US_PR_BULK}, | ||
| 225 | { .useProtocol = US_SC_SCSI, | ||
| 226 | .useTransport = US_PR_BULK}, | ||
| 227 | 178 | ||
| 228 | /* Terminating entry */ | 179 | /* Terminating entry */ |
| 229 | { NULL } | 180 | { NULL } |
| @@ -240,6 +191,8 @@ static int storage_suspend(struct usb_interface *iface, pm_message_t message) | |||
| 240 | down(&us->dev_semaphore); | 191 | down(&us->dev_semaphore); |
| 241 | 192 | ||
| 242 | US_DEBUGP("%s\n", __FUNCTION__); | 193 | US_DEBUGP("%s\n", __FUNCTION__); |
| 194 | if (us->suspend_resume_hook) | ||
| 195 | (us->suspend_resume_hook)(us, US_SUSPEND); | ||
| 243 | iface->dev.power.power_state.event = message.event; | 196 | iface->dev.power.power_state.event = message.event; |
| 244 | 197 | ||
| 245 | /* When runtime PM is working, we'll set a flag to indicate | 198 | /* When runtime PM is working, we'll set a flag to indicate |
| @@ -256,6 +209,8 @@ static int storage_resume(struct usb_interface *iface) | |||
| 256 | down(&us->dev_semaphore); | 209 | down(&us->dev_semaphore); |
| 257 | 210 | ||
| 258 | US_DEBUGP("%s\n", __FUNCTION__); | 211 | US_DEBUGP("%s\n", __FUNCTION__); |
| 212 | if (us->suspend_resume_hook) | ||
| 213 | (us->suspend_resume_hook)(us, US_RESUME); | ||
| 259 | iface->dev.power.power_state.event = PM_EVENT_ON; | 214 | iface->dev.power.power_state.event = PM_EVENT_ON; |
| 260 | 215 | ||
| 261 | up(&us->dev_semaphore); | 216 | up(&us->dev_semaphore); |
| @@ -484,14 +439,20 @@ static int associate_dev(struct us_data *us, struct usb_interface *intf) | |||
| 484 | return 0; | 439 | return 0; |
| 485 | } | 440 | } |
| 486 | 441 | ||
| 442 | /* Find an unusual_dev descriptor (always succeeds in the current code) */ | ||
| 443 | static struct us_unusual_dev *find_unusual(const struct usb_device_id *id) | ||
| 444 | { | ||
| 445 | const int id_index = id - storage_usb_ids; | ||
| 446 | return &us_unusual_dev_list[id_index]; | ||
| 447 | } | ||
| 448 | |||
| 487 | /* Get the unusual_devs entries and the string descriptors */ | 449 | /* Get the unusual_devs entries and the string descriptors */ |
| 488 | static void get_device_info(struct us_data *us, int id_index) | 450 | static void get_device_info(struct us_data *us, const struct usb_device_id *id) |
| 489 | { | 451 | { |
| 490 | struct usb_device *dev = us->pusb_dev; | 452 | struct usb_device *dev = us->pusb_dev; |
| 491 | struct usb_interface_descriptor *idesc = | 453 | struct usb_interface_descriptor *idesc = |
| 492 | &us->pusb_intf->cur_altsetting->desc; | 454 | &us->pusb_intf->cur_altsetting->desc; |
| 493 | struct us_unusual_dev *unusual_dev = &us_unusual_dev_list[id_index]; | 455 | struct us_unusual_dev *unusual_dev = find_unusual(id); |
| 494 | struct usb_device_id *id = &storage_usb_ids[id_index]; | ||
| 495 | 456 | ||
| 496 | /* Store the entries */ | 457 | /* Store the entries */ |
| 497 | us->unusual_dev = unusual_dev; | 458 | us->unusual_dev = unusual_dev; |
| @@ -501,7 +462,7 @@ static void get_device_info(struct us_data *us, int id_index) | |||
| 501 | us->protocol = (unusual_dev->useTransport == US_PR_DEVICE) ? | 462 | us->protocol = (unusual_dev->useTransport == US_PR_DEVICE) ? |
| 502 | idesc->bInterfaceProtocol : | 463 | idesc->bInterfaceProtocol : |
| 503 | unusual_dev->useTransport; | 464 | unusual_dev->useTransport; |
| 504 | us->flags = unusual_dev->flags; | 465 | us->flags = USB_US_ORIG_FLAGS(id->driver_info); |
| 505 | 466 | ||
| 506 | /* | 467 | /* |
| 507 | * This flag is only needed when we're in high-speed, so let's | 468 | * This flag is only needed when we're in high-speed, so let's |
| @@ -516,7 +477,7 @@ static void get_device_info(struct us_data *us, int id_index) | |||
| 516 | * from the unusual_devs.h table. | 477 | * from the unusual_devs.h table. |
| 517 | */ | 478 | */ |
| 518 | if (id->idVendor || id->idProduct) { | 479 | if (id->idVendor || id->idProduct) { |
| 519 | static char *msgs[3] = { | 480 | static const char *msgs[3] = { |
| 520 | "an unneeded SubClass entry", | 481 | "an unneeded SubClass entry", |
| 521 | "an unneeded Protocol entry", | 482 | "an unneeded Protocol entry", |
| 522 | "unneeded SubClass and Protocol entries"}; | 483 | "unneeded SubClass and Protocol entries"}; |
| @@ -529,7 +490,7 @@ static void get_device_info(struct us_data *us, int id_index) | |||
| 529 | if (unusual_dev->useTransport != US_PR_DEVICE && | 490 | if (unusual_dev->useTransport != US_PR_DEVICE && |
| 530 | us->protocol == idesc->bInterfaceProtocol) | 491 | us->protocol == idesc->bInterfaceProtocol) |
| 531 | msg += 2; | 492 | msg += 2; |
| 532 | if (msg >= 0 && !(unusual_dev->flags & US_FL_NEED_OVERRIDE)) | 493 | if (msg >= 0 && !(us->flags & US_FL_NEED_OVERRIDE)) |
| 533 | printk(KERN_NOTICE USB_STORAGE "This device " | 494 | printk(KERN_NOTICE USB_STORAGE "This device " |
| 534 | "(%04x,%04x,%04x S %02x P %02x)" | 495 | "(%04x,%04x,%04x S %02x P %02x)" |
| 535 | " has %s in unusual_devs.h\n" | 496 | " has %s in unusual_devs.h\n" |
| @@ -686,6 +647,15 @@ static int get_protocol(struct us_data *us) | |||
| 686 | break; | 647 | break; |
| 687 | #endif | 648 | #endif |
| 688 | 649 | ||
| 650 | #ifdef CONFIG_USB_STORAGE_ALAUDA | ||
| 651 | case US_PR_ALAUDA: | ||
| 652 | us->transport_name = "Alauda Control/Bulk"; | ||
| 653 | us->transport = alauda_transport; | ||
| 654 | us->transport_reset = usb_stor_Bulk_reset; | ||
| 655 | us->max_lun = 1; | ||
| 656 | break; | ||
| 657 | #endif | ||
| 658 | |||
| 689 | default: | 659 | default: |
| 690 | return -EIO; | 660 | return -EIO; |
| 691 | } | 661 | } |
| @@ -921,10 +891,12 @@ static int storage_probe(struct usb_interface *intf, | |||
| 921 | { | 891 | { |
| 922 | struct Scsi_Host *host; | 892 | struct Scsi_Host *host; |
| 923 | struct us_data *us; | 893 | struct us_data *us; |
| 924 | const int id_index = id - storage_usb_ids; | ||
| 925 | int result; | 894 | int result; |
| 926 | struct task_struct *th; | 895 | struct task_struct *th; |
| 927 | 896 | ||
| 897 | if (usb_usual_check_type(id, USB_US_TYPE_STOR)) | ||
| 898 | return -ENXIO; | ||
| 899 | |||
| 928 | US_DEBUGP("USB Mass Storage device detected\n"); | 900 | US_DEBUGP("USB Mass Storage device detected\n"); |
| 929 | 901 | ||
| 930 | /* | 902 | /* |
| @@ -957,29 +929,7 @@ static int storage_probe(struct usb_interface *intf, | |||
| 957 | * of the match from the usb_device_id table, so we can find the | 929 | * of the match from the usb_device_id table, so we can find the |
| 958 | * corresponding entry in the private table. | 930 | * corresponding entry in the private table. |
| 959 | */ | 931 | */ |
| 960 | get_device_info(us, id_index); | 932 | get_device_info(us, id); |
| 961 | |||
| 962 | #ifdef CONFIG_USB_STORAGE_SDDR09 | ||
| 963 | if (us->protocol == US_PR_EUSB_SDDR09 || | ||
| 964 | us->protocol == US_PR_DPCM_USB) { | ||
| 965 | /* set the configuration -- STALL is an acceptable response here */ | ||
| 966 | if (us->pusb_dev->actconfig->desc.bConfigurationValue != 1) { | ||
| 967 | US_DEBUGP("active config #%d != 1 ??\n", us->pusb_dev | ||
| 968 | ->actconfig->desc.bConfigurationValue); | ||
| 969 | goto BadDevice; | ||
| 970 | } | ||
| 971 | result = usb_reset_configuration(us->pusb_dev); | ||
| 972 | |||
| 973 | US_DEBUGP("Result of usb_reset_configuration is %d\n", result); | ||
| 974 | if (result == -EPIPE) { | ||
| 975 | US_DEBUGP("-- stall on control interface\n"); | ||
| 976 | } else if (result != 0) { | ||
| 977 | /* it's not a stall, but another error -- time to bail */ | ||
| 978 | US_DEBUGP("-- Unknown error. Rejecting device\n"); | ||
| 979 | goto BadDevice; | ||
| 980 | } | ||
| 981 | } | ||
| 982 | #endif | ||
| 983 | 933 | ||
| 984 | /* Get the transport, protocol, and pipe settings */ | 934 | /* Get the transport, protocol, and pipe settings */ |
| 985 | result = get_transport(us); | 935 | result = get_transport(us); |
| @@ -1044,7 +994,6 @@ static void storage_disconnect(struct usb_interface *intf) | |||
| 1044 | ***********************************************************************/ | 994 | ***********************************************************************/ |
| 1045 | 995 | ||
| 1046 | static struct usb_driver usb_storage_driver = { | 996 | static struct usb_driver usb_storage_driver = { |
| 1047 | .owner = THIS_MODULE, | ||
| 1048 | .name = "usb-storage", | 997 | .name = "usb-storage", |
| 1049 | .probe = storage_probe, | 998 | .probe = storage_probe, |
| 1050 | .disconnect = storage_disconnect, | 999 | .disconnect = storage_disconnect, |
| @@ -1062,9 +1011,10 @@ static int __init usb_stor_init(void) | |||
| 1062 | 1011 | ||
| 1063 | /* register the driver, return usb_register return code if error */ | 1012 | /* register the driver, return usb_register return code if error */ |
| 1064 | retval = usb_register(&usb_storage_driver); | 1013 | retval = usb_register(&usb_storage_driver); |
| 1065 | if (retval == 0) | 1014 | if (retval == 0) { |
| 1066 | printk(KERN_INFO "USB Mass Storage support registered.\n"); | 1015 | printk(KERN_INFO "USB Mass Storage support registered.\n"); |
| 1067 | 1016 | usb_usual_set_present(USB_US_TYPE_STOR); | |
| 1017 | } | ||
| 1068 | return retval; | 1018 | return retval; |
| 1069 | } | 1019 | } |
| 1070 | 1020 | ||
| @@ -1088,6 +1038,8 @@ static void __exit usb_stor_exit(void) | |||
| 1088 | wait_for_completion(&threads_gone); | 1038 | wait_for_completion(&threads_gone); |
| 1089 | atomic_dec(&total_threads); | 1039 | atomic_dec(&total_threads); |
| 1090 | } | 1040 | } |
| 1041 | |||
| 1042 | usb_usual_clear_present(USB_US_TYPE_STOR); | ||
| 1091 | } | 1043 | } |
| 1092 | 1044 | ||
| 1093 | module_init(usb_stor_init); | 1045 | module_init(usb_stor_init); |
diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h index 98b09711a739..7259fd1f6b0d 100644 --- a/drivers/usb/storage/usb.h +++ b/drivers/usb/storage/usb.h | |||
| @@ -45,6 +45,7 @@ | |||
| 45 | #define _USB_H_ | 45 | #define _USB_H_ |
| 46 | 46 | ||
| 47 | #include <linux/usb.h> | 47 | #include <linux/usb.h> |
| 48 | #include <linux/usb_usual.h> | ||
| 48 | #include <linux/blkdev.h> | 49 | #include <linux/blkdev.h> |
| 49 | #include <linux/smp_lock.h> | 50 | #include <linux/smp_lock.h> |
| 50 | #include <linux/completion.h> | 51 | #include <linux/completion.h> |
| @@ -63,38 +64,8 @@ struct us_unusual_dev { | |||
| 63 | __u8 useProtocol; | 64 | __u8 useProtocol; |
| 64 | __u8 useTransport; | 65 | __u8 useTransport; |
| 65 | int (*initFunction)(struct us_data *); | 66 | int (*initFunction)(struct us_data *); |
| 66 | unsigned int flags; | ||
| 67 | }; | 67 | }; |
| 68 | 68 | ||
| 69 | /* | ||
| 70 | * Static flag definitions. We use this roundabout technique so that the | ||
| 71 | * proc_info() routine can automatically display a message for each flag. | ||
| 72 | */ | ||
| 73 | #define US_DO_ALL_FLAGS \ | ||
| 74 | US_FLAG(SINGLE_LUN, 0x00000001) \ | ||
| 75 | /* allow access to only LUN 0 */ \ | ||
| 76 | US_FLAG(NEED_OVERRIDE, 0x00000002) \ | ||
| 77 | /* unusual_devs entry is necessary */ \ | ||
| 78 | US_FLAG(SCM_MULT_TARG, 0x00000004) \ | ||
| 79 | /* supports multiple targets */ \ | ||
| 80 | US_FLAG(FIX_INQUIRY, 0x00000008) \ | ||
| 81 | /* INQUIRY response needs faking */ \ | ||
| 82 | US_FLAG(FIX_CAPACITY, 0x00000010) \ | ||
| 83 | /* READ CAPACITY response too big */ \ | ||
| 84 | US_FLAG(IGNORE_RESIDUE, 0x00000020) \ | ||
| 85 | /* reported residue is wrong */ \ | ||
| 86 | US_FLAG(BULK32, 0x00000040) \ | ||
| 87 | /* Uses 32-byte CBW length */ \ | ||
| 88 | US_FLAG(NOT_LOCKABLE, 0x00000080) \ | ||
| 89 | /* PREVENT/ALLOW not supported */ \ | ||
| 90 | US_FLAG(GO_SLOW, 0x00000100) \ | ||
| 91 | /* Need delay after Command phase */ \ | ||
| 92 | US_FLAG(NO_WP_DETECT, 0x00000200) \ | ||
| 93 | /* Don't check for write-protect */ \ | ||
| 94 | |||
| 95 | #define US_FLAG(name, value) US_FL_##name = value , | ||
| 96 | enum { US_DO_ALL_FLAGS }; | ||
| 97 | #undef US_FLAG | ||
| 98 | 69 | ||
| 99 | /* Dynamic flag definitions: used in set_bit() etc. */ | 70 | /* Dynamic flag definitions: used in set_bit() etc. */ |
| 100 | #define US_FLIDX_URB_ACTIVE 18 /* 0x00040000 current_urb is in use */ | 71 | #define US_FLIDX_URB_ACTIVE 18 /* 0x00040000 current_urb is in use */ |
| @@ -122,7 +93,11 @@ enum { US_DO_ALL_FLAGS }; | |||
| 122 | typedef int (*trans_cmnd)(struct scsi_cmnd *, struct us_data*); | 93 | typedef int (*trans_cmnd)(struct scsi_cmnd *, struct us_data*); |
| 123 | typedef int (*trans_reset)(struct us_data*); | 94 | typedef int (*trans_reset)(struct us_data*); |
| 124 | typedef void (*proto_cmnd)(struct scsi_cmnd*, struct us_data*); | 95 | typedef void (*proto_cmnd)(struct scsi_cmnd*, struct us_data*); |
| 125 | typedef void (*extra_data_destructor)(void *); /* extra data destructor */ | 96 | typedef void (*extra_data_destructor)(void *); /* extra data destructor */ |
| 97 | typedef void (*pm_hook)(struct us_data *, int); /* power management hook */ | ||
| 98 | |||
| 99 | #define US_SUSPEND 0 | ||
| 100 | #define US_RESUME 1 | ||
| 126 | 101 | ||
| 127 | /* we allocate one of these for every device that we remember */ | 102 | /* we allocate one of these for every device that we remember */ |
| 128 | struct us_data { | 103 | struct us_data { |
| @@ -178,6 +153,9 @@ struct us_data { | |||
| 178 | /* subdriver information */ | 153 | /* subdriver information */ |
| 179 | void *extra; /* Any extra data */ | 154 | void *extra; /* Any extra data */ |
| 180 | extra_data_destructor extra_destructor;/* extra data destructor */ | 155 | extra_data_destructor extra_destructor;/* extra data destructor */ |
| 156 | #ifdef CONFIG_PM | ||
| 157 | pm_hook suspend_resume_hook; | ||
| 158 | #endif | ||
| 181 | }; | 159 | }; |
| 182 | 160 | ||
| 183 | /* Convert between us_data and the corresponding Scsi_Host */ | 161 | /* Convert between us_data and the corresponding Scsi_Host */ |
diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c index 6c3a53f8f26c..5d02f16b7d0e 100644 --- a/drivers/usb/usb-skeleton.c +++ b/drivers/usb/usb-skeleton.c | |||
| @@ -39,10 +39,15 @@ MODULE_DEVICE_TABLE (usb, skel_table); | |||
| 39 | /* Get a minor range for your devices from the usb maintainer */ | 39 | /* Get a minor range for your devices from the usb maintainer */ |
| 40 | #define USB_SKEL_MINOR_BASE 192 | 40 | #define USB_SKEL_MINOR_BASE 192 |
| 41 | 41 | ||
| 42 | /* our private defines. if this grows any larger, use your own .h file */ | ||
| 43 | #define MAX_TRANSFER ( PAGE_SIZE - 512 ) | ||
| 44 | #define WRITES_IN_FLIGHT 8 | ||
| 45 | |||
| 42 | /* Structure to hold all of our device specific stuff */ | 46 | /* Structure to hold all of our device specific stuff */ |
| 43 | struct usb_skel { | 47 | struct usb_skel { |
| 44 | struct usb_device * udev; /* the usb device for this device */ | 48 | struct usb_device * udev; /* the usb device for this device */ |
| 45 | struct usb_interface * interface; /* the interface for this device */ | 49 | struct usb_interface * interface; /* the interface for this device */ |
| 50 | struct semaphore limit_sem; /* limiting the number of writes in progress */ | ||
| 46 | unsigned char * bulk_in_buffer; /* the buffer to receive data */ | 51 | unsigned char * bulk_in_buffer; /* the buffer to receive data */ |
| 47 | size_t bulk_in_size; /* the size of the receive buffer */ | 52 | size_t bulk_in_size; /* the size of the receive buffer */ |
| 48 | __u8 bulk_in_endpointAddr; /* the address of the bulk in endpoint */ | 53 | __u8 bulk_in_endpointAddr; /* the address of the bulk in endpoint */ |
| @@ -152,6 +157,7 @@ static void skel_write_bulk_callback(struct urb *urb, struct pt_regs *regs) | |||
| 152 | /* free up our allocated buffer */ | 157 | /* free up our allocated buffer */ |
| 153 | usb_buffer_free(urb->dev, urb->transfer_buffer_length, | 158 | usb_buffer_free(urb->dev, urb->transfer_buffer_length, |
| 154 | urb->transfer_buffer, urb->transfer_dma); | 159 | urb->transfer_buffer, urb->transfer_dma); |
| 160 | up(&dev->limit_sem); | ||
| 155 | } | 161 | } |
| 156 | 162 | ||
| 157 | static ssize_t skel_write(struct file *file, const char *user_buffer, size_t count, loff_t *ppos) | 163 | static ssize_t skel_write(struct file *file, const char *user_buffer, size_t count, loff_t *ppos) |
| @@ -160,6 +166,7 @@ static ssize_t skel_write(struct file *file, const char *user_buffer, size_t cou | |||
| 160 | int retval = 0; | 166 | int retval = 0; |
| 161 | struct urb *urb = NULL; | 167 | struct urb *urb = NULL; |
| 162 | char *buf = NULL; | 168 | char *buf = NULL; |
| 169 | size_t writesize = min(count, (size_t)MAX_TRANSFER); | ||
| 163 | 170 | ||
| 164 | dev = (struct usb_skel *)file->private_data; | 171 | dev = (struct usb_skel *)file->private_data; |
| 165 | 172 | ||
| @@ -167,6 +174,12 @@ static ssize_t skel_write(struct file *file, const char *user_buffer, size_t cou | |||
| 167 | if (count == 0) | 174 | if (count == 0) |
| 168 | goto exit; | 175 | goto exit; |
| 169 | 176 | ||
| 177 | /* limit the number of URBs in flight to stop a user from using up all RAM */ | ||
| 178 | if (down_interruptible(&dev->limit_sem)) { | ||
| 179 | retval = -ERESTARTSYS; | ||
| 180 | goto exit; | ||
| 181 | } | ||
| 182 | |||
| 170 | /* create a urb, and a buffer for it, and copy the data to the urb */ | 183 | /* create a urb, and a buffer for it, and copy the data to the urb */ |
| 171 | urb = usb_alloc_urb(0, GFP_KERNEL); | 184 | urb = usb_alloc_urb(0, GFP_KERNEL); |
| 172 | if (!urb) { | 185 | if (!urb) { |
| @@ -174,13 +187,13 @@ static ssize_t skel_write(struct file *file, const char *user_buffer, size_t cou | |||
| 174 | goto error; | 187 | goto error; |
| 175 | } | 188 | } |
| 176 | 189 | ||
| 177 | buf = usb_buffer_alloc(dev->udev, count, GFP_KERNEL, &urb->transfer_dma); | 190 | buf = usb_buffer_alloc(dev->udev, writesize, GFP_KERNEL, &urb->transfer_dma); |
| 178 | if (!buf) { | 191 | if (!buf) { |
| 179 | retval = -ENOMEM; | 192 | retval = -ENOMEM; |
| 180 | goto error; | 193 | goto error; |
| 181 | } | 194 | } |
| 182 | 195 | ||
| 183 | if (copy_from_user(buf, user_buffer, count)) { | 196 | if (copy_from_user(buf, user_buffer, writesize)) { |
| 184 | retval = -EFAULT; | 197 | retval = -EFAULT; |
| 185 | goto error; | 198 | goto error; |
| 186 | } | 199 | } |
| @@ -188,7 +201,7 @@ static ssize_t skel_write(struct file *file, const char *user_buffer, size_t cou | |||
| 188 | /* initialize the urb properly */ | 201 | /* initialize the urb properly */ |
| 189 | usb_fill_bulk_urb(urb, dev->udev, | 202 | usb_fill_bulk_urb(urb, dev->udev, |
| 190 | usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr), | 203 | usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr), |
| 191 | buf, count, skel_write_bulk_callback, dev); | 204 | buf, writesize, skel_write_bulk_callback, dev); |
| 192 | urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 205 | urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
| 193 | 206 | ||
| 194 | /* send the data out the bulk port */ | 207 | /* send the data out the bulk port */ |
| @@ -202,11 +215,12 @@ static ssize_t skel_write(struct file *file, const char *user_buffer, size_t cou | |||
| 202 | usb_free_urb(urb); | 215 | usb_free_urb(urb); |
| 203 | 216 | ||
| 204 | exit: | 217 | exit: |
| 205 | return count; | 218 | return writesize; |
| 206 | 219 | ||
| 207 | error: | 220 | error: |
| 208 | usb_buffer_free(dev->udev, count, buf, urb->transfer_dma); | 221 | usb_buffer_free(dev->udev, writesize, buf, urb->transfer_dma); |
| 209 | usb_free_urb(urb); | 222 | usb_free_urb(urb); |
| 223 | up(&dev->limit_sem); | ||
| 210 | return retval; | 224 | return retval; |
| 211 | } | 225 | } |
| 212 | 226 | ||
| @@ -238,13 +252,13 @@ static int skel_probe(struct usb_interface *interface, const struct usb_device_i | |||
| 238 | int retval = -ENOMEM; | 252 | int retval = -ENOMEM; |
| 239 | 253 | ||
| 240 | /* allocate memory for our device state and initialize it */ | 254 | /* allocate memory for our device state and initialize it */ |
| 241 | dev = kmalloc(sizeof(*dev), GFP_KERNEL); | 255 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
| 242 | if (dev == NULL) { | 256 | if (dev == NULL) { |
| 243 | err("Out of memory"); | 257 | err("Out of memory"); |
| 244 | goto error; | 258 | goto error; |
| 245 | } | 259 | } |
| 246 | memset(dev, 0x00, sizeof(*dev)); | ||
| 247 | kref_init(&dev->kref); | 260 | kref_init(&dev->kref); |
| 261 | sema_init(&dev->limit_sem, WRITES_IN_FLIGHT); | ||
| 248 | 262 | ||
| 249 | dev->udev = usb_get_dev(interface_to_usbdev(interface)); | 263 | dev->udev = usb_get_dev(interface_to_usbdev(interface)); |
| 250 | dev->interface = interface; | 264 | dev->interface = interface; |
| @@ -330,7 +344,6 @@ static void skel_disconnect(struct usb_interface *interface) | |||
| 330 | } | 344 | } |
| 331 | 345 | ||
| 332 | static struct usb_driver skel_driver = { | 346 | static struct usb_driver skel_driver = { |
| 333 | .owner = THIS_MODULE, | ||
| 334 | .name = "skeleton", | 347 | .name = "skeleton", |
| 335 | .probe = skel_probe, | 348 | .probe = skel_probe, |
| 336 | .disconnect = skel_disconnect, | 349 | .disconnect = skel_disconnect, |
diff --git a/drivers/w1/dscore.c b/drivers/w1/dscore.c index 15fb250451e5..b9146306df49 100644 --- a/drivers/w1/dscore.c +++ b/drivers/w1/dscore.c | |||
| @@ -52,7 +52,6 @@ static int ds_send_control_cmd(struct ds_device *, u16, u16); | |||
| 52 | 52 | ||
| 53 | 53 | ||
| 54 | static struct usb_driver ds_driver = { | 54 | static struct usb_driver ds_driver = { |
| 55 | .owner = THIS_MODULE, | ||
| 56 | .name = "DS9490R", | 55 | .name = "DS9490R", |
| 57 | .probe = ds_probe, | 56 | .probe = ds_probe, |
| 58 | .disconnect = ds_disconnect, | 57 | .disconnect = ds_disconnect, |
diff --git a/include/asm-arm/arch-pxa/ohci.h b/include/asm-arm/arch-pxa/ohci.h new file mode 100644 index 000000000000..7da89569061e --- /dev/null +++ b/include/asm-arm/arch-pxa/ohci.h | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | #ifndef ASMARM_ARCH_OHCI_H | ||
| 2 | #define ASMARM_ARCH_OHCI_H | ||
| 3 | |||
| 4 | struct device; | ||
| 5 | |||
| 6 | struct pxaohci_platform_data { | ||
| 7 | int (*init)(struct device *); | ||
| 8 | void (*exit)(struct device *); | ||
| 9 | |||
| 10 | int port_mode; | ||
| 11 | #define PMM_NPS_MODE 1 | ||
| 12 | #define PMM_GLOBAL_MODE 2 | ||
| 13 | #define PMM_PERPORT_MODE 3 | ||
| 14 | }; | ||
| 15 | |||
| 16 | extern void pxa_set_ohci_info(struct pxaohci_platform_data *info); | ||
| 17 | |||
| 18 | #endif | ||
diff --git a/include/linux/usb.h b/include/linux/usb.h index d81b050e5955..e59d1bd52d4f 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h | |||
| @@ -329,8 +329,6 @@ struct usb_device { | |||
| 329 | struct usb_tt *tt; /* low/full speed dev, highspeed hub */ | 329 | struct usb_tt *tt; /* low/full speed dev, highspeed hub */ |
| 330 | int ttport; /* device port on that tt hub */ | 330 | int ttport; /* device port on that tt hub */ |
| 331 | 331 | ||
| 332 | struct semaphore serialize; | ||
| 333 | |||
| 334 | unsigned int toggle[2]; /* one bit for each endpoint | 332 | unsigned int toggle[2]; /* one bit for each endpoint |
| 335 | * ([0] = IN, [1] = OUT) */ | 333 | * ([0] = IN, [1] = OUT) */ |
| 336 | 334 | ||
| @@ -349,6 +347,9 @@ struct usb_device { | |||
| 349 | 347 | ||
| 350 | char **rawdescriptors; /* Raw descriptors for each config */ | 348 | char **rawdescriptors; /* Raw descriptors for each config */ |
| 351 | 349 | ||
| 350 | unsigned short bus_mA; /* Current available from the bus */ | ||
| 351 | u8 portnum; /* Parent port number (origin 1) */ | ||
| 352 | |||
| 352 | int have_langid; /* whether string_langid is valid */ | 353 | int have_langid; /* whether string_langid is valid */ |
| 353 | int string_langid; /* language ID for strings */ | 354 | int string_langid; /* language ID for strings */ |
| 354 | 355 | ||
| @@ -377,11 +378,12 @@ struct usb_device { | |||
| 377 | extern struct usb_device *usb_get_dev(struct usb_device *dev); | 378 | extern struct usb_device *usb_get_dev(struct usb_device *dev); |
| 378 | extern void usb_put_dev(struct usb_device *dev); | 379 | extern void usb_put_dev(struct usb_device *dev); |
| 379 | 380 | ||
| 380 | extern void usb_lock_device(struct usb_device *udev); | 381 | /* USB device locking */ |
| 381 | extern int usb_trylock_device(struct usb_device *udev); | 382 | #define usb_lock_device(udev) down(&(udev)->dev.sem) |
| 383 | #define usb_unlock_device(udev) up(&(udev)->dev.sem) | ||
| 384 | #define usb_trylock_device(udev) down_trylock(&(udev)->dev.sem) | ||
| 382 | extern int usb_lock_device_for_reset(struct usb_device *udev, | 385 | extern int usb_lock_device_for_reset(struct usb_device *udev, |
| 383 | struct usb_interface *iface); | 386 | struct usb_interface *iface); |
| 384 | extern void usb_unlock_device(struct usb_device *udev); | ||
| 385 | 387 | ||
| 386 | /* USB port reset for device reinitialization */ | 388 | /* USB port reset for device reinitialization */ |
| 387 | extern int usb_reset_device(struct usb_device *dev); | 389 | extern int usb_reset_device(struct usb_device *dev); |
| @@ -529,10 +531,13 @@ static inline int usb_make_path (struct usb_device *dev, char *buf, | |||
| 529 | 531 | ||
| 530 | /* ----------------------------------------------------------------------- */ | 532 | /* ----------------------------------------------------------------------- */ |
| 531 | 533 | ||
| 534 | struct usb_dynids { | ||
| 535 | spinlock_t lock; | ||
| 536 | struct list_head list; | ||
| 537 | }; | ||
| 538 | |||
| 532 | /** | 539 | /** |
| 533 | * struct usb_driver - identifies USB driver to usbcore | 540 | * struct usb_driver - identifies USB driver to usbcore |
| 534 | * @owner: Pointer to the module owner of this driver; initialize | ||
| 535 | * it using THIS_MODULE. | ||
| 536 | * @name: The driver name should be unique among USB drivers, | 541 | * @name: The driver name should be unique among USB drivers, |
| 537 | * and should normally be the same as the module name. | 542 | * and should normally be the same as the module name. |
| 538 | * @probe: Called to see if the driver is willing to manage a particular | 543 | * @probe: Called to see if the driver is willing to manage a particular |
| @@ -553,7 +558,11 @@ static inline int usb_make_path (struct usb_device *dev, char *buf, | |||
| 553 | * @id_table: USB drivers use ID table to support hotplugging. | 558 | * @id_table: USB drivers use ID table to support hotplugging. |
| 554 | * Export this with MODULE_DEVICE_TABLE(usb,...). This must be set | 559 | * Export this with MODULE_DEVICE_TABLE(usb,...). This must be set |
| 555 | * or your driver's probe function will never get called. | 560 | * or your driver's probe function will never get called. |
| 561 | * @dynids: used internally to hold the list of dynamically added device | ||
| 562 | * ids for this driver. | ||
| 556 | * @driver: the driver model core driver structure. | 563 | * @driver: the driver model core driver structure. |
| 564 | * @no_dynamic_id: if set to 1, the USB core will not allow dynamic ids to be | ||
| 565 | * added to this driver by preventing the sysfs file from being created. | ||
| 557 | * | 566 | * |
| 558 | * USB drivers must provide a name, probe() and disconnect() methods, | 567 | * USB drivers must provide a name, probe() and disconnect() methods, |
| 559 | * and an id_table. Other driver fields are optional. | 568 | * and an id_table. Other driver fields are optional. |
| @@ -571,8 +580,6 @@ static inline int usb_make_path (struct usb_device *dev, char *buf, | |||
| 571 | * them as necessary, and blocking until the unlinks complete). | 580 | * them as necessary, and blocking until the unlinks complete). |
| 572 | */ | 581 | */ |
| 573 | struct usb_driver { | 582 | struct usb_driver { |
| 574 | struct module *owner; | ||
| 575 | |||
| 576 | const char *name; | 583 | const char *name; |
| 577 | 584 | ||
| 578 | int (*probe) (struct usb_interface *intf, | 585 | int (*probe) (struct usb_interface *intf, |
| @@ -588,7 +595,9 @@ struct usb_driver { | |||
| 588 | 595 | ||
| 589 | const struct usb_device_id *id_table; | 596 | const struct usb_device_id *id_table; |
| 590 | 597 | ||
| 598 | struct usb_dynids dynids; | ||
| 591 | struct device_driver driver; | 599 | struct device_driver driver; |
| 600 | unsigned int no_dynamic_id:1; | ||
| 592 | }; | 601 | }; |
| 593 | #define to_usb_driver(d) container_of(d, struct usb_driver, driver) | 602 | #define to_usb_driver(d) container_of(d, struct usb_driver, driver) |
| 594 | 603 | ||
| @@ -614,7 +623,11 @@ struct usb_class_driver { | |||
| 614 | * use these in module_init()/module_exit() | 623 | * use these in module_init()/module_exit() |
| 615 | * and don't forget MODULE_DEVICE_TABLE(usb, ...) | 624 | * and don't forget MODULE_DEVICE_TABLE(usb, ...) |
| 616 | */ | 625 | */ |
| 617 | extern int usb_register(struct usb_driver *); | 626 | int usb_register_driver(struct usb_driver *, struct module *); |
| 627 | static inline int usb_register(struct usb_driver *driver) | ||
| 628 | { | ||
| 629 | return usb_register_driver(driver, THIS_MODULE); | ||
| 630 | } | ||
| 618 | extern void usb_deregister(struct usb_driver *); | 631 | extern void usb_deregister(struct usb_driver *); |
| 619 | 632 | ||
| 620 | extern int usb_register_dev(struct usb_interface *intf, | 633 | extern int usb_register_dev(struct usb_interface *intf, |
diff --git a/include/linux/usb_usual.h b/include/linux/usb_usual.h new file mode 100644 index 000000000000..b2d08984a9f7 --- /dev/null +++ b/include/linux/usb_usual.h | |||
| @@ -0,0 +1,126 @@ | |||
| 1 | /* | ||
| 2 | * Interface to the libusual. | ||
| 3 | * | ||
| 4 | * Copyright (c) 2005 Pete Zaitcev <zaitcev@redhat.com> | ||
| 5 | * Copyright (c) 1999-2002 Matthew Dharm (mdharm-usb@one-eyed-alien.net) | ||
| 6 | * Copyright (c) 1999 Michael Gee (michael@linuxspecific.com) | ||
| 7 | */ | ||
| 8 | |||
| 9 | #ifndef __LINUX_USB_USUAL_H | ||
| 10 | #define __LINUX_USB_USUAL_H | ||
| 11 | |||
| 12 | #include <linux/config.h> | ||
| 13 | |||
| 14 | /* We should do this for cleanliness... But other usb_foo.h do not do this. */ | ||
| 15 | /* #include <linux/usb.h> */ | ||
| 16 | |||
| 17 | /* | ||
| 18 | * The flags field, which we store in usb_device_id.driver_info. | ||
| 19 | * It is compatible with the old usb-storage flags in lower 24 bits. | ||
| 20 | */ | ||
| 21 | |||
| 22 | /* | ||
| 23 | * Static flag definitions. We use this roundabout technique so that the | ||
| 24 | * proc_info() routine can automatically display a message for each flag. | ||
| 25 | */ | ||
| 26 | #define US_DO_ALL_FLAGS \ | ||
| 27 | US_FLAG(SINGLE_LUN, 0x00000001) \ | ||
| 28 | /* allow access to only LUN 0 */ \ | ||
| 29 | US_FLAG(NEED_OVERRIDE, 0x00000002) \ | ||
| 30 | /* unusual_devs entry is necessary */ \ | ||
| 31 | US_FLAG(SCM_MULT_TARG, 0x00000004) \ | ||
| 32 | /* supports multiple targets */ \ | ||
| 33 | US_FLAG(FIX_INQUIRY, 0x00000008) \ | ||
| 34 | /* INQUIRY response needs faking */ \ | ||
| 35 | US_FLAG(FIX_CAPACITY, 0x00000010) \ | ||
| 36 | /* READ CAPACITY response too big */ \ | ||
| 37 | US_FLAG(IGNORE_RESIDUE, 0x00000020) \ | ||
| 38 | /* reported residue is wrong */ \ | ||
| 39 | US_FLAG(BULK32, 0x00000040) \ | ||
| 40 | /* Uses 32-byte CBW length */ \ | ||
| 41 | US_FLAG(NOT_LOCKABLE, 0x00000080) \ | ||
| 42 | /* PREVENT/ALLOW not supported */ \ | ||
| 43 | US_FLAG(GO_SLOW, 0x00000100) \ | ||
| 44 | /* Need delay after Command phase */ \ | ||
| 45 | US_FLAG(NO_WP_DETECT, 0x00000200) \ | ||
| 46 | /* Don't check for write-protect */ \ | ||
| 47 | |||
| 48 | #define US_FLAG(name, value) US_FL_##name = value , | ||
| 49 | enum { US_DO_ALL_FLAGS }; | ||
| 50 | #undef US_FLAG | ||
| 51 | |||
| 52 | /* | ||
| 53 | * The bias field for libusual and friends. | ||
| 54 | */ | ||
| 55 | #define USB_US_TYPE_NONE 0 | ||
| 56 | #define USB_US_TYPE_STOR 1 /* usb-storage */ | ||
| 57 | #define USB_US_TYPE_UB 2 /* ub */ | ||
| 58 | |||
| 59 | #define USB_US_TYPE(flags) (((flags) >> 24) & 0xFF) | ||
| 60 | #define USB_US_ORIG_FLAGS(flags) ((flags) & 0x00FFFFFF) | ||
| 61 | |||
| 62 | /* | ||
| 63 | * This is probably not the best place to keep these constants, conceptually. | ||
| 64 | * But it's the only header included into all places which need them. | ||
| 65 | */ | ||
| 66 | |||
| 67 | /* Sub Classes */ | ||
| 68 | |||
| 69 | #define US_SC_RBC 0x01 /* Typically, flash devices */ | ||
| 70 | #define US_SC_8020 0x02 /* CD-ROM */ | ||
| 71 | #define US_SC_QIC 0x03 /* QIC-157 Tapes */ | ||
| 72 | #define US_SC_UFI 0x04 /* Floppy */ | ||
| 73 | #define US_SC_8070 0x05 /* Removable media */ | ||
| 74 | #define US_SC_SCSI 0x06 /* Transparent */ | ||
| 75 | #define US_SC_ISD200 0x07 /* ISD200 ATA */ | ||
| 76 | #define US_SC_MIN US_SC_RBC | ||
| 77 | #define US_SC_MAX US_SC_ISD200 | ||
| 78 | |||
| 79 | #define US_SC_DEVICE 0xff /* Use device's value */ | ||
| 80 | |||
| 81 | /* Protocols */ | ||
| 82 | |||
| 83 | #define US_PR_CBI 0x00 /* Control/Bulk/Interrupt */ | ||
| 84 | #define US_PR_CB 0x01 /* Control/Bulk w/o interrupt */ | ||
| 85 | #define US_PR_BULK 0x50 /* bulk only */ | ||
| 86 | #ifdef CONFIG_USB_STORAGE_USBAT | ||
| 87 | #define US_PR_USBAT 0x80 /* SCM-ATAPI bridge */ | ||
| 88 | #endif | ||
| 89 | #ifdef CONFIG_USB_STORAGE_SDDR09 | ||
| 90 | #define US_PR_EUSB_SDDR09 0x81 /* SCM-SCSI bridge for SDDR-09 */ | ||
| 91 | #endif | ||
| 92 | #ifdef CONFIG_USB_STORAGE_SDDR55 | ||
| 93 | #define US_PR_SDDR55 0x82 /* SDDR-55 (made up) */ | ||
| 94 | #endif | ||
| 95 | #define US_PR_DPCM_USB 0xf0 /* Combination CB/SDDR09 */ | ||
| 96 | #ifdef CONFIG_USB_STORAGE_FREECOM | ||
| 97 | #define US_PR_FREECOM 0xf1 /* Freecom */ | ||
| 98 | #endif | ||
| 99 | #ifdef CONFIG_USB_STORAGE_DATAFAB | ||
| 100 | #define US_PR_DATAFAB 0xf2 /* Datafab chipsets */ | ||
| 101 | #endif | ||
| 102 | #ifdef CONFIG_USB_STORAGE_JUMPSHOT | ||
| 103 | #define US_PR_JUMPSHOT 0xf3 /* Lexar Jumpshot */ | ||
| 104 | #endif | ||
| 105 | #ifdef CONFIG_USB_STORAGE_ALAUDA | ||
| 106 | #define US_PR_ALAUDA 0xf4 /* Alauda chipsets */ | ||
| 107 | #endif | ||
| 108 | |||
| 109 | #define US_PR_DEVICE 0xff /* Use device's value */ | ||
| 110 | |||
| 111 | /* | ||
| 112 | */ | ||
| 113 | #ifdef CONFIG_USB_LIBUSUAL | ||
| 114 | |||
| 115 | extern struct usb_device_id storage_usb_ids[]; | ||
| 116 | extern void usb_usual_set_present(int type); | ||
| 117 | extern void usb_usual_clear_present(int type); | ||
| 118 | extern int usb_usual_check_type(const struct usb_device_id *, int type); | ||
| 119 | #else | ||
| 120 | |||
| 121 | #define usb_usual_set_present(t) do { } while(0) | ||
| 122 | #define usb_usual_clear_present(t) do { } while(0) | ||
| 123 | #define usb_usual_check_type(id, t) (0) | ||
| 124 | #endif /* CONFIG_USB_LIBUSUAL */ | ||
| 125 | |||
| 126 | #endif /* __LINUX_USB_USUAL_H */ | ||
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index 99dae024b640..22f8bb612bff 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c | |||
| @@ -1996,7 +1996,6 @@ static struct usb_device_id usb_audio_ids [] = { | |||
| 1996 | MODULE_DEVICE_TABLE (usb, usb_audio_ids); | 1996 | MODULE_DEVICE_TABLE (usb, usb_audio_ids); |
| 1997 | 1997 | ||
| 1998 | static struct usb_driver usb_audio_driver = { | 1998 | static struct usb_driver usb_audio_driver = { |
| 1999 | .owner = THIS_MODULE, | ||
| 2000 | .name = "snd-usb-audio", | 1999 | .name = "snd-usb-audio", |
| 2001 | .probe = usb_audio_probe, | 2000 | .probe = usb_audio_probe, |
| 2002 | .disconnect = usb_audio_disconnect, | 2001 | .disconnect = usb_audio_disconnect, |
diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c index cf77313c609d..a3967f72ab4e 100644 --- a/sound/usb/usx2y/usbusx2y.c +++ b/sound/usb/usx2y/usbusx2y.c | |||
| @@ -409,7 +409,6 @@ static void snd_usX2Y_disconnect(struct usb_interface *intf) | |||
| 409 | 409 | ||
| 410 | MODULE_DEVICE_TABLE(usb, snd_usX2Y_usb_id_table); | 410 | MODULE_DEVICE_TABLE(usb, snd_usX2Y_usb_id_table); |
| 411 | static struct usb_driver snd_usX2Y_usb_driver = { | 411 | static struct usb_driver snd_usX2Y_usb_driver = { |
| 412 | .owner = THIS_MODULE, | ||
| 413 | .name = "snd-usb-usx2y", | 412 | .name = "snd-usb-usx2y", |
| 414 | .probe = snd_usX2Y_probe, | 413 | .probe = snd_usX2Y_probe, |
| 415 | .disconnect = snd_usX2Y_disconnect, | 414 | .disconnect = snd_usX2Y_disconnect, |
