bk://kernel.bkbits.net/gregkh/linux/usb-2.6 greg@kroah.com|ChangeSet|20040804045238|03790 greg # This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2004/08/04 03:03:16-07:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6 # into bix.(none):/usr/src/bk-usb # # drivers/usb/misc/tiglusb.c # 2004/08/04 03:03:12-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/usb/media/ov511.c # 2004/08/04 03:03:12-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/08/03 21:52:38-07:00 greg@kroah.com # USB: convert a lot of usb drivers from MODULE_PARM to module_param # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/net/usbnet.c # 2004/08/03 21:51:50-07:00 greg@kroah.com +1 -1 # USB: convert a lot of usb drivers from MODULE_PARM to module_param # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/net/pegasus.c # 2004/08/03 21:51:50-07:00 greg@kroah.com +2 -2 # USB: convert a lot of usb drivers from MODULE_PARM to module_param # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/misc/tiglusb.c # 2004/08/03 21:51:50-07:00 greg@kroah.com +1 -1 # USB: convert a lot of usb drivers from MODULE_PARM to module_param # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/misc/legousbtower.c # 2004/08/03 21:51:49-07:00 greg@kroah.com +7 -7 # USB: convert a lot of usb drivers from MODULE_PARM to module_param # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/media/usbvideo.c # 2004/08/03 21:51:49-07:00 greg@kroah.com +1 -1 # USB: convert a lot of usb drivers from MODULE_PARM to module_param # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/media/ultracam.c # 2004/08/03 21:51:50-07:00 greg@kroah.com +8 -8 # USB: convert a lot of usb drivers from MODULE_PARM to module_param # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/media/stv680.c # 2004/08/03 21:51:50-07:00 greg@kroah.com +3 -3 # USB: convert a lot of usb drivers from MODULE_PARM to module_param # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/media/se401.c # 2004/08/03 21:51:50-07:00 greg@kroah.com +2 -2 # USB: convert a lot of usb drivers from MODULE_PARM to module_param # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/media/pwc-if.c # 2004/08/03 21:51:50-07:00 greg@kroah.com +16 -18 # USB: convert a lot of usb drivers from MODULE_PARM to module_param # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/media/ov511.c # 2004/08/03 21:51:51-07:00 greg@kroah.com +35 -35 # USB: convert a lot of usb drivers from MODULE_PARM to module_param # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/media/konicawc.c # 2004/08/03 21:51:50-07:00 greg@kroah.com +9 -9 # USB: convert a lot of usb drivers from MODULE_PARM to module_param # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/media/dabusb.c # 2004/08/03 21:51:50-07:00 greg@kroah.com +1 -1 # USB: convert a lot of usb drivers from MODULE_PARM to module_param # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/input/kbtab.c # 2004/08/03 21:51:50-07:00 greg@kroah.com +3 -4 # USB: convert a lot of usb drivers from MODULE_PARM to module_param # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/input/aiptek.c # 2004/08/03 21:51:49-07:00 greg@kroah.com +2 -2 # USB: convert a lot of usb drivers from MODULE_PARM to module_param # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/host/uhci-hcd.c # 2004/08/03 21:51:51-07:00 greg@kroah.com +1 -1 # USB: convert a lot of usb drivers from MODULE_PARM to module_param # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/host/ohci-omap.c # 2004/08/03 21:51:50-07:00 greg@kroah.com +1 -1 # USB: convert a lot of usb drivers from MODULE_PARM to module_param # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/host/hc_sl811.c # 2004/08/03 21:51:49-07:00 greg@kroah.com +4 -4 # USB: convert a lot of usb drivers from MODULE_PARM to module_param # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/class/usblp.c # 2004/08/03 21:51:49-07:00 greg@kroah.com +1 -1 # USB: convert a lot of usb drivers from MODULE_PARM to module_param # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/class/usb-midi.c # 2004/08/03 21:51:50-07:00 greg@kroah.com +10 -10 # USB: convert a lot of usb drivers from MODULE_PARM to module_param # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/08/03 07:11:34-07:00 greg@kroah.com # USB: replace old usb-skeleton driver with a rewritten and simpler version. # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/usb-skeleton.c # 2004/08/03 07:11:11-07:00 greg@kroah.com +139 -483 # USB: replace old usb-skeleton driver with a rewritten and simpler version. # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/08/02 16:24:51-07:00 greg@kroah.com # [PATCH] USB: fix build error from previous patch. # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/core/message.c # 2004/08/02 16:22:54-07:00 greg@kroah.com +1 -1 # USB: fix build error from previous patch. # # ChangeSet # 2004/08/02 16:24:29-07:00 david-b@pacbell.net # [PATCH] USB: hid intervals # # I noticed the HID driver had some potential misbehavior ... # # # Bugfix handling for HID devices at high speed (interrupt interval encoding # is log2 not linear), and for interrupt OUT transfers (use the interval # the hardware actually supports). # # Signed-off-by: David Brownell # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/input/hid-core.c # 2004/07/23 06:29:18-07:00 david-b@pacbell.net +8 -2 # USB: hid intervals # # ChangeSet # 2004/08/02 16:24:07-07:00 david-b@pacbell.net # [PATCH] USB: usb_get_descriptor, more error checks # # I've had different versions of this floating around for a while; # basically, the goal is to be more robust against devices that # misbehave by returning garbage descriptors in certain cases. # # Add an extra check when fetching descriptors: the type must be # correct. This guards against different types of firmware (or maybe # hardware) errors than the two checks already being made. # # Signed-off-by: David Brownell # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/core/message.c # 2004/07/14 05:05:11-07:00 david-b@pacbell.net +7 -2 # USB: usb_get_descriptor, more error checks # # ChangeSet # 2004/08/02 14:47:27-07:00 mdharm-usb@one-eyed-alien.net # [PATCH] USB Storage: cleanups, mostly # # This patch is originally from Christoph Hellwig. # # This patch coverts from Scsi_Foo typefs to struct scsi_cmnd, and moved from # the SCSI data direction constants to the DMA ones. # # It also switches to the proper (or so they tell me) use of # headers. This also includes some additional reshuffling to avoid useless # headers in the usb-storage local headers (to improve compile time). # # Signed-off-by: Matthew Dharm # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/storage/usb.h # 2004/07/20 16:30:35-07:00 mdharm-usb@one-eyed-alien.net +4 -5 # USB Storage: cleanups, mostly # # drivers/usb/storage/usb.c # 2004/07/20 16:30:34-07:00 mdharm-usb@one-eyed-alien.net +6 -1 # USB Storage: cleanups, mostly # # drivers/usb/storage/transport.h # 2004/07/20 16:30:38-07:00 mdharm-usb@one-eyed-alien.net +6 -5 # USB Storage: cleanups, mostly # # drivers/usb/storage/transport.c # 2004/07/20 16:30:37-07:00 mdharm-usb@one-eyed-alien.net +18 -13 # USB Storage: cleanups, mostly # # drivers/usb/storage/shuttle_usbat.h # 2004/07/20 16:30:37-07:00 mdharm-usb@one-eyed-alien.net +1 -1 # USB Storage: cleanups, mostly # # drivers/usb/storage/shuttle_usbat.c # 2004/07/20 16:30:36-07:00 mdharm-usb@one-eyed-alien.net +23 -19 # USB Storage: cleanups, mostly # # drivers/usb/storage/sddr55.h # 2004/07/20 16:30:36-07:00 mdharm-usb@one-eyed-alien.net +1 -1 # USB Storage: cleanups, mostly # # drivers/usb/storage/sddr55.c # 2004/07/20 16:30:33-07:00 mdharm-usb@one-eyed-alien.net +24 -20 # USB Storage: cleanups, mostly # # drivers/usb/storage/sddr09.h # 2004/07/20 16:30:35-07:00 mdharm-usb@one-eyed-alien.net +1 -1 # USB Storage: cleanups, mostly # # drivers/usb/storage/sddr09.c # 2004/07/20 16:30:33-07:00 mdharm-usb@one-eyed-alien.net +12 -9 # USB Storage: cleanups, mostly # # drivers/usb/storage/scsiglue.h # 2004/07/20 16:30:26-07:00 mdharm-usb@one-eyed-alien.net +3 -5 # USB Storage: cleanups, mostly # # drivers/usb/storage/scsiglue.c # 2004/07/20 16:30:25-07:00 mdharm-usb@one-eyed-alien.net +18 -11 # USB Storage: cleanups, mostly # # drivers/usb/storage/protocol.h # 2004/07/20 16:30:25-07:00 mdharm-usb@one-eyed-alien.net +10 -10 # USB Storage: cleanups, mostly # # drivers/usb/storage/protocol.c # 2004/07/20 16:30:24-07:00 mdharm-usb@one-eyed-alien.net +14 -11 # USB Storage: cleanups, mostly # # drivers/usb/storage/jumpshot.h # 2004/07/20 16:30:24-07:00 mdharm-usb@one-eyed-alien.net +1 -1 # USB Storage: cleanups, mostly # # drivers/usb/storage/jumpshot.c # 2004/07/20 16:30:23-07:00 mdharm-usb@one-eyed-alien.net +11 -7 # USB Storage: cleanups, mostly # # drivers/usb/storage/isd200.h # 2004/07/20 16:30:23-07:00 mdharm-usb@one-eyed-alien.net +1 -1 # USB Storage: cleanups, mostly # # drivers/usb/storage/isd200.c # 2004/07/20 16:30:22-07:00 mdharm-usb@one-eyed-alien.net +38 -33 # USB Storage: cleanups, mostly # # drivers/usb/storage/freecom.h # 2004/07/20 16:30:21-07:00 mdharm-usb@one-eyed-alien.net +1 -1 # USB Storage: cleanups, mostly # # drivers/usb/storage/freecom.c # 2004/07/20 16:30:21-07:00 mdharm-usb@one-eyed-alien.net +11 -7 # USB Storage: cleanups, mostly # # drivers/usb/storage/dpcm.h # 2004/07/20 16:30:20-07:00 mdharm-usb@one-eyed-alien.net +1 -1 # USB Storage: cleanups, mostly # # drivers/usb/storage/dpcm.c # 2004/07/20 16:30:20-07:00 mdharm-usb@one-eyed-alien.net +5 -1 # USB Storage: cleanups, mostly # # drivers/usb/storage/debug.h # 2004/07/20 16:30:19-07:00 mdharm-usb@one-eyed-alien.net +3 -3 # USB Storage: cleanups, mostly # # drivers/usb/storage/debug.c # 2004/07/20 16:30:18-07:00 mdharm-usb@one-eyed-alien.net +7 -1 # USB Storage: cleanups, mostly # # drivers/usb/storage/datafab.h # 2004/07/20 16:30:17-07:00 mdharm-usb@one-eyed-alien.net +1 -1 # USB Storage: cleanups, mostly # # drivers/usb/storage/datafab.c # 2004/07/20 16:30:17-07:00 mdharm-usb@one-eyed-alien.net +11 -8 # USB Storage: cleanups, mostly # # ChangeSet # 2004/08/02 14:47:07-07:00 mdharm-usb@one-eyed-alien.net # [PATCH] USB Storage: improve debugging output in usb-storage # # This patch started life as as294. All I did was to regenerate it to apply # cleanly against current kernels. # # This just adds a couple of lines to the debugging output with some useful # information, and removes some lines that nobody has looked at in a very # long time. # # Signed-off-by: Alan Stern # Signed-off-by: Matthew Dharm # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/storage/usb.c # 2004/08/01 10:17:28-07:00 mdharm-usb@one-eyed-alien.net +9 -10 # USB Storage: improve debugging output in usb-storage # # ChangeSet # 2004/08/02 14:46:49-07:00 mdharm-usb@one-eyed-alien.net # [PATCH] USB Storage: fix Genesys Logic based on info from vendor # # In theory, this is the fix we need to make Genesys Logic devices work. # This patch started life as as343, which was created based on some # information which a user finally coaxed out of Genesys Logic. Limited # end-user testing gives good results. # # As we expected, it's a bug in their device. This is really a workaround # for what is almost certainly a timing problem. Apparently, the 'popular' # OSes don't push the device as hard as Linux does. # # Although it is likely that this workaround is not needed for all Genesys # devices, Genesys was unable/unwilling to provide us with the explicit list # of VID/PIDs which required this -- thus we apply it to all Genesys devices. # # We have lots of good reports with max_sectors set to 128 with these # devices, but the official recommendation is to set that to 64. End-users # can experiment with higher values (for higher performance) via the runtime # sysfs interface to that parameter. # # I would like to give special thanks to the users who hounded Genesys into # giving up this information, and to Alan Stern for not giving up on this # vendor long after I had. # # Signed-off-by: Alan Stern # Signed-off-by: Matthew Dharm # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/storage/usb.h # 2004/08/01 10:32:35-07:00 mdharm-usb@one-eyed-alien.net +4 -0 # USB Storage: fix Genesys Logic based on info from vendor # # drivers/usb/storage/transport.c # 2004/08/01 10:32:35-07:00 mdharm-usb@one-eyed-alien.net +6 -0 # USB Storage: fix Genesys Logic based on info from vendor # # drivers/usb/storage/scsiglue.c # 2004/08/01 10:32:35-07:00 mdharm-usb@one-eyed-alien.net +8 -10 # USB Storage: fix Genesys Logic based on info from vendor # # ChangeSet # 2004/08/02 14:46:24-07:00 oliver@neukum.org # [PATCH] USB: ACM USB modem on Kernel 2.6.8-rc2 # # this adds a workaround for a broken USB modem. # # # Signed-Off-By: Oliver Neukum # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/class/cdc-acm.c # 2004/08/02 12:40:30-07:00 oliver@neukum.org +17 -11 # USB: ACM USB modem on Kernel 2.6.8-rc2 # # ChangeSet # 2004/08/02 14:29:51-07:00 nacc@us.ibm.com # [PATCH] USB: usbnet: replace schedule_timeout() with msleep() # # Use msleep() instead of schedule_timeout() to guarantee the task delays # for the desired time. Delete unused UNLINK_TIMEOUT_JIFFIES #define. # # Signed-off-by: Nishanth Aravamudan # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/net/usbnet.c # 2004/07/28 12:33:16-07:00 nacc@us.ibm.com +2 -3 # USB: usbnet: replace schedule_timeout() with msleep() # # ChangeSet # 2004/08/02 14:29:08-07:00 nacc@us.ibm.com # [PATCH] USB: auerswald: replace schedule_timeout() with msleep() # # Use msleep() instead of schedule_timeout() to # guarantee the task delays for the desired time. # # Signed-off-by: Nishanth Aravamudan # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/misc/auerswald.c # 2004/07/05 18:12:12-07:00 nacc@us.ibm.com +1 -2 # USB: auerswald: replace schedule_timeout() with msleep() # # ChangeSet # 2004/08/02 14:28:02-07:00 nacc@us.ibm.com # [PATCH] USB: ov511: replace schedule_timeout() with msleep() # # Use msleep() instead of schedule_timeout() to # guarantee the task delays for the desired time. # # Signed-off-by: Nishanth Aravamudan # Signed-off-by: Mark McClelland # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/media/ov511.c # 2004/07/13 13:29:29-07:00 nacc@us.ibm.com +3 -3 # USB: ov511: replace schedule_timeout() with msleep() # # ChangeSet # 2004/08/02 14:26:44-07:00 nacc@us.ibm.com # [PATCH] USB: pxa2xx_udc.c: replace schedule_timeout() with msleep() # # Use msleep() instead of schedule_timeout() to # guarantee the task delays for the desired time. # # Signed-off-by: Nishanth Aravamudan # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/gadget/pxa2xx_udc.c # 2004/07/13 13:31:07-07:00 nacc@us.ibm.com +1 -1 # USB: pxa2xx_udc.c: replace schedule_timeout() with msleep() # # ChangeSet # 2004/08/02 14:25:50-07:00 da-x@gmx.net # [PATCH] d_unhash consolidation # # This removes a copy of d_unhash() from drivers/usb/core/inode.c and # and exports d_unhash() from fs/namei.c as dentry_unhash(). # Tested - compiled and running. # # Signed-off-by: Dan Aloni # Signed-off-by: Greg Kroah-Hartman # # include/linux/fs.h # 2004/07/24 05:52:42-07:00 da-x@gmx.net +5 -0 # d_unhash consolidation # # fs/namei.c # 2004/07/24 06:14:13-07:00 da-x@gmx.net +4 -3 # d_unhash consolidation # # drivers/usb/core/inode.c # 2004/07/24 06:13:27-07:00 da-x@gmx.net +1 -18 # d_unhash consolidation # # ChangeSet # 2004/08/02 13:35:47-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-usb # # MAINTAINERS # 2004/08/02 13:35:43-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/07/30 16:55:46-07:00 greg@kroah.com # USB: fix build error in the cyberjack driver # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/cyberjack.c # 2004/07/30 16:55:16-07:00 greg@kroah.com +1 -0 # USB: fix build error in the cyberjack driver # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/07/30 16:38:58-07:00 luca.risolia@studio.unibo.it # [PATCH] USB: New entry in MAINTAINERS # # I forgot to add an entry in MAINTAINERS about the new SN9C10[12] driver. # # Signed-off-by: Luca Risolia # Signed-off-by: Greg Kroah-Hartman # # MAINTAINERS # 2004/07/15 04:04:07-07:00 luca.risolia@studio.unibo.it +7 -0 # USB: New entry in MAINTAINERS # # ChangeSet # 2004/07/30 16:38:38-07:00 stern@rowland.harvard.edu # [PATCH] USB: unusual_devs.h update # # In view of the comments below, I think we should modify this # unusual_devs.h entry to suppress the warning messages. Please apply. # # # # On Mon, 28 Jun 2004, Joël Bourquard wrote: # # > There seem to be two different flavors of ISD-300 (ie: 05ab,0060) # > devices, one of which needs this entry to work, and the other doesn't. # > # > I have a 2 1/2'' HDD enclosure which (just like your device) doesn't # > need the entry (so when I plug it, I get the same warning as you). # > # > However, I also happen to own two 5 1/4'' CD-ROM enclosures, for which # > this entry *is* necessary. I tried again, very recently to remove my # > unusual_devs.h entry, and it prevented them from working. # > # > So, I think the entry should be kept (it does more good than harm), but # > maybe it could get some tweaking ? If there's a way to recognize these # > "CD-ROM enclosure" bridge chips and exclude the others, I'm all for it. # # # # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/storage/unusual_devs.h # 2004/07/19 04:26:41-07:00 stern@rowland.harvard.edu +6 -2 # USB: unusual_devs.h update # # ChangeSet # 2004/07/30 16:38:21-07:00 stern@rowland.harvard.edu # [PATCH] USB: unusual_devs.h update # # Just like in as347, we have another example of descriptors that vary from # device to device. Please apply this patch to suppress the warning # message. # # On Fri, 16 Jul 2004, Ken Yap wrote: # # > Jul 16 21:44:20 media kernel: usb-storage: This device (090a,1001,0100 S 06 P 50) has an unneeded Protocol entry in unusual_devs.h # > Jul 16 21:44:20 media kernel: Please send a copy of this message to # # # # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/storage/unusual_devs.h # 2004/07/19 04:35:14-07:00 stern@rowland.harvard.edu +1 -1 # USB: unusual_devs.h update # # ChangeSet # 2004/07/30 16:38:02-07:00 johann.cardon@free.fr # [PATCH] USB: New unusual_devs.h entry # # Please merge this new entry for the unusual_devs.h database. # # From: Johann Cardon # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/storage/unusual_devs.h # 2004/07/19 04:43:38-07:00 johann.cardon@free.fr +9 -0 # USB: New unusual_devs.h entry # # ChangeSet # 2004/07/30 16:37:43-07:00 domen@coderock.org # [PATCH] USB: use list_for_each() in core/devices.c # # Signed-off-by: Maximilian Attems # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/core/devices.c # 2004/07/11 05:41:36-07:00 domen@coderock.org +1 -1 # USB: use list_for_each() in core/devices.c # # ChangeSet # 2004/07/30 16:37:24-07:00 domen@coderock.org # [PATCH] USB: use list_for_each() in class/usb-midi.c # # Signed-off-by: Maximilian Attems # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/class/usb-midi.c # 2004/07/11 05:41:39-07:00 domen@coderock.org +3 -3 # USB: use list_for_each() in class/usb-midi.c # # ChangeSet # 2004/07/30 16:37:05-07:00 domen@coderock.org # [PATCH] USB: use list_for_each() in class/audio.c # # Signed-off-by: Maximilian Attems # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/class/audio.c # 2004/07/11 05:41:32-07:00 domen@coderock.org +6 -6 # USB: use list_for_each() in class/audio.c # # ChangeSet # 2004/07/30 16:36:42-07:00 ganesh@veritas.com # [PATCH] USB: fix for ipaq.c # # as per pete and greg's input, fixing only the uninitialized variable. # # Signed-off-by: Ganesh Varadarajan # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/ipaq.c # 2004/07/22 08:42:31-07:00 ganesh@veritas.com +1 -0 # USB: fix for ipaq.c # # ChangeSet # 2004/07/30 16:36:24-07:00 phil@ipom.com # [PATCH] USB: Debug fix in pl2303 # # This is a simple patch to fix a debug statement where the arguements are # in the wrong order. Resending it with a CC to Greg and a signed-off-by line. # # Signed-off-by: Phil Dibowitz # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/pl2303.c # 2004/07/24 00:50:24-07:00 phil@ipom.com +1 -1 # USB: Debug fix in pl2303 # # ChangeSet # 2004/07/30 16:36:03-07:00 stern@rowland.harvard.edu # [PATCH] USB: Remove unneeded unusual_devs.h entry # # According to Jonas Fährmann, the very first entry in unusual_devs.h isn't # needed. In fact, I can't tell why it was there in the first place... # unless some earlier device in the product line had incorrect descriptor # values. # # # On Mon, 26 Jul 2004, Jonas Fährmann wrote: # # > usb-storage: This device (03ee,0000,0045 S 02 P 00) has unneeded SubClass and Protocol entries in unusual_devs.h # > Please send a copy of this message to # # # # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/storage/unusual_devs.h # 2004/07/27 04:39:20-07:00 stern@rowland.harvard.edu +0 -5 # USB: Remove unneeded unusual_devs.h entry # # ChangeSet # 2004/07/30 16:35:44-07:00 abbotti@mev.co.uk # [PATCH] USB: Add support for FT2232C chip to ftdi_sio # # This patch adds support for the FTDI FT2232C USB to dual serial port # converter to the ftdi_sio driver. # # The patch is based on a fork of the 2.4 ftdi_sio driver by Steven # Turner of FTDI, and a preliminary port of these changes to the 2.6 # ftdi_sio driver by Rus V. Brushkoff. I've tidied it up and fixed a # couple of things. # # I don't have a FT2232C to test it with, but Steven Turner of FTDI # has tested it. He mentioned a couple of known problems with the # driver, but nothing to do with this patch. # # # Signed-off-by: Ian Abbott # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/ftdi_sio.h # 2004/07/27 11:12:46-07:00 abbotti@mev.co.uk +17 -0 # USB: Add support for FT2232C chip to ftdi_sio # # drivers/usb/serial/ftdi_sio.c # 2004/07/27 11:12:46-07:00 abbotti@mev.co.uk +102 -13 # USB: Add support for FT2232C chip to ftdi_sio # # ChangeSet # 2004/07/30 16:35:24-07:00 abbotti@mev.co.uk # [PATCH] USB: ftdi_sio doesn't re-assert DTR modem control line # # I've dredged up another old ftdi_sio patch that I never Cc'd to you # the first time. Please see Nathan's description below. # # It applies okay against your usb-2.6 tree, with or without the patch # I posted yesterday to support the FT2232C chip and neither patch # invalidates the other in any way. # # # On 25/06/2004 21:56, Croy, Nathan wrote: # > SUMMARY # > ======= # > ftdi_sio never reasserts modem control lines once the baud has been set to # > B0. # > # > DESCRIPTION # > =========== # > Setting the baud to B0 (hangup) drops DTR. When the baud is raised again, # > DTR is not raised. This can cause a modem to ignore any commands sent to it # > until the device is closed and reopened. This renders minicom (and other # > software) useless, unless you instruct the modem to ignore DTR. # > # > The following patch is intended to make ftdi_sio act like other serial # > devices I have used (i.e. the standard serial ports (/dev/ttyS*) and # > stallion ports (/dev/ttyE*)). Upon setting the baud to something other than # > B0, it ensures the modem control lines are set back to the way they were # > when the port was opened. # > # > Thanks to Ian Abbott for confirming my suspicions: # > http://sourceforge.net/mailarchive/forum.php?thread_id=4984710&forum_id=12120 # # Nathan's email suffered from a line-folding bug (blame M$, # probably!), so his patch came out corrupted. I'm reposting an # uncorrupted version. # # # Signed off by: Ian Abbott # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/ftdi_sio.c # 2004/06/24 05:29:22-07:00 abbotti@mev.co.uk +7 -0 # USB: ftdi_sio doesn't re-assert DTR modem control line # # ChangeSet # 2004/07/30 16:35:06-07:00 laforge@netfilter.org # [PATCH] USB: Hackish fix for cyberjack driver # # The following patch is in use by REINER-SCT customres for some time and # works for them in about 90% of all cases. I would really appreciate # this going in before 2.6.8-final, since the device doesn't work at all # with current 2.6.x driver. # # Changes: # - bump version number # - open interrupt endpoint in startup() rather than open # # # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/serial/cyberjack.c # 2004/07/28 08:40:57-07:00 laforge@netfilter.org +16 -17 # USB: Hackish fix for cyberjack driver # # ChangeSet # 2004/07/30 16:34:47-07:00 akpm@osdl.org # [PATCH] USB: gcc-3.5 fixes # # From: Andi Kleen # # Trivial gcc-3.5 build fixes. # # Signed-off-by: Andrew Morton # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/class/usblp.c # 2004/07/10 17:52:27-07:00 akpm@osdl.org +1 -1 # USB: gcc-3.5 fixes # # ChangeSet # 2004/07/30 16:34:27-07:00 david-b@pacbell.net # [PATCH] USB: usb hub docs and locktree() # # Please merge; the CONFIG_USB_SUSPEND patch depends on it. # # This hub patch: # # - updates internal docs about locking, matching current usage # for device state spinlock and dev->serialize semaphore # # - adds locktree() to use with signaling that affect everything # downstream of a given device ... right now just khubd uses it, # but usb_reset_device() should too (not just with hub resets...) # # - adds hub_quiesce()/hub_reactivate() ... former is used now # during shutdown, both are needed in suspend/resume paths # # Net change in behavior for current systems should be nothing. # # Signed-off-by: David Brownell # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/core/hub.h # 2004/07/29 01:31:30-07:00 david-b@pacbell.net +2 -0 # USB: usb hub docs and locktree() # # drivers/usb/core/hub.c # 2004/07/29 03:00:59-07:00 david-b@pacbell.net +105 -21 # USB: usb hub docs and locktree() # # ChangeSet # 2004/07/30 16:34:04-07:00 david-b@pacbell.net # [PATCH] USB: add CONFIG_USB_SUSPEND # # This is the core of the USB_SUSPEND functionality. Please merge. # # This adds an experimental CONFIG_USB_SUSPEND option, which supports the # USB "suspend" state. Linux-USB hosts have previously ignored that state. # # - New driver API calls, usb_suspend_device() and its # sibling usb_resume_device(). # # - Access to those calls through sysfs, such as # echo -n 2 > power/state # echo -n 0 > power/state # # That can be used to reduce the power consumption of any given USB device, # then re-activate it later. Eventually, most USB device drivers should # probably suspend idle USB devices. # # One problem with this patch: USB drivers without suspend() callbacks # may badly misbehave. Right now only hub drivers know suspend(). If the # driver core didn't self-deadlock when we try it, unbinding those drivers # from those devices (then re-enumerating on resume) would be perfect... # the current compromise is just to emit a warning message. # # In conjunction with host controller driver support (already merged for # OHCI and EHCI), PCI host controllers will issue the PME# wakeup signal # when a USB keyboard starts remote wakeup signaling. (But the keyboard # wasn't usable later, since HID doesn't try to suspend.) # # I understand some ACPI patches are circulating, and maybe already in # the MM tree, to make a suspended system wake up given PME# signaling. # It'd be great if someone made that work transparently with USB, but # for now I'm told it'll need some sysfs setup first. # # Signed-off-by: David Brownell # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/core/hub.c # 2004/07/29 03:00:59-07:00 david-b@pacbell.net +484 -1 # USB: add CONFIG_USB_SUSPEND # # drivers/usb/core/Kconfig # 2004/07/29 01:31:44-07:00 david-b@pacbell.net +11 -0 # USB: add CONFIG_USB_SUSPEND # # Documentation/DocBook/usb.tmpl # 2004/07/29 01:42:14-07:00 david-b@pacbell.net +1 -0 # USB: add CONFIG_USB_SUSPEND # # ChangeSet # 2004/07/30 16:33:45-07:00 stern@rowland.harvard.edu # [PATCH] USB: Make removable-LUN support a non-test option in the g_file_storage driver # # This patch follows the suggestions sent by Todd Fischer and Diego Dompe # for making removable-LUN support part of the normal non-testing version of # the g_file_storage driver. It also moves LUN device registration to the # correct place and eliminates a code path that stalls the bulk-out pipe in # a racy way. # # There are also some smaller changes: update some comments, add initial # debugging support for USB suspend/resume, and miscellaneous code cleanups. # Last but not least, the driver has been sufficiently stable for # sufficiently long that it's fair to remove the "(DEVELOPMENT)" warning in # Kconfig. # # # # Sent-by: Todd Fischer # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/gadget/file_storage.c # 2004/07/28 04:17:49-07:00 stern@rowland.harvard.edu +94 -75 # USB: Make removable-LUN support a non-test option in the g_file_storage driver # # drivers/usb/gadget/Kconfig # 2004/07/28 04:08:24-07:00 stern@rowland.harvard.edu +2 -2 # USB: Make removable-LUN support a non-test option in the g_file_storage driver # # ChangeSet # 2004/07/30 16:33:20-07:00 stern@rowland.harvard.edu # [PATCH] USB: Fix NULL-pointer bug in dummy_hcd # # This patch fixes a NULL-pointer-dereference bug in the dummy_hcd driver. # It also makes the code slightly more elegant and removes an unnecessary # buffer-overflow test. Unfortunately it's still a little bit racy, but # this is a fault it shares with other gadget controller drivers, like # net2280. # # Signed-off-by: Alan Stern # Signed-off-by: Greg Kroah-Hartman # # drivers/usb/gadget/dummy_hcd.c # 2004/07/29 05:10:55-07:00 stern@rowland.harvard.edu +4 -5 # USB: Fix NULL-pointer bug in dummy_hcd # diff -Nru a/Documentation/DocBook/usb.tmpl b/Documentation/DocBook/usb.tmpl --- a/Documentation/DocBook/usb.tmpl 2004-08-04 17:58:04 -07:00 +++ b/Documentation/DocBook/usb.tmpl 2004-08-04 17:58:04 -07:00 @@ -251,6 +251,7 @@ !Edrivers/usb/core/message.c !Edrivers/usb/core/file.c !Edrivers/usb/core/usb.c +!Edrivers/usb/core/hub.c Host Controller APIs diff -Nru a/MAINTAINERS b/MAINTAINERS --- a/MAINTAINERS 2004-08-04 17:58:03 -07:00 +++ b/MAINTAINERS 2004-08-04 17:58:03 -07:00 @@ -2299,6 +2299,13 @@ W: http://www.connecttech.com S: Supported +USB SN9C10[12] DRIVER +P: Luca Risolia +M: luca.risolia@studio.unibo.it +L: linux-usb-devel@lists.sourceforge.net +W: http://go.lamarinapunto.com +S: Maintained + USB SUBSYSTEM P: Greg Kroah-Hartman M: greg@kroah.com diff -Nru a/drivers/usb/class/audio.c b/drivers/usb/class/audio.c --- a/drivers/usb/class/audio.c 2004-08-04 17:58:04 -07:00 +++ b/drivers/usb/class/audio.c 2004-08-04 17:58:04 -07:00 @@ -1954,9 +1954,9 @@ struct usb_audio_state *s; down(&open_sem); - for (devs = audiodevs.next; devs != &audiodevs; devs = devs->next) { + list_for_each(devs, &audiodevs) { s = list_entry(devs, struct usb_audio_state, audiodev); - for (mdevs = s->mixerlist.next; mdevs != &s->mixerlist; mdevs = mdevs->next) { + list_for_each(mdevs, &s->mixerlist) { ms = list_entry(mdevs, struct usb_mixerdev, list); if (ms->dev_mixer == minor) goto mixer_found; @@ -2644,9 +2644,9 @@ for (;;) { down(&open_sem); - for (devs = audiodevs.next; devs != &audiodevs; devs = devs->next) { + list_for_each(devs, &audiodevs) { s = list_entry(devs, struct usb_audio_state, audiodev); - for (adevs = s->audiolist.next; adevs != &s->audiolist; adevs = adevs->next) { + list_for_each(adevs, &s->audiolist) { as = list_entry(adevs, struct usb_audiodev, list); if (!((as->dev_audio ^ minor) & ~0xf)) goto device_found; @@ -3835,7 +3835,7 @@ usb_set_intfdata (intf, NULL); /* deregister all audio and mixer devices, so no new processes can open this device */ - for(list = s->audiolist.next; list != &s->audiolist; list = list->next) { + list_for_each(list, &s->audiolist) { as = list_entry(list, struct usb_audiodev, list); usbin_disc(as); usbout_disc(as); @@ -3847,7 +3847,7 @@ } as->dev_audio = -1; } - for(list = s->mixerlist.next; list != &s->mixerlist; list = list->next) { + list_for_each(list, &s->mixerlist) { ms = list_entry(list, struct usb_mixerdev, list); if (ms->dev_mixer >= 0) { unregister_sound_mixer(ms->dev_mixer); diff -Nru a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c --- a/drivers/usb/class/cdc-acm.c 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/class/cdc-acm.c 2004-08-04 17:58:03 -07:00 @@ -583,19 +583,25 @@ } if (!union_header) { - dev_dbg(&intf->dev,"No union descriptor, giving up\n"); - return -ENODEV; - } - - control_interface = usb_ifnum_to_if(usb_dev, union_header->bMasterInterface0); - data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = union_header->bSlaveInterface0)); - if (!control_interface || !data_interface) { - dev_dbg(&intf->dev,"no interfaces\n"); - return -ENODEV; + if (call_interface_num > 0) { + dev_dbg(&intf->dev,"No union descriptor, using call management descriptor\n"); + data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = call_interface_num)); + control_interface = intf; + } else { + dev_dbg(&intf->dev,"No union descriptor, giving up\n"); + return -ENODEV; + } + } else { + control_interface = usb_ifnum_to_if(usb_dev, union_header->bMasterInterface0); + data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = union_header->bSlaveInterface0)); + if (!control_interface || !data_interface) { + dev_dbg(&intf->dev,"no interfaces\n"); + return -ENODEV; + } } - if (data_interface_num != call_interface_num) - dev_dbg(&intf->dev,"Seperate call control interface. That is not fully supported."); + if (data_interface_num != call_interface_num) + dev_dbg(&intf->dev,"Seperate call control interface. That is not fully supported."); if (usb_interface_claimed(data_interface)) { /* valid in this context */ dev_dbg(&intf->dev,"The data interface isn't available\n"); diff -Nru a/drivers/usb/class/usb-midi.c b/drivers/usb/class/usb-midi.c --- a/drivers/usb/class/usb-midi.c 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/class/usb-midi.c 2004-08-04 17:58:03 -07:00 @@ -55,39 +55,39 @@ /* ------------------------------------------------------------------------- */ static int singlebyte = 0; -MODULE_PARM(singlebyte,"i"); +module_param(singlebyte, int, 0); MODULE_PARM_DESC(singlebyte,"Enable sending MIDI messages with single message packet"); static int maxdevices = 4; -MODULE_PARM(maxdevices,"i"); +module_param(maxdevices, int, 0); MODULE_PARM_DESC(maxdevices,"Max number of allocatable MIDI device"); static int uvendor = -1; -MODULE_PARM(uvendor,"i"); +module_param(uvendor, int, 0); MODULE_PARM_DESC(uvendor, "The USB Vendor ID of a semi-compliant interface"); static int uproduct = -1; -MODULE_PARM(uproduct,"i"); +module_param(uproduct, int, 0); MODULE_PARM_DESC(uproduct, "The USB Product ID of a semi-compliant interface"); static int uinterface = -1; -MODULE_PARM(uinterface,"i"); +module_param(uinterface, int, 0); MODULE_PARM_DESC(uinterface, "The Interface number of a semi-compliant interface"); static int ualt = -1; -MODULE_PARM(ualt,"i"); +module_param(ualt, int, 0); MODULE_PARM_DESC(ualt, "The optional alternative setting of a semi-compliant interface"); static int umin = -1; -MODULE_PARM(umin,"i"); +module_param(umin, int, 0); MODULE_PARM_DESC(umin, "The input endpoint of a semi-compliant interface"); static int umout = -1; -MODULE_PARM(umout,"i"); +module_param(umout, int, 0); MODULE_PARM_DESC(umout, "The output endpoint of a semi-compliant interface"); static int ucable = -1; -MODULE_PARM(ucable,"i"); +module_param(ucable, int, 0); MODULE_PARM_DESC(ucable, "The cable number used for a semi-compliant interface"); /** Note -- the usb_string() returns only Latin-1 characters. @@ -95,7 +95,7 @@ * unicode16LE-to-JIS routine is needed to wrap around usb_get_string(). **/ static unsigned short ulangid = 0x0409; /** 0x0411 for Japanese **/ -MODULE_PARM(ulangid,"h"); +module_param(ulangid, ushort, 0); MODULE_PARM_DESC(ulangid, "The optional preferred USB Language ID for all devices"); MODULE_AUTHOR("NAGANO Daisuke "); @@ -823,9 +823,9 @@ for(;;) { down(&open_sem); - for (devs = mididevs.next; devs != &mididevs; devs = devs->next) { + list_for_each(devs, &mididevs) { s = list_entry(devs, struct usb_midi_state, mididev); - for (mdevs = s->midiDevList.next; mdevs != &s->midiDevList; mdevs = mdevs->next) { + list_for_each(mdevs, &s->midiDevList) { m = list_entry(mdevs, struct usb_mididev, list); if ( !((m->dev_midi ^ minor) & ~0xf) ) goto device_found; @@ -2018,7 +2018,7 @@ s->usbdev = NULL; usb_set_intfdata (intf, NULL); - for ( list = s->midiDevList.next; list != &s->midiDevList; list = list->next ) { + list_for_each(list, &s->midiDevList) { m = list_entry(list, struct usb_mididev, list); wake_up(&(m->min.ep->wait)); wake_up(&(m->mout.ep->wait)); diff -Nru a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c --- a/drivers/usb/class/usblp.c 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/class/usblp.c 2004-08-04 17:58:03 -07:00 @@ -221,7 +221,7 @@ static int usblp_cache_device_id_string(struct usblp *usblp); /* forward reference to make our lives easier */ -extern struct usb_driver usblp_driver; +static struct usb_driver usblp_driver; /* * Functions for usblp control messages. @@ -1208,6 +1208,6 @@ MODULE_AUTHOR( DRIVER_AUTHOR ); MODULE_DESCRIPTION( DRIVER_DESC ); -MODULE_PARM(proto_bias, "i"); +module_param(proto_bias, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(proto_bias, "Favourite protocol number"); MODULE_LICENSE("GPL"); diff -Nru a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig --- a/drivers/usb/core/Kconfig 2004-08-04 17:58:04 -07:00 +++ b/drivers/usb/core/Kconfig 2004-08-04 17:58:04 -07:00 @@ -60,3 +60,14 @@ If you are unsure about this, say N here. +config USB_SUSPEND + bool "USB suspend/resume (EXPERIMENTAL)" + depends on USB && PM && EXPERIMENTAL + help + If you say Y here, you can use driver calls or the sysfs + "power/state" file to suspend or resume individual USB + peripherals. There are many related features, such as + remote wakeup and driver-specific suspend processing, that + may not yet work as expected. + + If you are unsure about this, say N here. diff -Nru a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c --- a/drivers/usb/core/devices.c 2004-08-04 17:58:04 -07:00 +++ b/drivers/usb/core/devices.c 2004-08-04 17:58:04 -07:00 @@ -584,7 +584,7 @@ /* enumerate busses */ down (&usb_bus_list_lock); - for (buslist = usb_bus_list.next; buslist != &usb_bus_list; buslist = buslist->next) { + list_for_each(buslist, &usb_bus_list) { /* print devices for this bus */ bus = list_entry(buslist, struct usb_bus, bus_list); diff -Nru a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c --- a/drivers/usb/core/hub.c 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/core/hub.c 2004-08-04 17:58:03 -07:00 @@ -36,7 +36,7 @@ #include "hcd.h" #include "hub.h" -/* Protect all struct usb_device state members */ +/* Protect struct usb_device state and children members */ static spinlock_t device_state_lock = SPIN_LOCK_UNLOCKED; /* Wakes up khubd */ @@ -143,7 +143,7 @@ unsigned changed = 0; int cursor = -1; - if (hdev->state != USB_STATE_CONFIGURED) + if (hdev->state != USB_STATE_CONFIGURED || hub->quiescing) return; for (i = 0; i < hub->descriptor->bNbrPorts; i++) { @@ -269,6 +269,9 @@ spin_unlock(&hub_event_lock); resubmit: + if (hub->quiescing) + return; + if ((status = usb_submit_urb (hub->urb, GFP_ATOMIC)) != 0 && status != -ENODEV && status != -EPERM) dev_err (&hub->intf->dev, "resubmit --> %d\n", status); @@ -623,6 +626,33 @@ static unsigned highspeed_hubs; +static void hub_quiesce(struct usb_hub *hub) +{ + /* stop khubd and related activity */ + hub->quiescing = 1; + usb_kill_urb(hub->urb); + if (hub->has_indicators) + cancel_delayed_work(&hub->leds); + if (hub->has_indicators || hub->tt.hub) + flush_scheduled_work(); +} + +#ifdef CONFIG_USB_SUSPEND + +static void hub_reactivate(struct usb_hub *hub) +{ + int status; + + hub->quiescing = 0; + status = usb_submit_urb(hub->urb, GFP_NOIO); + if (status < 0) + dev_err(&hub->intf->dev, "reactivate --> %d\n", status); + if (hub->has_indicators && blinkenlights) + schedule_delayed_work(&hub->leds, LED_CYCLE_PERIOD); +} + +#endif + static void hub_disconnect(struct usb_interface *intf) { struct usb_hub *hub = usb_get_intfdata (intf); @@ -637,22 +667,14 @@ usb_set_intfdata (intf, NULL); - if (hub->urb) { - usb_kill_urb(hub->urb); - usb_free_urb(hub->urb); - hub->urb = NULL; - } + hub_quiesce(hub); + usb_free_urb(hub->urb); + hub->urb = NULL; spin_lock_irq(&hub_event_lock); list_del_init(&hub->event_list); spin_unlock_irq(&hub_event_lock); - /* assuming we used keventd, it must quiesce too */ - if (hub->has_indicators) - cancel_delayed_work (&hub->leds); - if (hub->has_indicators || hub->tt.hub) - flush_scheduled_work (); - if (hub->descriptor) { kfree(hub->descriptor); hub->descriptor = NULL; @@ -772,6 +794,7 @@ } } +/* caller has locked the hub */ static int hub_reset(struct usb_hub *hub) { struct usb_device *hdev = hub->hdev; @@ -801,6 +824,7 @@ return 0; } +/* caller has locked the hub */ /* FIXME! This routine should be subsumed into hub_reset */ static void hub_start_disconnect(struct usb_device *hdev) { @@ -832,12 +856,65 @@ udev->state = USB_STATE_NOTATTACHED; } +/* grab device/port lock, returning index of that port (zero based). + * protects the upstream link used by this device from concurrent + * tree operations like suspend, resume, reset, and disconnect, which + * apply to everything downstream of a given port. + */ +static int locktree(struct usb_device *udev) +{ + int t; + struct usb_device *hdev; + + if (!udev) + return -ENODEV; + + /* root hub is always the first lock in the series */ + hdev = udev->parent; + if (!hdev) { + down(&udev->serialize); + return 0; + } + + /* on the path from root to us, lock everything from + * top down, dropping parent locks when not needed + * + * NOTE: if disconnect were to ignore the locking, we'd need + * to get extra refcounts to everything since hdev->children + * and udev->parent could be invalidated while we work... + */ + t = locktree(hdev); + if (t < 0) + return t; + spin_lock_irq(&device_state_lock); + for (t = 0; t < hdev->maxchild; t++) { + if (hdev->children[t] == udev) { + /* everything is fail-fast once disconnect + * processing starts + */ + if (udev->state == USB_STATE_NOTATTACHED) + break; + + /* when everyone grabs locks top->bottom, + * non-overlapping work may be concurrent + */ + spin_unlock_irq(&device_state_lock); + down(&udev->serialize); + up(&hdev->serialize); + return t; + } + } + spin_unlock_irq(&device_state_lock); + up(&hdev->serialize); + return -ENODEV; +} + /** * usb_set_device_state - change a device's current state (usbcore-internal) * @udev: pointer to device whose state should be changed * @new_state: new state value to be stored * - * udev->state is _not_ protected by the udev->serialize semaphore. This + * udev->state is _not_ protected by the device lock. This * is so that devices can be marked as disconnected as soon as possible, * without having to wait for the semaphore to be released. Instead, * changes to the state must be protected by the device_state_lock spinlock. @@ -897,7 +974,7 @@ /** * usb_disconnect - disconnect a device (usbcore-internal) - * @pdev: pointer to device being disconnected + * @pdev: pointer to device being disconnected, into a locked hub * Context: !in_interrupt () * * Something got disconnected. Get rid of it, and all of its children. @@ -921,7 +998,8 @@ } /* mark the device as inactive, so any further urb submissions for - * this device will fail. + * this device (and any of its children) will fail immediately. + * this quiesces everyting except pending urbs. */ usb_set_device_state(udev, USB_STATE_NOTATTACHED); @@ -940,6 +1018,7 @@ /* deallocate hcd/hardware state ... nuking all pending urbs and * cleaning up all state associated with the current configuration + * so that the hardware is now fully quiesced. */ usb_disable_device(udev, 0); @@ -952,7 +1031,7 @@ usbfs_remove_device(udev); usb_remove_sysfs_dev_files(udev); - /* Avoid races with recursively_mark_NOTATTACHED() */ + /* Avoid races with recursively_mark_NOTATTACHED() and locktree() */ spin_lock_irq(&device_state_lock); *pdev = NULL; spin_unlock_irq(&device_state_lock); @@ -1203,6 +1282,7 @@ if (status == -ENOTCONN || status == 0) { clear_port_feature(hdev, port + 1, USB_PORT_FEAT_C_RESET); + /* FIXME need disconnect() for NOTATTACHED device */ usb_set_device_state(udev, status ? USB_STATE_NOTATTACHED : USB_STATE_DEFAULT); @@ -1226,9 +1306,11 @@ { int ret; - if (hdev->children[port]) + if (hdev->children[port]) { + /* FIXME need disconnect() for NOTATTACHED device */ usb_set_device_state(hdev->children[port], USB_STATE_NOTATTACHED); + } ret = clear_port_feature(hdev, port + 1, USB_PORT_FEAT_ENABLE); if (ret) dev_err(hubdev(hdev), "cannot disable port %d (err = %d)\n", @@ -1239,7 +1321,490 @@ #ifdef CONFIG_USB_SUSPEND - /* no USB_SUSPEND yet! */ +/* + * Selective port suspend reduces power; most suspended devices draw + * less than 500 uA. It's also used in OTG, along with remote wakeup. + * All devices below the suspended port are also suspended. + * + * Devices leave suspend state when the host wakes them up. Some devices + * also support "remote wakeup", where the device can activate the USB + * tree above them to deliver data, such as a keypress or packet. In + * some cases, this wakes the USB host. + */ +static int hub_port_suspend(struct usb_device *hdev, int port) +{ + int status; + struct usb_device *udev; + + udev = hdev->children[port - 1]; + // dev_dbg(hubdev(hdev), "suspend port %d\n", port); + + /* enable remote wakeup when appropriate; this lets the device + * wake up the upstream hub (including maybe the root hub). + * + * NOTE: OTG devices may issue remote wakeup (or SRP) even when + * we don't explicitly enable it here. + */ + if (udev->actconfig + // && FIXME (remote wakeup enabled on this bus) + // ... currently assuming it's always appropriate + && (udev->actconfig->desc.bmAttributes + & USB_CONFIG_ATT_WAKEUP) != 0) { + status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + USB_REQ_SET_FEATURE, USB_RECIP_DEVICE, + USB_DEVICE_REMOTE_WAKEUP, 0, + NULL, 0, + USB_CTRL_SET_TIMEOUT); + if (status) + dev_dbg(&udev->dev, + "won't remote wakeup, status %d\n", + status); + } + + /* see 7.1.7.6 */ + status = set_port_feature(hdev, port, USB_PORT_FEAT_SUSPEND); + if (status) { + dev_dbg(hubdev(hdev), + "can't suspend port %d, status %d\n", + port, status); + /* paranoia: "should not happen" */ + (void) usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + USB_REQ_CLEAR_FEATURE, USB_RECIP_DEVICE, + USB_DEVICE_REMOTE_WAKEUP, 0, + NULL, 0, + USB_CTRL_SET_TIMEOUT); + } else { + /* device has up to 10 msec to fully suspend */ + dev_dbg(&udev->dev, "usb suspend\n"); + udev->state = USB_STATE_SUSPENDED; + msleep(10); + } + return status; +} + +/* + * Devices on USB hub ports have only one "suspend" state, corresponding + * to ACPI D2 (PM_SUSPEND_MEM), "may cause the device to lose some context". + * State transitions include: + * + * - suspend, resume ... when the VBUS power link stays live + * - suspend, disconnect ... VBUS lost + * + * Once VBUS drop breaks the circuit, the port it's using has to go through + * normal re-enumeration procedures, starting with enabling VBUS power. + * Other than re-initializing the hub (plug/unplug, except for root hubs), + * Linux (2.6) currently has NO mechanisms to initiate that: no khubd + * timer, no SRP, no requests through sysfs. + */ +static int __usb_suspend_device (struct usb_device *udev, int port, u32 state) +{ + int status; + + if (port < 0) + return port; + + /* NOTE: udev->serialize released on all real returns! */ + + if (state <= udev->dev.power.power_state + || state < PM_SUSPEND_MEM + || udev->state == USB_STATE_SUSPENDED + || udev->state == USB_STATE_NOTATTACHED) { + up(&udev->serialize); + return 0; + } + + /* suspend interface drivers; if this is a hub, it + * suspends the child devices + */ + if (udev->actconfig) { + int i; + + for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { + struct usb_interface *intf; + struct usb_driver *driver; + + intf = udev->actconfig->interface[i]; + if (state <= intf->dev.power.power_state) + continue; + if (!intf->dev.driver) + continue; + driver = to_usb_driver(intf->dev.driver); + + if (driver->suspend) { + status = driver->suspend(intf, state); + if (intf->dev.power.power_state != state + || status) + dev_err(&intf->dev, + "suspend %d fail, code %d\n", + state, status); + } + + /* only drivers with suspend() can ever resume(); + * and after power loss, even they won't. + * bus_rescan_devices() can rebind drivers later. + * + * FIXME the PM core self-deadlocks when unbinding + * drivers during suspend/resume ... everything grabs + * dpm_sem (not a spinlock, ugh). we want to unbind, + * since we know every driver's probe/disconnect works + * even for drivers that can't suspend. + */ + if (!driver->suspend || state > PM_SUSPEND_MEM) { +#if 1 + dev_warn(&intf->dev, "resume is unsafe!\n"); +#else + down_write(&usb_bus_type.rwsem); + device_release_driver(&intf->dev); + up_write(&usb_bus_type.rwsem); +#endif + } + } + } + + /* + * FIXME this needs port power off call paths too, to help force + * USB into the "generic" PM model. At least for devices on + * ports that aren't using ganged switching (usually root hubs). + * + * NOTE: SRP-capable links should adopt more aggressive poweroff + * policies (when HNP doesn't apply) once we have mechanisms to + * turn power back on! (Likely not before 2.7...) + */ + if (state > PM_SUSPEND_MEM) { + dev_warn(&udev->dev, "no poweroff yet, suspending instead\n"); + state = PM_SUSPEND_MEM; + } + + /* "global suspend" of the HC-to-USB interface (root hub), or + * "selective suspend" of just one hub-device link. + */ + if (!udev->parent) { + struct usb_bus *bus = udev->bus; + if (bus && bus->op->hub_suspend) + status = bus->op->hub_suspend (bus); + else + status = -EOPNOTSUPP; + } else + status = hub_port_suspend(udev->parent, port + 1); + + if (status == 0) + udev->dev.power.power_state = state; + up(&udev->serialize); + return status; +} + +/** + * usb_suspend_device - suspend a usb device + * @udev: device that's no longer in active use + * @state: PM_SUSPEND_MEM to suspend + * Context: must be able to sleep; device not locked + * + * Suspends a USB device that isn't in active use, conserving power. + * Devices may wake out of a suspend, if anything important happens, + * using the remote wakeup mechanism. They may also be taken out of + * suspend by the host, using usb_resume_device(). It's also routine + * to disconnect devices while they are suspended. + * + * Suspending OTG devices may trigger HNP, if that's been enabled + * between a pair of dual-role devices. That will change roles, such + * as from A-Host to A-Peripheral or from B-Host back to B-Peripheral. + * + * Returns 0 on success, else negative errno. + */ +int usb_suspend_device(struct usb_device *udev, u32 state) +{ + return __usb_suspend_device(udev, locktree(udev), state); +} + +/* + * hardware resume signaling is finished, either because of selective + * resume (by host) or remote wakeup (by device) ... now see what changed + * in the tree that's rooted at this device. + */ +static int finish_port_resume(struct usb_device *udev) +{ + int status; + u16 devstatus; + + /* caller owns udev->serialize */ + dev_dbg(&udev->dev, "usb resume\n"); + udev->dev.power.power_state = PM_SUSPEND_ON; + + /* usb ch9 identifies four variants of SUSPENDED, based on what + * state the device resumes to. Linux currently won't see the + * first two on the host side; they'd be inside hub_port_init() + * during many timeouts, but khubd can't suspend until later. + */ + udev->state = udev->actconfig + ? USB_STATE_CONFIGURED + : USB_STATE_ADDRESS; + + /* 10.5.4.5 says be sure devices in the tree are still there. + * For now let's assume the device didn't go crazy on resume, + * and device drivers will know about any resume quirks. + */ + status = usb_get_status(udev, USB_RECIP_DEVICE, 0, &devstatus); + if (status < 0) + dev_dbg(&udev->dev, + "gone after usb resume? status %d\n", + status); + else if (udev->actconfig) { + unsigned i; + + le16_to_cpus(&devstatus); + if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)) { + status = usb_control_msg(udev, + usb_sndctrlpipe(udev, 0), + USB_REQ_CLEAR_FEATURE, + USB_RECIP_DEVICE, + USB_DEVICE_REMOTE_WAKEUP, 0, + NULL, 0, + USB_CTRL_SET_TIMEOUT); + if (status) { + dev_dbg(&udev->dev, "disable remote " + "wakeup, status %d\n", status); + status = 0; + } + } + + /* resume interface drivers; if this is a hub, it + * resumes the child devices + */ + for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { + struct usb_interface *intf; + struct usb_driver *driver; + + intf = udev->actconfig->interface[i]; + if (intf->dev.power.power_state == PM_SUSPEND_ON) + continue; + if (!intf->dev.driver) { + /* FIXME maybe force to alt 0 */ + continue; + } + driver = to_usb_driver(intf->dev.driver); + + /* bus_rescan_devices() may rebind drivers */ + if (!driver->resume) + continue; + + /* can we do better than just logging errors? */ + status = driver->resume(intf); + if (intf->dev.power.power_state != PM_SUSPEND_ON + || status) + dev_dbg(&intf->dev, + "resume fail, state %d code %d\n", + intf->dev.power.power_state, status); + } + status = 0; + + } else if (udev->devnum <= 0) { + dev_dbg(&udev->dev, "bogus resume!\n"); + status = -EINVAL; + } + return status; +} + +static int +hub_port_resume(struct usb_device *hdev, int port) +{ + int status; + struct usb_device *udev; + + udev = hdev->children[port - 1]; + // dev_dbg(hubdev(hdev), "resume port %d\n", port); + + /* see 7.1.7.7; affects power usage, but not budgeting */ + status = clear_port_feature(hdev, port, USB_PORT_FEAT_SUSPEND); + if (status) { + dev_dbg(&hdev->actconfig->interface[0]->dev, + "can't resume port %d, status %d\n", + port, status); + } else { + u16 devstatus; + u16 portchange; + + /* drive resume for at least 20 msec */ + dev_dbg(&udev->dev, "RESUME\n"); + msleep(25); + +#define LIVE_FLAGS ( USB_PORT_STAT_POWER \ + | USB_PORT_STAT_ENABLE \ + | USB_PORT_STAT_CONNECTION) + + /* Virtual root hubs can trigger on GET_PORT_STATUS to + * stop resume signaling. Then finish the resume + * sequence. + */ + devstatus = portchange = 0; + status = hub_port_status(hdev, port - 1, + &devstatus, &portchange); + if (status < 0 + || (devstatus & LIVE_FLAGS) != LIVE_FLAGS + || (devstatus & USB_PORT_STAT_SUSPEND) != 0 + ) { + dev_dbg(&hdev->actconfig->interface[0]->dev, + "port %d status %04x.%04x after resume, %d\n", + port, portchange, devstatus, status); + } else { + /* TRSMRCY = 10 msec */ + msleep(10); + status = finish_port_resume(udev); + } + } + if (status < 0) + status = hub_port_disable(hdev, port); + + return status; +} + +static int hub_resume (struct usb_interface *intf); + +/** + * usb_resume_device - re-activate a suspended usb device + * @udev: device to re-activate + * Context: must be able to sleep; device not locked + * + * This will re-activate the suspended device, increasing power usage + * while letting drivers communicate again with its endpoints. + * USB resume explicitly guarantees that the power session between + * the host and the device is the same as it was when the device + * suspended. + * + * Returns 0 on success, else negative errno. + */ +int usb_resume_device(struct usb_device *udev) +{ + int port, status; + + port = locktree(udev); + if (port < 0) + return port; + + /* "global resume" of the HC-to-USB interface (root hub), or + * selective resume of one hub-to-device port + */ + if (!udev->parent) { + struct usb_bus *bus = udev->bus; + if (bus && bus->op->hub_resume) + status = bus->op->hub_resume (bus); + else + status = -EOPNOTSUPP; + if (status == 0) { + /* TRSMRCY = 10 msec */ + msleep(10); + status = hub_resume (bus->root_hub + ->actconfig->interface[0]); + } + } else if (udev->state == USB_STATE_SUSPENDED) { + status = hub_port_resume(udev->parent, port + 1); + } else { + status = 0; + udev->dev.power.power_state = PM_SUSPEND_ON; + } + if (status < 0) { + dev_dbg(&udev->dev, "can't resume, status %d\n", + status); + } + + up(&udev->serialize); + + /* rebind drivers that had no suspend() */ + bus_rescan_devices(&usb_bus_type); + + return status; +} + +static int remote_wakeup(struct usb_device *udev) +{ + int status = 0; + + /* don't repeat RESUME sequence if this device + * was already woken up by some other task + */ + down(&udev->serialize); + if (udev->state == USB_STATE_SUSPENDED) { + dev_dbg(&udev->dev, "RESUME (wakeup)\n"); + /* TRSMRCY = 10 msec */ + msleep(10); + status = finish_port_resume(udev); + } + up(&udev->serialize); + return status; +} + +static int hub_suspend(struct usb_interface *intf, u32 state) +{ + struct usb_hub *hub = usb_get_intfdata (intf); + struct usb_device *hdev = hub->hdev; + unsigned port; + int status; + + /* stop khubd and related activity */ + hub_quiesce(hub); + + /* then suspend every port */ + for (port = 0; port < hdev->maxchild; port++) { + struct usb_device *udev; + + udev = hdev->children [port]; + if (!udev) + continue; + down(&udev->serialize); + status = __usb_suspend_device(udev, port, state); + if (status < 0) + dev_dbg(&intf->dev, "suspend port %d --> %d\n", + port, status); + } + + intf->dev.power.power_state = state; + return 0; +} + +static int hub_resume(struct usb_interface *intf) +{ + struct usb_device *hdev = interface_to_usbdev(intf); + struct usb_hub *hub = usb_get_intfdata (intf); + unsigned port; + int status; + + for (port = 0; port < hdev->maxchild; port++) { + struct usb_device *udev; + u16 portstat, portchange; + + udev = hdev->children [port]; + status = hub_port_status(hdev, port, &portstat, &portchange); + if (status == 0) { + if (portchange & USB_PORT_STAT_C_SUSPEND) { + clear_port_feature(hdev, port + 1, + USB_PORT_FEAT_C_SUSPEND); + portchange &= ~USB_PORT_STAT_C_SUSPEND; + } + + /* let khubd handle disconnects etc */ + if (portchange) + continue; + } + + if (!udev) + continue; + down (&udev->serialize); + if (portstat & USB_PORT_STAT_SUSPEND) + status = hub_port_resume(hdev, port + 1); + else { + status = finish_port_resume(udev); + if (status < 0) + status = hub_port_disable(hdev, port); + if (status < 0) + dev_dbg(&intf->dev, "resume port %d --> %d\n", + port, status); + } + up(&udev->serialize); + } + intf->dev.power.power_state = PM_SUSPEND_ON; + + hub_reactivate(hub); + return 0; +} #else /* !CONFIG_USB_SUSPEND */ @@ -1574,6 +2139,7 @@ * a port enable-change occurs (often caused by EMI); * usb_reset_device() encounters changed descriptors (as from * a firmware download) + * caller already locked the hub */ static void hub_port_connect_change(struct usb_hub *hub, int port, u16 portstatus, u16 portchange) @@ -1780,7 +2346,8 @@ /* Lock the device, then check to see if we were * disconnected while waiting for the lock to succeed. */ - down(&hdev->serialize); + if (locktree(hdev) < 0) + break; if (hdev->state != USB_STATE_CONFIGURED || !hdev->actconfig || hub != usb_get_intfdata( @@ -2034,7 +2601,7 @@ } /** - * usb_reset_devce - perform a USB port reset to reinitialize a device + * usb_reset_device - perform a USB port reset to reinitialize a device * @udev: device to reset (not in SUSPENDED or NOTATTACHED state) * * WARNING - don't reset any device unless drivers for all of its @@ -2123,7 +2690,7 @@ struct usb_interface *intf = udev->actconfig->interface[i]; struct usb_interface_descriptor *desc; - /* set_interface resets host side toggle and halt status even + /* set_interface resets host side toggle even * for altsetting zero. the interface may have no driver. */ desc = &intf->cur_altsetting->desc; diff -Nru a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h --- a/drivers/usb/core/hub.h 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/core/hub.h 2004-08-04 17:58:03 -07:00 @@ -214,6 +214,8 @@ u8 power_budget; /* in 2mA units; or zero */ + unsigned quiescing:1; + unsigned has_indicators:1; enum hub_led_mode indicator[USB_MAXCHILDREN]; struct work_struct leds; diff -Nru a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c --- a/drivers/usb/core/inode.c 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/core/inode.c 2004-08-04 17:58:03 -07:00 @@ -345,30 +345,13 @@ return 0; } -static void d_unhash(struct dentry *dentry) -{ - dget(dentry); - spin_lock(&dcache_lock); - switch (atomic_read(&dentry->d_count)) { - default: - spin_unlock(&dcache_lock); - shrink_dcache_parent(dentry); - spin_lock(&dcache_lock); - if (atomic_read(&dentry->d_count) != 2) - break; - case 2: - __d_drop(dentry); - } - spin_unlock(&dcache_lock); -} - static int usbfs_rmdir(struct inode *dir, struct dentry *dentry) { int error = -ENOTEMPTY; struct inode * inode = dentry->d_inode; down(&inode->i_sem); - d_unhash(dentry); + dentry_unhash(dentry); if (usbfs_empty(dentry)) { dentry->d_inode->i_nlink -= 2; dput(dentry); diff -Nru a/drivers/usb/core/message.c b/drivers/usb/core/message.c --- a/drivers/usb/core/message.c 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/core/message.c 2004-08-04 17:58:03 -07:00 @@ -577,8 +577,13 @@ USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, (type << 8) + index, 0, buf, size, HZ * USB_CTRL_GET_TIMEOUT); - if (!(result == 0 || result == -EPIPE)) - break; + if (result == 0 || result == -EPIPE) + continue; + if (result > 1 && ((u8 *)buf)[1] != type) { + result = -EPROTO; + continue; + } + break; } return result; } diff -Nru a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig --- a/drivers/usb/gadget/Kconfig 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/gadget/Kconfig 2004-08-04 17:58:03 -07:00 @@ -275,7 +275,7 @@ dynamically linked module called "gadgetfs". config USB_FILE_STORAGE - tristate "File-backed Storage Gadget (DEVELOPMENT)" + tristate "File-backed Storage Gadget" # we don't support the SA1100 because of its limitations depends on USB_GADGET_SA1100 = n help @@ -288,7 +288,7 @@ dynamically linked module called "g_file_storage". config USB_FILE_STORAGE_TEST - bool "File-backed Storage Gadget test version" + bool "File-backed Storage Gadget testing version" depends on USB_FILE_STORAGE default n help diff -Nru a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c --- a/drivers/usb/gadget/dummy_hcd.c 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/gadget/dummy_hcd.c 2004-08-04 17:58:03 -07:00 @@ -596,14 +596,13 @@ /* "function" sysfs attribute */ static ssize_t -show_function (struct device *_dev, char *buf) +show_function (struct device *dev, char *buf) { - struct dummy *dum = the_controller; + struct dummy *dum = gadget_dev_to_dummy (dev); - if (!dum->driver->function - || strlen (dum->driver->function) > PAGE_SIZE) + if (!dum->driver || !dum->driver->function) return 0; - return snprintf (buf, PAGE_SIZE, "%s\n", dum->driver->function); + return scnprintf (buf, PAGE_SIZE, "%s\n", dum->driver->function); } DEVICE_ATTR (function, S_IRUGO, show_function, NULL); diff -Nru a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c --- a/drivers/usb/gadget/file_storage.c 2004-08-04 17:58:04 -07:00 +++ b/drivers/usb/gadget/file_storage.c 2004-08-04 17:58:04 -07:00 @@ -46,17 +46,16 @@ * * Backing storage is provided by a regular file or a block device, specified * by the "file" module parameter. Access can be limited to read-only by - * setting the optional "ro" module parameter. + * setting the optional "ro" module parameter. The gadget will indicate that + * it has removable media if the optional "removable" module parameter is set. * * The gadget supports the Control-Bulk (CB), Control-Bulk-Interrupt (CBI), * and Bulk-Only (also known as Bulk-Bulk-Bulk or BBB) transports, selected * by the optional "transport" module parameter. It also supports the * following protocols: RBC (0x01), ATAPI or SFF-8020i (0x02), QIC-157 (0c03), * UFI (0x04), SFF-8070i (0x05), and transparent SCSI (0x06), selected by - * the optional "protocol" module parameter. For testing purposes the - * gadget will indicate that it has removable media if the optional - * "removable" module parameter is set. In addition, the default Vendor ID, - * Product ID, and release number can be overridden. + * the optional "protocol" module parameter. In addition, the default + * Vendor ID, Product ID, and release number can be overridden. * * There is support for multiple logical units (LUNs), each of which has * its own backing file. The number of LUNs can be set using the optional @@ -79,13 +78,13 @@ * the files or block devices used for * backing storage * ro=b[,b...] Default false, booleans for read-only access + * removable Default false, boolean for removable media * luns=N Default N = number of filenames, number of * LUNs to support * transport=XXX Default BBB, transport name (CB, CBI, or BBB) * protocol=YYY Default SCSI, protocol name (RBC, 8020 or * ATAPI, QIC, UFI, 8070, or SCSI; * also 1 - 6) - * removable Default false, boolean for removable media * vendor=0xVVVV Default 0x0525 (NetChip), USB Vendor ID * product=0xPPPP Default 0xa4a5 (FSG), USB Product ID * release=0xRRRR Override the USB release number (bcdDevice) @@ -97,16 +96,16 @@ * boolean to permit the driver to halt * bulk endpoints * - * If CONFIG_USB_FILE_STORAGE_TEST is not set, only the "file" and "ro" - * options are available; default values are used for everything else. + * If CONFIG_USB_FILE_STORAGE_TEST is not set, only the "file", "ro", + * "removable", and "luns" options are available; default values are used + * for everything else. * * The pathnames of the backing files and the ro settings are available in * the attribute files "file" and "ro" in the lun subdirectory of the - * gadget's sysfs directory. If CONFIG_USB_FILE_STORAGE_TEST and the - * "removable" option are both set, writing to these files will simulate - * ejecting/loading the medium (writing an empty line means eject) and - * adjusting a write-enable tab. Changes to the ro setting are not allowed - * when the medium is loaded. + * gadget's sysfs directory. If the "removable" option is set, writing to + * these files will simulate ejecting/loading the medium (writing an empty + * line means eject) and adjusting a write-enable tab. Changes to the ro + * setting are not allowed when the medium is loaded. * * This gadget driver is heavily based on "Gadget Zero" by David Brownell. */ @@ -178,7 +177,10 @@ * Bulk-only specification requires a stall. In such cases the driver * will halt the endpoint and set a flag indicating that it should clear * the halt in software during the next device reset. Hopefully this - * will permit everything to work correctly. + * will permit everything to work correctly. Furthermore, although the + * specification allows the bulk-out endpoint to halt when the host sends + * too much data, implementing this would cause an unavoidable race. + * The driver will always use the "no-stall" approach for OUT transfers. * * One subtle point concerns sending status-stage responses for ep0 * requests. Some of these requests, such as device reset, can involve @@ -246,7 +248,7 @@ #define DRIVER_DESC "File-backed Storage Gadget" #define DRIVER_NAME "g_file_storage" -#define DRIVER_VERSION "21 March 2004" +#define DRIVER_VERSION "28 July 2004" static const char longname[] = DRIVER_DESC; static const char shortname[] = DRIVER_NAME; @@ -371,14 +373,17 @@ module_param_array(ro, bool, mod_data.num_ros, S_IRUGO); MODULE_PARM_DESC(ro, "true to force read-only"); +module_param_named(luns, mod_data.nluns, uint, S_IRUGO); +MODULE_PARM_DESC(luns, "number of LUNs"); -/* In the non-TEST version, only the file and ro module parameters +module_param_named(removable, mod_data.removable, bool, S_IRUGO); +MODULE_PARM_DESC(removable, "true to simulate removable media"); + + +/* In the non-TEST version, only the module parameters listed above * are available. */ #ifdef CONFIG_USB_FILE_STORAGE_TEST -module_param_named(luns, mod_data.nluns, uint, S_IRUGO); -MODULE_PARM_DESC(luns, "number of LUNs"); - module_param_named(transport, mod_data.transport_parm, charp, S_IRUGO); MODULE_PARM_DESC(transport, "type of transport (BBB, CBI, or CB)"); @@ -386,9 +391,6 @@ MODULE_PARM_DESC(protocol, "type of protocol (RBC, 8020, QIC, UFI, " "8070, or SCSI)"); -module_param_named(removable, mod_data.removable, bool, S_IRUGO); -MODULE_PARM_DESC(removable, "true to simulate removable media"); - module_param_named(vendor, mod_data.vendor, ushort, S_IRUGO); MODULE_PARM_DESC(vendor, "USB Vendor ID"); @@ -525,11 +527,6 @@ * parts of the driver that aren't used in the non-TEST version. Even gcc * can recognize when a test of a constant expression yields a dead code * path. - * - * Also, in the non-TEST version, open_backing_file() is only used during - * initialization and the sysfs attribute store_xxx routines aren't used - * at all. We will define NORMALLY_INIT to mark them as __init so they - * don't occupy kernel code space unnecessarily. */ #ifdef CONFIG_USB_FILE_STORAGE_TEST @@ -537,16 +534,12 @@ #define transport_is_bbb() (mod_data.transport_type == USB_PR_BULK) #define transport_is_cbi() (mod_data.transport_type == USB_PR_CBI) #define protocol_is_scsi() (mod_data.protocol_type == USB_SC_SCSI) -#define backing_file_is_open(curlun) ((curlun)->filp != NULL) -#define NORMALLY_INIT #else #define transport_is_bbb() 1 #define transport_is_cbi() 0 #define protocol_is_scsi() 1 -#define backing_file_is_open(curlun) 1 -#define NORMALLY_INIT __init #endif /* CONFIG_USB_FILE_STORAGE_TEST */ @@ -567,6 +560,8 @@ struct device dev; }; +#define backing_file_is_open(curlun) ((curlun)->filp != NULL) + static inline struct lun *dev_to_lun(struct device *dev) { return container_of(dev, struct lun, dev); @@ -659,6 +654,7 @@ unsigned long atomic_bitflags; #define REGISTERED 0 #define CLEAR_BULK_HALTS 1 +#define SUSPENDED 2 struct usb_ep *bulk_in; struct usb_ep *bulk_out; @@ -1041,8 +1037,6 @@ function = fs_function; len = usb_gadget_config_buf(&config_desc, buf, EP0_BUFSIZE, function); - if (len < 0) - return len; ((struct usb_config_descriptor *) buf)->bDescriptorType = type; return len; } @@ -1172,9 +1166,10 @@ wakeup_thread(fsg); } + +#ifdef CONFIG_USB_FILE_STORAGE_TEST static void intr_in_complete(struct usb_ep *ep, struct usb_request *req) { -#ifdef CONFIG_USB_FILE_STORAGE_TEST struct fsg_dev *fsg = (struct fsg_dev *) ep->driver_data; struct fsg_buffhd *bh = (struct fsg_buffhd *) req->context; @@ -1190,17 +1185,21 @@ bh->state = BUF_STATE_EMPTY; spin_unlock(&fsg->lock); wakeup_thread(fsg); -#endif /* CONFIG_USB_FILE_STORAGE_TEST */ } +#else +static void intr_in_complete(struct usb_ep *ep, struct usb_request *req) +{} +#endif /* CONFIG_USB_FILE_STORAGE_TEST */ + /*-------------------------------------------------------------------------*/ /* Ep0 class-specific handlers. These always run in_irq. */ +#ifdef CONFIG_USB_FILE_STORAGE_TEST static void received_cbi_adsc(struct fsg_dev *fsg, struct fsg_buffhd *bh) { -#ifdef CONFIG_USB_FILE_STORAGE_TEST struct usb_request *req = fsg->ep0req; static u8 cbi_reset_cmnd[6] = { SC_SEND_DIAGNOSTIC, 4, 0xff, 0xff, 0xff, 0xff}; @@ -1238,9 +1237,13 @@ spin_unlock(&fsg->lock); wakeup_thread(fsg); -#endif /* CONFIG_USB_FILE_STORAGE_TEST */ } +#else +static void received_cbi_adsc(struct fsg_dev *fsg, struct fsg_buffhd *bh) +{} +#endif /* CONFIG_USB_FILE_STORAGE_TEST */ + static int class_setup_req(struct fsg_dev *fsg, const struct usb_ctrlrequest *ctrl) @@ -1465,8 +1468,8 @@ /* Respond with data/status or defer until later? */ if (rc >= 0 && rc != DELAYED_STATUS) { fsg->ep0req->length = rc; - fsg->ep0req->zero = rc < ctrl->wLength - && (rc % gadget->ep0->maxpacket) == 0; + fsg->ep0req->zero = (rc < ctrl->wLength && + (rc % gadget->ep0->maxpacket) == 0); fsg->ep0req_name = (ctrl->bRequestType & USB_DIR_IN ? "ep0-in" : "ep0-out"); rc = ep0_queue(fsg); @@ -2443,14 +2446,19 @@ rc = -EINTR; } - /* We haven't processed all the incoming data. If we are - * allowed to stall, halt the bulk-out endpoint and cancel - * any outstanding requests. */ + /* We haven't processed all the incoming data. Even though + * we may be allowed to stall, doing so would cause a race. + * The controller may already have ACK'ed all the remaining + * bulk-out packets, in which case the host wouldn't see a + * STALL. Not realizing the endpoint was halted, it wouldn't + * clear the halt -- leading to problems later on. */ +#if 0 else if (mod_data.can_stall) { fsg_set_halt(fsg, fsg->bulk_out); raise_exception(fsg, FSG_STATE_ABORT_BULK_OUT); rc = -EINTR; } +#endif /* We can't stall. Read in the excess data and throw it * all away. */ @@ -2513,7 +2521,7 @@ } else if (mod_data.transport_type == USB_PR_CB) { - /* Control-Bulk transport has no status stage! */ + /* Control-Bulk transport has no status phase! */ return 0; } else { // USB_PR_CBI @@ -2603,8 +2611,10 @@ fsg->residue = fsg->usb_amount_left = fsg->data_size; /* Conflicting data directions is a phase error */ - if (fsg->data_dir != data_dir && fsg->data_size_from_cmnd > 0) - goto phase_error; + if (fsg->data_dir != data_dir && fsg->data_size_from_cmnd > 0) { + fsg->phase_error = 1; + return -EINVAL; + } /* Verify the length of the command itself */ if (cmnd_size != fsg->cmnd_size) { @@ -2613,8 +2623,10 @@ * with cbw->Length == 12 (it should be 6). */ if (fsg->cmnd[0] == SC_REQUEST_SENSE && fsg->cmnd_size == 12) cmnd_size = fsg->cmnd_size; - else - goto phase_error; + else { + fsg->phase_error = 1; + return -EINVAL; + } } /* Check that the LUN values are oonsistent */ @@ -2674,10 +2686,6 @@ } return 0; - -phase_error: - fsg->phase_error = 1; - return -EINVAL; } @@ -3424,8 +3432,7 @@ /* If the next two routines are called while the gadget is registered, * the caller must own fsg->filesem for writing. */ -static int NORMALLY_INIT open_backing_file(struct lun *curlun, - const char *filename) +static int open_backing_file(struct lun *curlun, const char *filename) { int ro; struct file *filp = NULL; @@ -3550,8 +3557,7 @@ } -ssize_t NORMALLY_INIT store_ro(struct device *dev, const char *buf, - size_t count) +ssize_t store_ro(struct device *dev, const char *buf, size_t count) { ssize_t rc = count; struct lun *curlun = dev_to_lun(dev); @@ -3575,8 +3581,7 @@ return rc; } -ssize_t NORMALLY_INIT store_file(struct device *dev, const char *buf, - size_t count) +ssize_t store_file(struct device *dev, const char *buf, size_t count) { struct lun *curlun = dev_to_lun(dev); struct fsg_dev *fsg = (struct fsg_dev *) dev_get_drvdata(dev); @@ -3805,9 +3810,8 @@ goto out; } - /* Create the LUNs and open their backing files. We can't register - * the LUN devices until the gadget itself is registered, which - * doesn't happen until after fsg_bind() returns. */ + /* Create the LUNs, open their backing files, and register the + * LUN devices in sysfs. */ fsg->luns = kmalloc(i * sizeof(struct lun), GFP_KERNEL); if (!fsg->luns) { rc = -ENOMEM; @@ -3825,6 +3829,15 @@ snprintf(curlun->dev.bus_id, BUS_ID_SIZE, "%s-lun%d", gadget->dev.bus_id, i); + if ((rc = device_register(&curlun->dev)) != 0) + INFO(fsg, "failed to register LUN%d: %d\n", i, rc); + else { + curlun->registered = 1; + curlun->dev.release = lun_release; + device_create_file(&curlun->dev, &dev_attr_ro); + device_create_file(&curlun->dev, &dev_attr_file); + } + if (file[i] && *file[i]) { if ((rc = open_backing_file(curlun, file[i])) != 0) goto out; @@ -3974,6 +3987,25 @@ /*-------------------------------------------------------------------------*/ +static void fsg_suspend(struct usb_gadget *gadget) +{ + struct fsg_dev *fsg = get_gadget_data(gadget); + + DBG(fsg, "suspend\n"); + set_bit(SUSPENDED, &fsg->atomic_bitflags); +} + +static void fsg_resume(struct usb_gadget *gadget) +{ + struct fsg_dev *fsg = get_gadget_data(gadget); + + DBG(fsg, "resume\n"); + clear_bit(SUSPENDED, &fsg->atomic_bitflags); +} + + +/*-------------------------------------------------------------------------*/ + static struct usb_gadget_driver fsg_driver = { #ifdef CONFIG_USB_GADGET_DUALSPEED .speed = USB_SPEED_HIGH, @@ -3985,6 +4017,8 @@ .unbind = fsg_unbind, .disconnect = fsg_disconnect, .setup = fsg_setup, + .suspend = fsg_suspend, + .resume = fsg_resume, .driver = { .name = (char *) shortname, @@ -4024,8 +4058,6 @@ { int rc; struct fsg_dev *fsg; - int i; - struct lun *curlun; if ((rc = fsg_alloc()) != 0) return rc; @@ -4035,19 +4067,6 @@ return rc; } set_bit(REGISTERED, &fsg->atomic_bitflags); - - /* Register the LUN devices and their attribute files */ - for (i = 0; i < fsg->nluns; ++i) { - curlun = &fsg->luns[i]; - if ((rc = device_register(&curlun->dev)) != 0) - INFO(fsg, "failed to register LUN%d: %d\n", i, rc); - else { - curlun->registered = 1; - curlun->dev.release = lun_release; - device_create_file(&curlun->dev, &dev_attr_ro); - device_create_file(&curlun->dev, &dev_attr_file); - } - } /* Tell the thread to start working */ complete(&fsg->thread_notifier); diff -Nru a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c --- a/drivers/usb/gadget/pxa2xx_udc.c 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/gadget/pxa2xx_udc.c 2004-08-04 17:58:03 -07:00 @@ -1508,7 +1508,7 @@ /* caller must be able to sleep in order to cope * with startup transients. */ - schedule_timeout(HZ/10); + msleep(100); /* enable suspend/resume and reset irqs */ udc_clear_mask_UDCCR(UDCCR_SRM | UDCCR_REM); diff -Nru a/drivers/usb/host/hc_sl811.c b/drivers/usb/host/hc_sl811.c --- a/drivers/usb/host/hc_sl811.c 2004-08-04 17:58:04 -07:00 +++ b/drivers/usb/host/hc_sl811.c 2004-08-04 17:58:04 -07:00 @@ -106,14 +106,14 @@ static int sofWaitCnt = 0; -MODULE_PARM (urb_debug, "i"); +module_param(urb_debug, int, 0); MODULE_PARM_DESC (urb_debug, "debug urb messages, default is 0 (no)"); -MODULE_PARM (base_addr, "i"); +module_param(base_addr, int, 0); MODULE_PARM_DESC (base_addr, "sl811 base address 0xd3800000"); -MODULE_PARM (data_reg_addr, "i"); +module_param(data_reg_addr, int, 0); MODULE_PARM_DESC (data_reg_addr, "sl811 data register address 0xd3810000"); -MODULE_PARM (irq, "i"); +module_param(irq, int, 0); MODULE_PARM_DESC (irq, "IRQ 34 (default)"); static int hc_reset (hci_t * hci); diff -Nru a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c --- a/drivers/usb/host/ohci-omap.c 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/host/ohci-omap.c 2004-08-04 17:58:03 -07:00 @@ -658,7 +658,7 @@ return ret; } -MODULE_PARM(hmc_mode, "hmc_mode"); +module_param(hmc_mode, int, 0); static void __exit ohci_hcd_omap_cleanup (void) { diff -Nru a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c --- a/drivers/usb/host/uhci-hcd.c 2004-08-04 17:58:04 -07:00 +++ b/drivers/usb/host/uhci-hcd.c 2004-08-04 17:58:04 -07:00 @@ -82,7 +82,7 @@ #else static int debug = 0; #endif -MODULE_PARM(debug, "i"); +module_param(debug, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(debug, "Debug level"); static char *errbuf; #define ERRBUF_LEN (32 * 1024) diff -Nru a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c --- a/drivers/usb/input/aiptek.c 2004-08-04 17:58:04 -07:00 +++ b/drivers/usb/input/aiptek.c 2004-08-04 17:58:04 -07:00 @@ -2289,9 +2289,9 @@ MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); -MODULE_PARM(programmableDelay, "i"); +module_param(programmableDelay, int, 0); MODULE_PARM_DESC(programmableDelay, "delay used during tablet programming"); -MODULE_PARM(jitterDelay, "i"); +module_param(jitterDelay, int, 0); MODULE_PARM_DESC(jitterDelay, "stylus/mouse settlement delay"); module_init(aiptek_init); diff -Nru a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c --- a/drivers/usb/input/hid-core.c 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/input/hid-core.c 2004-08-04 17:58:03 -07:00 @@ -1619,11 +1619,17 @@ struct usb_endpoint_descriptor *endpoint; int pipe; + int interval; endpoint = &interface->endpoint[n].desc; if ((endpoint->bmAttributes & 3) != 3) /* Not an interrupt endpoint */ continue; + /* handle potential highspeed HID correctly */ + interval = endpoint->bInterval; + if (dev->speed == USB_SPEED_HIGH) + interval = 1 << (interval - 1); + if (endpoint->bEndpointAddress & USB_DIR_IN) { int len; @@ -1636,7 +1642,7 @@ if (len > HID_BUFFER_SIZE) len = HID_BUFFER_SIZE; usb_fill_int_urb(hid->urbin, dev, pipe, hid->inbuf, len, - hid_irq_in, hid, endpoint->bInterval); + hid_irq_in, hid, interval); hid->urbin->transfer_dma = hid->inbuf_dma; hid->urbin->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; } else { @@ -1646,7 +1652,7 @@ goto fail; pipe = usb_sndintpipe(dev, endpoint->bEndpointAddress); usb_fill_int_urb(hid->urbout, dev, pipe, hid->outbuf, 0, - hid_irq_out, hid, 1); + hid_irq_out, hid, interval); hid->urbout->transfer_dma = hid->outbuf_dma; hid->urbout->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; } diff -Nru a/drivers/usb/input/kbtab.c b/drivers/usb/input/kbtab.c --- a/drivers/usb/input/kbtab.c 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/input/kbtab.c 2004-08-04 17:58:03 -07:00 @@ -26,10 +26,9 @@ #define USB_VENDOR_ID_KBGEAR 0x084e -static int kb_pressure_click = 0x10; -MODULE_PARM (kb_pressure_click,"i"); -MODULE_PARM_DESC(kb_pressure_click, - "pressure threshold for clicks"); +static int kb_pressure_click = 0x10; +module_param(kb_pressure_click, int, 0); +MODULE_PARM_DESC(kb_pressure_click, "pressure threshold for clicks"); struct kbtab { signed char *data; diff -Nru a/drivers/usb/media/dabusb.c b/drivers/usb/media/dabusb.c --- a/drivers/usb/media/dabusb.c 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/media/dabusb.c 2004-08-04 17:58:03 -07:00 @@ -868,7 +868,7 @@ MODULE_DESCRIPTION( DRIVER_DESC ); MODULE_LICENSE("GPL"); -MODULE_PARM (buffers, "i"); +module_param(buffers, int, 0); MODULE_PARM_DESC (buffers, "Number of buffers (default=256)"); module_init (dabusb_init); diff -Nru a/drivers/usb/media/konicawc.c b/drivers/usb/media/konicawc.c --- a/drivers/usb/media/konicawc.c 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/media/konicawc.c 2004-08-04 17:58:03 -07:00 @@ -68,7 +68,7 @@ /* Some default values for initial camera settings, can be set by modprobe */ -static enum frame_sizes size; +static int size; static int speed = 6; /* Speed (fps) 0 (slowest) to 6 (fastest) */ static int brightness = MAX_BRIGHTNESS/2; static int contrast = MAX_CONTRAST/2; @@ -928,23 +928,23 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Simon Evans "); MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_PARM(speed, "i"); +module_param(speed, int, 0); MODULE_PARM_DESC(speed, "Initial speed: 0 (slowest) - 6 (fastest)"); -MODULE_PARM(size, "i"); +module_param(size, int, 0); MODULE_PARM_DESC(size, "Initial Size 0: 160x120 1: 160x136 2: 176x144 3: 320x240"); -MODULE_PARM(brightness, "i"); +module_param(brightness, int, 0); MODULE_PARM_DESC(brightness, "Initial brightness 0 - 108"); -MODULE_PARM(contrast, "i"); +module_param(contrast, int, 0); MODULE_PARM_DESC(contrast, "Initial contrast 0 - 108"); -MODULE_PARM(saturation, "i"); +module_param(saturation, int, 0); MODULE_PARM_DESC(saturation, "Initial saturation 0 - 108"); -MODULE_PARM(sharpness, "i"); +module_param(sharpness, int, 0); MODULE_PARM_DESC(sharpness, "Initial brightness 0 - 108"); -MODULE_PARM(whitebal, "i"); +module_param(whitebal, int, 0); MODULE_PARM_DESC(whitebal, "Initial white balance 0 - 363"); #ifdef CONFIG_USB_DEBUG -MODULE_PARM(debug, "i"); +module_param(debug, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(debug, "Debug level: 0-9 (default=0)"); #endif diff -Nru a/drivers/usb/media/ov511.c b/drivers/usb/media/ov511.c --- a/drivers/usb/media/ov511.c 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/media/ov511.c 2004-08-04 17:58:03 -07:00 @@ -119,78 +119,78 @@ static int mirror; static int ov518_color; -MODULE_PARM(autobright, "i"); +module_param(autobright, int, 0); MODULE_PARM_DESC(autobright, "Sensor automatically changes brightness"); -MODULE_PARM(autogain, "i"); +module_param(autogain, int, 0); MODULE_PARM_DESC(autogain, "Sensor automatically changes gain"); -MODULE_PARM(autoexp, "i"); +module_param(autoexp, int, 0); MODULE_PARM_DESC(autoexp, "Sensor automatically changes exposure"); -MODULE_PARM(debug, "i"); +module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level: 0=none, 1=inits, 2=warning, 3=config, 4=functions, 5=max"); -MODULE_PARM(snapshot, "i"); +module_param(snapshot, int, 0); MODULE_PARM_DESC(snapshot, "Enable snapshot mode"); -MODULE_PARM(cams, "i"); +module_param(cams, int, 0); MODULE_PARM_DESC(cams, "Number of simultaneous cameras"); -MODULE_PARM(compress, "i"); +module_param(compress, int, 0); MODULE_PARM_DESC(compress, "Turn on compression"); -MODULE_PARM(testpat, "i"); +module_param(testpat, int, 0); MODULE_PARM_DESC(testpat, "Replace image with vertical bar testpattern (only partially working)"); -MODULE_PARM(dumppix, "i"); +module_param(dumppix, int, 0); MODULE_PARM_DESC(dumppix, "Dump raw pixel data"); -MODULE_PARM(led, "i"); +module_param(led, int, 0); MODULE_PARM_DESC(led, "LED policy (OV511+ or later). 0=off, 1=on (default), 2=auto (on when open)"); -MODULE_PARM(dump_bridge, "i"); +module_param(dump_bridge, int, 0); MODULE_PARM_DESC(dump_bridge, "Dump the bridge registers"); -MODULE_PARM(dump_sensor, "i"); +module_param(dump_sensor, int, 0); MODULE_PARM_DESC(dump_sensor, "Dump the sensor registers"); -MODULE_PARM(printph, "i"); +module_param(printph, int, 0); MODULE_PARM_DESC(printph, "Print frame start/end headers"); -MODULE_PARM(phy, "i"); +module_param(phy, int, 0); MODULE_PARM_DESC(phy, "Prediction range (horiz. Y)"); -MODULE_PARM(phuv, "i"); +module_param(phuv, int, 0); MODULE_PARM_DESC(phuv, "Prediction range (horiz. UV)"); -MODULE_PARM(pvy, "i"); +module_param(pvy, int, 0); MODULE_PARM_DESC(pvy, "Prediction range (vert. Y)"); -MODULE_PARM(pvuv, "i"); +module_param(pvuv, int, 0); MODULE_PARM_DESC(pvuv, "Prediction range (vert. UV)"); -MODULE_PARM(qhy, "i"); +module_param(qhy, int, 0); MODULE_PARM_DESC(qhy, "Quantization threshold (horiz. Y)"); -MODULE_PARM(qhuv, "i"); +module_param(qhuv, int, 0); MODULE_PARM_DESC(qhuv, "Quantization threshold (horiz. UV)"); -MODULE_PARM(qvy, "i"); +module_param(qvy, int, 0); MODULE_PARM_DESC(qvy, "Quantization threshold (vert. Y)"); -MODULE_PARM(qvuv, "i"); +module_param(qvuv, int, 0); MODULE_PARM_DESC(qvuv, "Quantization threshold (vert. UV)"); -MODULE_PARM(lightfreq, "i"); +module_param(lightfreq, int, 0); MODULE_PARM_DESC(lightfreq, "Light frequency. Set to 50 or 60 Hz, or zero for default settings"); -MODULE_PARM(bandingfilter, "i"); +module_param(bandingfilter, int, 0); MODULE_PARM_DESC(bandingfilter, "Enable banding filter (to reduce effects of fluorescent lighting)"); -MODULE_PARM(clockdiv, "i"); +module_param(clockdiv, int, 0); MODULE_PARM_DESC(clockdiv, "Force pixel clock divisor to a specific value"); -MODULE_PARM(packetsize, "i"); +module_param(packetsize, int, 0); MODULE_PARM_DESC(packetsize, "Force a specific isoc packet size"); -MODULE_PARM(framedrop, "i"); +module_param(framedrop, int, 0); MODULE_PARM_DESC(framedrop, "Force a specific frame drop register setting"); -MODULE_PARM(fastset, "i"); +module_param(fastset, int, 0); MODULE_PARM_DESC(fastset, "Allows picture settings to take effect immediately"); -MODULE_PARM(force_palette, "i"); +module_param(force_palette, int, 0); MODULE_PARM_DESC(force_palette, "Force the palette to a specific value"); -MODULE_PARM(backlight, "i"); +module_param(backlight, int, 0); MODULE_PARM_DESC(backlight, "For objects that are lit from behind"); -MODULE_PARM(unit_video, "1-" __MODULE_STRING(OV511_MAX_UNIT_VIDEO) "i"); -MODULE_PARM_DESC(unit_video, - "Force use of specific minor number(s). 0 is not allowed."); -MODULE_PARM(remove_zeros, "i"); +/*module_param_array(unit_video, int, OV511_MAX_UNIT_VIDEO, 0); */ +/*MODULE_PARM_DESC(unit_video, + "Force use of specific minor number(s). 0 is not allowed."); */ +module_param(remove_zeros, int, 0); MODULE_PARM_DESC(remove_zeros, "Remove zero-padding from uncompressed incoming data"); -MODULE_PARM(mirror, "i"); +module_param(mirror, int, 0); MODULE_PARM_DESC(mirror, "Reverse image horizontally"); -MODULE_PARM(ov518_color, "i"); +module_param(ov518_color, int, 0); MODULE_PARM_DESC(ov518_color, "Enable OV518 color (experimental)"); MODULE_AUTHOR(DRIVER_AUTHOR); @@ -1169,7 +1169,7 @@ return -EIO; /* Wait for it to initialize */ - schedule_timeout(1 + 150 * HZ / 1000); + msleep(150); for (i = 0, success = 0; i < i2c_detect_tries && !success; i++) { if ((i2c_r(ov, OV7610_REG_ID_HIGH) == 0x7F) && @@ -1182,7 +1182,7 @@ if (i2c_w(ov, 0x12, 0x80) < 0) return -EIO; /* Wait for it to initialize */ - schedule_timeout(1 + 150 * HZ / 1000); + msleep(150); /* Dummy read to sync I2C */ if (i2c_r(ov, 0x00) < 0) return -EIO; @@ -4947,7 +4947,7 @@ return -1; /* Wait for it to initialize */ - schedule_timeout(1 + 150 * HZ / 1000); + msleep(150); i = 0; success = 0; diff -Nru a/drivers/usb/media/pwc-if.c b/drivers/usb/media/pwc-if.c --- a/drivers/usb/media/pwc-if.c 2004-08-04 17:58:04 -07:00 +++ b/drivers/usb/media/pwc-if.c 2004-08-04 17:58:04 -07:00 @@ -2009,33 +2009,35 @@ * Initialization code & module stuff */ -static char *size = NULL; +static char size[PSZ_MAX]; static int fps = 0; static int fbufs = 0; static int mbufs = 0; static int trace = -1; static int compression = -1; -static int leds[2] = { -1, -1 }; static char *dev_hint[MAX_DEV_HINTS] = { }; -MODULE_PARM(size, "s"); +module_param_string(size, size, PSZ_MAX, 0); MODULE_PARM_DESC(size, "Initial image size. One of sqcif, qsif, qcif, sif, cif, vga"); -MODULE_PARM(fps, "i"); +module_param(fps, int, 0); MODULE_PARM_DESC(fps, "Initial frames per second. Varies with model, useful range 5-30"); -MODULE_PARM(fbufs, "i"); +module_param(fbufs, int, 0); MODULE_PARM_DESC(fbufs, "Number of internal frame buffers to reserve"); -MODULE_PARM(mbufs, "i"); +module_param(mbufs, int, 0); MODULE_PARM_DESC(mbufs, "Number of external (mmap()ed) image buffers"); -MODULE_PARM(trace, "i"); +module_param(trace, int, 0); MODULE_PARM_DESC(trace, "For debugging purposes"); -MODULE_PARM(power_save, "i"); +module_param(power_save, int, 0); MODULE_PARM_DESC(power_save, "Turn power save feature in camera on or off"); -MODULE_PARM(compression, "i"); +module_param(compression, int, 0); MODULE_PARM_DESC(compression, "Preferred compression quality. Range 0 (uncompressed) to 3 (high compression)"); -MODULE_PARM(leds, "2i"); -MODULE_PARM_DESC(leds, "LED on,off time in milliseconds"); -MODULE_PARM(dev_hint, "0-20s"); -MODULE_PARM_DESC(dev_hint, "Device node hints"); +module_param(led_on, int, 0); +MODULE_PARM_DESC(led_on, "LED on time in milliseconds"); +module_param(led_off, int, 0); +MODULE_PARM_DESC(led_off, "LED off time in milliseconds"); +/* Commented out, as you should be using udev instead of crud like this... */ +/* MODULE_PARM(dev_hint, "0-20s"); */ +/* MODULE_PARM_DESC(dev_hint, "Device node hints"); */ MODULE_DESCRIPTION("Philips & OEM USB webcam driver"); MODULE_AUTHOR("Nemosoft Unv. "); @@ -2060,7 +2062,7 @@ Info("Default framerate set to %d.\n", default_fps); } - if (size) { + if (strlen(size)) { /* string; try matching with array */ for (sz = 0; sz < PSZ_MAX; sz++) { if (!strcmp(sizenames[sz], size)) { /* Found! */ @@ -2104,10 +2106,6 @@ } if (power_save) Info("Enabling power save on open/close.\n"); - if (leds[0] >= 0) - led_on = leds[0]; - if (leds[1] >= 0) - led_off = leds[1]; /* Big device node whoopla. Basicly, it allows you to assign a device node (/dev/videoX) to a camera, based on its type diff -Nru a/drivers/usb/media/se401.c b/drivers/usb/media/se401.c --- a/drivers/usb/media/se401.c 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/media/se401.c 2004-08-04 17:58:03 -07:00 @@ -53,9 +53,9 @@ MODULE_AUTHOR("Jeroen Vreeken "); MODULE_DESCRIPTION("SE401 USB Camera Driver"); MODULE_LICENSE("GPL"); -MODULE_PARM(flickerless, "i"); +module_param(flickerless, int, 0); MODULE_PARM_DESC(flickerless, "Net frequency to adjust exposure time to (0/50/60)"); -MODULE_PARM(video_nr, "i"); +module_param(video_nr, int, 0); static struct usb_driver se401_driver; diff -Nru a/drivers/usb/media/stv680.c b/drivers/usb/media/stv680.c --- a/drivers/usb/media/stv680.c 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/media/stv680.c 2004-08-04 17:58:03 -07:00 @@ -93,11 +93,11 @@ MODULE_AUTHOR (DRIVER_AUTHOR); MODULE_DESCRIPTION (DRIVER_DESC); MODULE_LICENSE ("GPL"); -MODULE_PARM (debug, "i"); +module_param(debug, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC (debug, "Debug enabled or not"); -MODULE_PARM (swapRGB_on, "i"); +module_param(swapRGB_on, int, 0); MODULE_PARM_DESC (swapRGB_on, "Red/blue swap: 1=always, 0=auto, -1=never"); -MODULE_PARM (video_nr, "i"); +module_param(video_nr, int, 0); /******************************************************************** * diff -Nru a/drivers/usb/media/ultracam.c b/drivers/usb/media/ultracam.c --- a/drivers/usb/media/ultracam.c 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/media/ultracam.c 2004-08-04 17:58:03 -07:00 @@ -60,9 +60,9 @@ static int init_hue = 128; static int hue_correction = 128; -MODULE_PARM(debug, "i"); +module_param(debug, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(debug, "Debug level: 0-9 (default=0)"); -MODULE_PARM(flags, "i"); +module_param(flags, int, 0); MODULE_PARM_DESC(flags, "Bitfield: 0=VIDIOCSYNC, " "1=B/W, " @@ -71,18 +71,18 @@ "4=test pattern, " "5=separate frames, " "6=clean frames"); -MODULE_PARM(framerate, "i"); +module_param(framerate, int, 0); MODULE_PARM_DESC(framerate, "Framerate setting: 0=slowest, 6=fastest (default=2)"); -MODULE_PARM(init_brightness, "i"); +module_param(init_brightness, int, 0); MODULE_PARM_DESC(init_brightness, "Brightness preconfiguration: 0-255 (default=128)"); -MODULE_PARM(init_contrast, "i"); +module_param(init_contrast, int, 0); MODULE_PARM_DESC(init_contrast, "Contrast preconfiguration: 0-255 (default=192)"); -MODULE_PARM(init_color, "i"); +module_param(init_color, int, 0); MODULE_PARM_DESC(init_color, "Color preconfiguration: 0-255 (default=128)"); -MODULE_PARM(init_hue, "i"); +module_param(init_hue, int, 0); MODULE_PARM_DESC(init_hue, "Hue preconfiguration: 0-255 (default=128)"); -MODULE_PARM(hue_correction, "i"); +module_param(hue_correction, int, 0); MODULE_PARM_DESC(hue_correction, "YUV colorspace regulation: 0-255 (default=128)"); /* diff -Nru a/drivers/usb/media/usbvideo.c b/drivers/usb/media/usbvideo.c --- a/drivers/usb/media/usbvideo.c 2004-08-04 17:58:04 -07:00 +++ b/drivers/usb/media/usbvideo.c 2004-08-04 17:58:04 -07:00 @@ -34,7 +34,7 @@ #endif static int video_nr = -1; -MODULE_PARM(video_nr, "i"); +module_param(video_nr, int, 0); /* * Local prototypes. diff -Nru a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c --- a/drivers/usb/misc/auerswald.c 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/misc/auerswald.c 2004-08-04 17:58:03 -07:00 @@ -1976,8 +1976,7 @@ dbg ("Version is %X", cp->version); /* allow some time to settle the device */ - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(HZ/3); + msleep(334); /* Try to get a suitable textual description of the device */ /* Device name:*/ diff -Nru a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c --- a/drivers/usb/misc/legousbtower.c 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/misc/legousbtower.c 2004-08-04 17:58:03 -07:00 @@ -103,7 +103,7 @@ #define DRIVER_DESC "LEGO USB Tower Driver" /* Module parameters */ -MODULE_PARM(debug, "i"); +module_param(debug, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(debug, "Debug enabled or not"); /* The defaults are chosen to work with the latest versions of leJOS and NQC. @@ -114,7 +114,7 @@ * (417 for datalog uploads), and packet_timeout should be set. */ static size_t read_buffer_size = 480; -MODULE_PARM(read_buffer_size, "i"); +module_param(read_buffer_size, int, 0); MODULE_PARM_DESC(read_buffer_size, "Read buffer size"); /* Some legacy software likes to send packets in one piece. @@ -124,7 +124,7 @@ * if the software is not prepared to wait long enough. */ static size_t write_buffer_size = 480; -MODULE_PARM(write_buffer_size, "i"); +module_param(write_buffer_size, int, 0); MODULE_PARM_DESC(write_buffer_size, "Write buffer size"); /* Some legacy software expects reads to contain whole LASM packets. @@ -138,7 +138,7 @@ * Set it to 0 to disable. */ static int packet_timeout = 50; -MODULE_PARM(packet_timeout, "i"); +module_param(packet_timeout, int, 0); MODULE_PARM_DESC(packet_timeout, "Packet timeout in ms"); /* Some legacy software expects blocking reads to time out. @@ -146,7 +146,7 @@ * Set it to 0 to disable. */ static int read_timeout = 200; -MODULE_PARM(read_timeout, "i"); +module_param(read_timeout, int, 0); MODULE_PARM_DESC(read_timeout, "Read timeout in ms"); /* As of kernel version 2.6.4 ehci-hcd uses an @@ -159,11 +159,11 @@ * or set to 0 to use the standard interval from the endpoint descriptors. */ static int interrupt_in_interval = 2; -MODULE_PARM(interrupt_in_interval, "i"); +module_param(interrupt_in_interval, int, 0); MODULE_PARM_DESC(interrupt_in_interval, "Interrupt in interval in ms"); static int interrupt_out_interval = 8; -MODULE_PARM(interrupt_out_interval, "i"); +module_param(interrupt_out_interval, int, 0); MODULE_PARM_DESC(interrupt_out_interval, "Interrupt out interval in ms"); /* Define these values to match your device */ diff -Nru a/drivers/usb/misc/tiglusb.c b/drivers/usb/misc/tiglusb.c --- a/drivers/usb/misc/tiglusb.c 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/misc/tiglusb.c 2004-08-04 17:58:03 -07:00 @@ -560,7 +560,7 @@ MODULE_DESCRIPTION (DRIVER_DESC); MODULE_LICENSE (DRIVER_LICENSE); -MODULE_PARM (timeout, "i"); +module_param(timeout, int, 0); MODULE_PARM_DESC (timeout, "Timeout in tenths of seconds (default=1.5 seconds)"); /* --------------------------------------------------------------------- */ diff -Nru a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c --- a/drivers/usb/net/pegasus.c 2004-08-04 17:58:04 -07:00 +++ b/drivers/usb/net/pegasus.c 2004-08-04 17:58:04 -07:00 @@ -78,8 +78,8 @@ MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); -MODULE_PARM(loopback, "i"); -MODULE_PARM(mii_mode, "i"); +module_param(loopback, bool, 0); +module_param(mii_mode, bool, 0); MODULE_PARM_DESC(loopback, "Enable MAC loopback mode (bit 0)"); MODULE_PARM_DESC(mii_mode, "Enable HomePNA mode (bit 0),default=MII mode = 0"); diff -Nru a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c --- a/drivers/usb/net/usbnet.c 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/net/usbnet.c 2004-08-04 17:58:03 -07:00 @@ -166,7 +166,7 @@ #define CONTROL_TIMEOUT_JIFFIES ((CONTROL_TIMEOUT_MS * HZ)/1000) // between wakeups -#define UNLINK_TIMEOUT_JIFFIES ((3 /*ms*/ * HZ)/1000) +#define UNLINK_TIMEOUT_MS 3 /*-------------------------------------------------------------------------*/ @@ -268,7 +268,7 @@ /* use ethtool to change the level for any given device */ static int msg_level = 1; -MODULE_PARM (msg_level, "i"); +module_param (msg_level, int, 0); MODULE_PARM_DESC (msg_level, "Initial message level (default = 1)"); @@ -2591,8 +2591,7 @@ while (skb_queue_len (&dev->rxq) && skb_queue_len (&dev->txq) && skb_queue_len (&dev->done)) { - set_current_state (TASK_UNINTERRUPTIBLE); - schedule_timeout (UNLINK_TIMEOUT_JIFFIES); + msleep(UNLINK_TIMEOUT_MS); devdbg (dev, "waited for %d urb completions", temp); } dev->wait = NULL; diff -Nru a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c --- a/drivers/usb/serial/cyberjack.c 2004-08-04 17:58:04 -07:00 +++ b/drivers/usb/serial/cyberjack.c 2004-08-04 17:58:04 -07:00 @@ -44,7 +44,7 @@ /* * Version Information */ -#define DRIVER_VERSION "v1.0" +#define DRIVER_VERSION "v1.01" #define DRIVER_AUTHOR "Matthias Bruestle" #define DRIVER_DESC "REINER SCT cyberJack pinpad/e-com USB Chipcard Reader Driver" @@ -111,6 +111,7 @@ static int cyberjack_startup (struct usb_serial *serial) { struct cyberjack_private *priv; + int i; dbg("%s", __FUNCTION__); @@ -128,6 +129,16 @@ init_waitqueue_head(&serial->port[0]->write_wait); + for (i = 0; i < serial->num_ports; ++i) { + int result; + serial->port[i]->interrupt_in_urb->dev = serial->dev; + result = usb_submit_urb(serial->port[i]->interrupt_in_urb, + GFP_KERNEL); + if (result) + err(" usb_submit_urb(read int) failed"); + dbg("%s - usb_submit_urb(int urb)", __FUNCTION__); + } + return( 0 ); } @@ -138,6 +149,7 @@ dbg("%s", __FUNCTION__); for (i=0; i < serial->num_ports; ++i) { + usb_unlink_urb (serial->port[i]->interrupt_in_urb); /* My special items, the standard routines free my urbs */ kfree(usb_get_serial_port_data(serial->port[i])); usb_set_serial_port_data(serial->port[i], NULL); @@ -168,17 +180,6 @@ priv->wrsent = 0; spin_unlock_irqrestore(&priv->lock, flags); - /* shutdown any bulk reads that might be going on */ - usb_unlink_urb (port->write_urb); - usb_unlink_urb (port->read_urb); - usb_unlink_urb (port->interrupt_in_urb); - - port->interrupt_in_urb->dev = port->serial->dev; - result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); - if (result) - err(" usb_submit_urb(read int) failed"); - dbg("%s - usb_submit_urb(int urb)", __FUNCTION__); - return result; } @@ -190,11 +191,6 @@ /* shutdown any bulk reads that might be going on */ usb_unlink_urb (port->write_urb); usb_unlink_urb (port->read_urb); - usb_unlink_urb (port->interrupt_in_urb); - dbg("%s - usb_clear_halt", __FUNCTION__ ); - usb_clear_halt(port->serial->dev, port->write_urb->pipe); - usb_clear_halt(port->serial->dev, port->read_urb->pipe); - usb_clear_halt(port->serial->dev, port->interrupt_in_urb->pipe); } } @@ -376,6 +372,10 @@ } tty = port->tty; + if (!tty) { + dbg("%s - ignoring since device not open\n", __FUNCTION__); + return; + } if (urb->actual_length) { for (i = 0; i < urb->actual_length ; ++i) { /* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */ diff -Nru a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c --- a/drivers/usb/serial/ftdi_sio.c 2004-08-04 17:58:04 -07:00 +++ b/drivers/usb/serial/ftdi_sio.c 2004-08-04 17:58:04 -07:00 @@ -17,6 +17,11 @@ * See http://ftdi-usb-sio.sourceforge.net for upto date testing info * and extra documentation * + * (21/Jul/2004) Ian Abbott + * Incorporated Steven Turner's code to add support for the FT2232C chip. + * The prelimilary port to the 2.6 kernel was by Rus V. Brushkoff. I have + * fixed a couple of things. + * * (27/May/2004) Ian Abbott * Improved throttling code, mostly stolen from the WhiteHEAT driver. * @@ -259,7 +264,7 @@ /* * Version Information */ -#define DRIVER_VERSION "v1.4.0" +#define DRIVER_VERSION "v1.4.1" #define DRIVER_AUTHOR "Greg Kroah-Hartman , Bill Ryder , Kuba Ober " #define DRIVER_DESC "USB FTDI Serial Converters Driver" @@ -489,11 +494,18 @@ }; +static struct usb_device_id id_table_FT2232C[] = { + { USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) }, + { } /* Terminating entry */ +}; + + static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_IRTRANS_PID) }, { USB_DEVICE(FTDI_VID, FTDI_SIO_PID) }, { USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) }, { USB_DEVICE(FTDI_VID, FTDI_8U232AM_ALT_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) }, { USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) }, { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) }, { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) }, @@ -621,6 +633,8 @@ __u8 rx_flags; /* receive state flags (throttling) */ spinlock_t rx_lock; /* spinlock for receive state */ + __u16 interface; /* FT2232C port interface (0 for FT232/245) */ + int force_baud; /* if non-zero, force the baud rate to this value */ int force_rtscts; /* if non-zero, force RTS-CTS to always be enabled */ }; @@ -637,6 +651,7 @@ static int ftdi_SIO_startup (struct usb_serial *serial); static int ftdi_8U232AM_startup (struct usb_serial *serial); static int ftdi_FT232BM_startup (struct usb_serial *serial); +static int ftdi_FT2232C_startup (struct usb_serial *serial); static int ftdi_USB_UIRT_startup (struct usb_serial *serial); static int ftdi_HE_TIRA1_startup (struct usb_serial *serial); static void ftdi_shutdown (struct usb_serial *serial); @@ -739,6 +754,32 @@ .shutdown = ftdi_shutdown, }; +static struct usb_serial_device_type ftdi_FT2232C_device = { + .owner = THIS_MODULE, + .name = "FTDI FT2232C Compatible", + .id_table = id_table_FT2232C, + .num_interrupt_in = 0, + .num_bulk_in = 1, + .num_bulk_out = 1, + .num_ports = 1, + .open = ftdi_open, + .close = ftdi_close, + .throttle = ftdi_throttle, + .unthrottle = ftdi_unthrottle, + .write = ftdi_write, + .write_room = ftdi_write_room, + .chars_in_buffer = ftdi_chars_in_buffer, + .read_bulk_callback = ftdi_read_bulk_callback, + .write_bulk_callback = ftdi_write_bulk_callback, + .tiocmget = ftdi_tiocmget, + .tiocmset = ftdi_tiocmset, + .ioctl = ftdi_ioctl, + .set_termios = ftdi_set_termios, + .break_ctl = ftdi_break_ctl, + .attach = ftdi_FT2232C_startup, + .shutdown = ftdi_shutdown, +}; + static struct usb_serial_device_type ftdi_USB_UIRT_device = { .owner = THIS_MODULE, .name = "USB-UIRT Infrared Tranceiver", @@ -866,7 +907,7 @@ usb_sndctrlpipe(port->serial->dev, 0), FTDI_SIO_SET_MODEM_CTRL_REQUEST, FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE, - ftdi_high_or_low, 0, + ftdi_high_or_low, priv->interface, buf, 0, WDR_TIMEOUT); kfree(buf); @@ -896,7 +937,7 @@ usb_sndctrlpipe(port->serial->dev, 0), FTDI_SIO_SET_MODEM_CTRL_REQUEST, FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE, - ftdi_high_or_low, 0, + ftdi_high_or_low, priv->interface, buf, 0, WDR_TIMEOUT); kfree(buf); @@ -909,6 +950,7 @@ static int change_speed(struct usb_serial_port *port) { + struct ftdi_private *priv = usb_get_serial_port_data(port); char *buf; __u16 urb_value; __u16 urb_index; @@ -922,6 +964,9 @@ urb_index_value = get_ftdi_divisor(port); urb_value = (__u16)urb_index_value; urb_index = (__u16)(urb_index_value >> 16); + if (priv->interface) { /* FT2232C */ + urb_index = (__u16)((urb_index << 8) | priv->interface); + } rv = usb_control_msg(port->serial->dev, usb_sndctrlpipe(port->serial->dev, 0), @@ -1015,7 +1060,12 @@ } break; case FT232BM: /* FT232BM chip */ - chip_name = "FT232BM"; + case FT2232C: /* FT2232C chip */ + if (priv->chip_type == FT2232C) { + chip_name = "FT2232C"; + } else { + chip_name = "FT232BM"; + } if (baud <= 3000000) { div_value = ftdi_232bm_baud_to_divisor(baud); } else { @@ -1231,6 +1281,35 @@ return (0); } /* ftdi_FT232BM_startup */ +/* Startup for the FT2232C chip */ +/* Called from usbserial:serial_probe */ +static int ftdi_FT2232C_startup (struct usb_serial *serial) +{ /* ftdi_FT2232C_startup */ + struct ftdi_private *priv; + int err; + int inter; + + dbg("%s",__FUNCTION__); + err = ftdi_common_startup(serial); + if (err){ + return (err); + } + + priv = usb_get_serial_port_data(serial->port[0]); + priv->chip_type = FT2232C; + inter = serial->interface->altsetting->desc.bInterfaceNumber; + + if (inter) { + priv->interface = INTERFACE_B; + } + else { + priv->interface = INTERFACE_A; + } + priv->baud_base = 48000000 / 2; /* Would be / 16, but FT2232C supports multiple of 0.125 divisor fractions! */ + + return (0); +} /* ftdi_FT2232C_startup */ + /* Startup for the USB-UIRT device, which requires hardwired baudrate (38400 gets mapped to 312500) */ /* Called from usbserial:serial_probe */ static int ftdi_USB_UIRT_startup (struct usb_serial *serial) @@ -1323,7 +1402,7 @@ usb_control_msg(dev, usb_sndctrlpipe(dev, 0), FTDI_SIO_RESET_REQUEST, FTDI_SIO_RESET_REQUEST_TYPE, FTDI_SIO_RESET_SIO, - 0, buf, 0, WDR_TIMEOUT); + priv->interface, buf, 0, WDR_TIMEOUT); /* Termios defaults are set by usb_serial_init. We don't change port->tty->termios - this would loose speed settings, etc. @@ -1373,6 +1452,7 @@ static void ftdi_close (struct usb_serial_port *port, struct file *filp) { /* ftdi_close */ unsigned int c_cflag = port->tty->termios->c_cflag; + struct ftdi_private *priv = usb_get_serial_port_data(port); char buf[1]; dbg("%s", __FUNCTION__); @@ -1383,7 +1463,8 @@ usb_sndctrlpipe(port->serial->dev, 0), FTDI_SIO_SET_FLOW_CTRL_REQUEST, FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, - 0, 0, buf, 0, WDR_TIMEOUT) < 0) { + 0, priv->interface, buf, 0, + WDR_TIMEOUT) < 0) { err("error from flowcontrol urb"); } @@ -1796,7 +1877,7 @@ if (usb_control_msg(port->serial->dev, usb_sndctrlpipe(port->serial->dev, 0), FTDI_SIO_SET_DATA_REQUEST, FTDI_SIO_SET_DATA_REQUEST_TYPE, - urb_value , 0, + urb_value , priv->interface, buf, 0, WDR_TIMEOUT) < 0) { err("%s FAILED to enable/disable break state (state was %d)", __FUNCTION__,break_state); } @@ -1875,7 +1956,7 @@ if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), FTDI_SIO_SET_DATA_REQUEST, FTDI_SIO_SET_DATA_REQUEST_TYPE, - urb_value , 0, + urb_value , priv->interface, buf, 0, 100) < 0) { err("%s FAILED to set databits/stopbits/parity", __FUNCTION__); } @@ -1886,7 +1967,7 @@ if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), FTDI_SIO_SET_FLOW_CTRL_REQUEST, FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, - 0, 0, + 0, priv->interface, buf, 0, WDR_TIMEOUT) < 0) { err("%s error from disable flowcontrol urb", __FUNCTION__); } @@ -1903,6 +1984,13 @@ if (change_speed(port)) { err("%s urb failed to set baurdrate", __FUNCTION__); } + /* Ensure RTS and DTR are raised */ + else if (set_dtr(port, HIGH) < 0){ + err("%s Error from DTR HIGH urb", __FUNCTION__); + } + else if (set_rts(port, HIGH) < 0){ + err("%s Error from RTS HIGH urb", __FUNCTION__); + } } /* Set flow control */ @@ -1913,7 +2001,7 @@ usb_sndctrlpipe(dev, 0), FTDI_SIO_SET_FLOW_CTRL_REQUEST, FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, - 0 , FTDI_SIO_RTS_CTS_HS, + 0 , (FTDI_SIO_RTS_CTS_HS | priv->interface), buf, 0, WDR_TIMEOUT) < 0) { err("urb failed to set to rts/cts flow control"); } @@ -1939,7 +2027,8 @@ usb_sndctrlpipe(dev, 0), FTDI_SIO_SET_FLOW_CTRL_REQUEST, FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, - urb_value , FTDI_SIO_XON_XOFF_HS, + urb_value , (FTDI_SIO_XON_XOFF_HS + | priv->interface), buf, 0, WDR_TIMEOUT) < 0) { err("urb failed to set to xon/xoff flow control"); } @@ -1951,7 +2040,7 @@ usb_sndctrlpipe(dev, 0), FTDI_SIO_SET_FLOW_CTRL_REQUEST, FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, - 0, 0, + 0, priv->interface, buf, 0, WDR_TIMEOUT) < 0) { err("urb failed to clear flow control"); } @@ -1985,13 +2074,14 @@ break; case FT8U232AM: case FT232BM: + case FT2232C: /* the 8U232AM returns a two byte value (the sio is a 1 byte value) - in the same format as the data returned from the in point */ if ((ret = usb_control_msg(port->serial->dev, usb_rcvctrlpipe(port->serial->dev, 0), FTDI_SIO_GET_MODEM_STATUS_REQUEST, FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE, - 0, 0, + 0, priv->interface, buf, 2, WDR_TIMEOUT)) < 0 ) { err("%s Could not get modem status of device - err: %d", __FUNCTION__, ret); @@ -2206,6 +2296,9 @@ retval = usb_serial_register(&ftdi_FT232BM_device); if (retval) goto failed_FT232BM_register; + retval = usb_serial_register(&ftdi_FT2232C_device); + if (retval) + goto failed_FT2232C_register; retval = usb_serial_register(&ftdi_USB_UIRT_device); if (retval) goto failed_USB_UIRT_register; @@ -2223,6 +2316,8 @@ failed_HE_TIRA1_register: usb_serial_deregister(&ftdi_USB_UIRT_device); failed_USB_UIRT_register: + usb_serial_deregister(&ftdi_FT2232C_device); +failed_FT2232C_register: usb_serial_deregister(&ftdi_FT232BM_device); failed_FT232BM_register: usb_serial_deregister(&ftdi_8U232AM_device); @@ -2241,6 +2336,7 @@ usb_deregister (&ftdi_driver); usb_serial_deregister (&ftdi_HE_TIRA1_device); usb_serial_deregister (&ftdi_USB_UIRT_device); + usb_serial_deregister (&ftdi_FT2232C_device); usb_serial_deregister (&ftdi_FT232BM_device); usb_serial_deregister (&ftdi_8U232AM_device); usb_serial_deregister (&ftdi_SIO_device); diff -Nru a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h --- a/drivers/usb/serial/ftdi_sio.h 2004-08-04 17:58:04 -07:00 +++ b/drivers/usb/serial/ftdi_sio.h 2004-08-04 17:58:04 -07:00 @@ -26,6 +26,7 @@ #define FTDI_SIO_PID 0x8372 /* Product Id SIO application of 8U100AX */ #define FTDI_8U232AM_PID 0x6001 /* Similar device to SIO above */ #define FTDI_8U232AM_ALT_PID 0x6006 /* FTDI's alternate PID for above */ +#define FTDI_8U2232C_PID 0x6010 /* Dual channel device */ #define FTDI_RELAIS_PID 0xFA10 /* Relais device from Rudolf Gugler */ #define FTDI_NF_RIC_VID 0x0DCD /* Vendor Id */ #define FTDI_NF_RIC_PID 0x0001 /* Product Id */ @@ -234,6 +235,21 @@ #define FTDI_SIO_SET_EVENT_CHAR 6 /* Set the event character */ #define FTDI_SIO_SET_ERROR_CHAR 7 /* Set the error character */ +/* Port interface code for FT2232C */ +#define INTERFACE_A 1 +#define INTERFACE_B 2 + + +/* + * BmRequestType: 1100 0000b + * bRequest: FTDI_E2_READ + * wValue: 0 + * wIndex: Address of word to read + * wLength: 2 + * Data: Will return a word of data from E2Address + * + */ + /* Port Identifier Table */ #define PIT_DEFAULT 0 /* SIOA */ #define PIT_SIOA 1 /* SIOA */ @@ -333,6 +349,7 @@ SIO = 1, FT8U232AM = 2, FT232BM = 3, + FT2232C = 4, } ftdi_chip_type_t; typedef enum { diff -Nru a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c --- a/drivers/usb/serial/ipaq.c 2004-08-04 17:58:04 -07:00 +++ b/drivers/usb/serial/ipaq.c 2004-08-04 17:58:04 -07:00 @@ -188,6 +188,7 @@ usb_set_serial_port_data(port, priv); priv->active = 0; priv->queue_len = 0; + priv->free_len = 0; INIT_LIST_HEAD(&priv->queue); INIT_LIST_HEAD(&priv->freelist); diff -Nru a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c --- a/drivers/usb/serial/pl2303.c 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/serial/pl2303.c 2004-08-04 17:58:03 -07:00 @@ -659,7 +659,7 @@ state = BREAK_OFF; else state = BREAK_ON; - dbg("%s - turning break %s", state==BREAK_OFF ? "off" : "on", __FUNCTION__); + dbg("%s - turning break %s", __FUNCTION__, state==BREAK_OFF ? "off" : "on"); result = usb_control_msg (serial->dev, usb_sndctrlpipe (serial->dev, 0), BREAK_REQUEST, BREAK_REQUEST_TYPE, state, diff -Nru a/drivers/usb/storage/datafab.c b/drivers/usb/storage/datafab.c --- a/drivers/usb/storage/datafab.c 2004-08-04 17:58:04 -07:00 +++ b/drivers/usb/storage/datafab.c 2004-08-04 17:58:04 -07:00 @@ -50,16 +50,19 @@ * in that routine. */ +#include +#include +#include + +#include +#include + #include "transport.h" #include "protocol.h" #include "usb.h" #include "debug.h" #include "datafab.h" -#include -#include -#include - static int datafab_determine_lun(struct us_data *us, struct datafab_info *info); @@ -388,7 +391,7 @@ static int datafab_handle_mode_sense(struct us_data *us, - Scsi_Cmnd * srb, + struct scsi_cmnd * srb, int sense_6) { static unsigned char rw_err_page[12] = { @@ -498,7 +501,7 @@ // Transport for the Datafab MDCFE-B // -int datafab_transport(Scsi_Cmnd * srb, struct us_data *us) +int datafab_transport(struct scsi_cmnd * srb, struct us_data *us) { struct datafab_info *info; int rc; @@ -625,12 +628,12 @@ if (srb->cmnd[0] == MODE_SENSE) { US_DEBUGP("datafab_transport: MODE_SENSE_6 detected\n"); - return datafab_handle_mode_sense(us, srb, TRUE); + return datafab_handle_mode_sense(us, srb, 1); } if (srb->cmnd[0] == MODE_SENSE_10) { US_DEBUGP("datafab_transport: MODE_SENSE_10 detected\n"); - return datafab_handle_mode_sense(us, srb, FALSE); + return datafab_handle_mode_sense(us, srb, 0); } if (srb->cmnd[0] == ALLOW_MEDIUM_REMOVAL) { diff -Nru a/drivers/usb/storage/datafab.h b/drivers/usb/storage/datafab.h --- a/drivers/usb/storage/datafab.h 2004-08-04 17:58:04 -07:00 +++ b/drivers/usb/storage/datafab.h 2004-08-04 17:58:04 -07:00 @@ -24,7 +24,7 @@ #ifndef _USB_DATAFAB_MDCFE_B_H #define _USB_DATAFAB_MDCFE_B_H -extern int datafab_transport(Scsi_Cmnd *srb, struct us_data *us); +extern int datafab_transport(struct scsi_cmnd *srb, struct us_data *us); struct datafab_info { unsigned long sectors; // total sector count diff -Nru a/drivers/usb/storage/debug.c b/drivers/usb/storage/debug.c --- a/drivers/usb/storage/debug.c 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/storage/debug.c 2004-08-04 17:58:03 -07:00 @@ -44,9 +44,15 @@ * 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include +#include +#include + #include "debug.h" +#include "scsi.h" + -void usb_stor_show_command(Scsi_Cmnd *srb) +void usb_stor_show_command(struct scsi_cmnd *srb) { char *what = NULL; int i; diff -Nru a/drivers/usb/storage/debug.h b/drivers/usb/storage/debug.h --- a/drivers/usb/storage/debug.h 2004-08-04 17:58:04 -07:00 +++ b/drivers/usb/storage/debug.h 2004-08-04 17:58:04 -07:00 @@ -46,13 +46,13 @@ #include #include -#include -#include "usb.h" + +struct scsi_cmnd; #define USB_STORAGE "usb-storage: " #ifdef CONFIG_USB_STORAGE_DEBUG -void usb_stor_show_command(Scsi_Cmnd *srb); +void usb_stor_show_command(struct scsi_cmnd *srb); void usb_stor_show_sense( unsigned char key, unsigned char asc, unsigned char ascq ); #define US_DEBUGP(x...) printk( KERN_DEBUG USB_STORAGE x ) diff -Nru a/drivers/usb/storage/dpcm.c b/drivers/usb/storage/dpcm.c --- a/drivers/usb/storage/dpcm.c 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/storage/dpcm.c 2004-08-04 17:58:03 -07:00 @@ -30,6 +30,10 @@ */ #include +#include +#include +#include + #include "transport.h" #include "protocol.h" #include "usb.h" @@ -41,7 +45,7 @@ * Transport for the Microtech DPCM-USB * */ -int dpcm_transport(Scsi_Cmnd *srb, struct us_data *us) +int dpcm_transport(struct scsi_cmnd *srb, struct us_data *us) { int ret; diff -Nru a/drivers/usb/storage/dpcm.h b/drivers/usb/storage/dpcm.h --- a/drivers/usb/storage/dpcm.h 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/storage/dpcm.h 2004-08-04 17:58:03 -07:00 @@ -29,6 +29,6 @@ #ifndef _MICROTECH_DPCM_USB_H #define _MICROTECH_DPCM_USB_H -extern int dpcm_transport(Scsi_Cmnd *srb, struct us_data *us); +extern int dpcm_transport(struct scsi_cmnd *srb, struct us_data *us); #endif diff -Nru a/drivers/usb/storage/freecom.c b/drivers/usb/storage/freecom.c --- a/drivers/usb/storage/freecom.c 2004-08-04 17:58:04 -07:00 +++ b/drivers/usb/storage/freecom.c 2004-08-04 17:58:04 -07:00 @@ -29,12 +29,16 @@ */ #include +#include + +#include +#include + #include "transport.h" #include "protocol.h" #include "usb.h" #include "debug.h" #include "freecom.h" -#include "linux/hdreg.h" #ifdef CONFIG_USB_STORAGE_DEBUG static void pdump (void *, int); @@ -105,7 +109,7 @@ #define FCM_STATUS_PACKET_LENGTH 4 static int -freecom_readdata (Scsi_Cmnd *srb, struct us_data *us, +freecom_readdata (struct scsi_cmnd *srb, struct us_data *us, unsigned int ipipe, unsigned int opipe, int count) { struct freecom_xfer_wrap *fxfr = @@ -139,7 +143,7 @@ } static int -freecom_writedata (Scsi_Cmnd *srb, struct us_data *us, +freecom_writedata (struct scsi_cmnd *srb, struct us_data *us, int unsigned ipipe, unsigned int opipe, int count) { struct freecom_xfer_wrap *fxfr = @@ -176,7 +180,7 @@ * Transport for the Freecom USB/IDE adaptor. * */ -int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) +int freecom_transport(struct scsi_cmnd *srb, struct us_data *us) { struct freecom_cb_wrap *fcb; struct freecom_status *fst; @@ -302,7 +306,7 @@ * move in. */ switch (us->srb->sc_data_direction) { - case SCSI_DATA_READ: + case DMA_FROM_DEVICE: /* catch bogus "read 0 length" case */ if (!length) break; @@ -334,7 +338,7 @@ US_DEBUGP("Transfer happy\n"); break; - case SCSI_DATA_WRITE: + case DMA_TO_DEVICE: /* catch bogus "write 0 length" case */ if (!length) break; @@ -364,7 +368,7 @@ break; - case SCSI_DATA_NONE: + case DMA_NONE: /* Easy, do nothing. */ break; diff -Nru a/drivers/usb/storage/freecom.h b/drivers/usb/storage/freecom.h --- a/drivers/usb/storage/freecom.h 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/storage/freecom.h 2004-08-04 17:58:03 -07:00 @@ -29,7 +29,7 @@ #ifndef _FREECOM_USB_H #define _FREECOM_USB_H -extern int freecom_transport(Scsi_Cmnd *srb, struct us_data *us); +extern int freecom_transport(struct scsi_cmnd *srb, struct us_data *us); extern int usb_stor_freecom_reset(struct us_data *us); extern int freecom_init (struct us_data *us); diff -Nru a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c --- a/drivers/usb/storage/isd200.c 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/storage/isd200.c 2004-08-04 17:58:03 -07:00 @@ -44,6 +44,16 @@ /* Include files */ +#include +#include +#include +#include +#include + +#include +#include +#include + #include "transport.h" #include "protocol.h" #include "usb.h" @@ -51,11 +61,6 @@ #include "scsiglue.h" #include "isd200.h" -#include -#include -#include -#include -#include /* Timeout defines (in Seconds) */ @@ -349,7 +354,7 @@ * RETURNS: * void */ -static void isd200_build_sense(struct us_data *us, Scsi_Cmnd *srb) +static void isd200_build_sense(struct us_data *us, struct scsi_cmnd *srb) { struct isd200_info *info = (struct isd200_info *)us->extra; struct sense_data *buf = (struct sense_data *) &srb->sense_buffer[0]; @@ -427,7 +432,7 @@ ata.generic.RegisterSelect = REG_CYLINDER_LOW | REG_CYLINDER_HIGH | REG_STATUS | REG_ERROR; - srb->sc_data_direction = SCSI_DATA_READ; + srb->sc_data_direction = DMA_FROM_DEVICE; srb->request_buffer = pointer; srb->request_bufflen = value; break; @@ -439,7 +444,7 @@ ACTION_SELECT_5; ata.generic.RegisterSelect = REG_DEVICE_HEAD; ata.write.DeviceHeadByte = value; - srb->sc_data_direction = SCSI_DATA_NONE; + srb->sc_data_direction = DMA_NONE; break; case ACTION_RESET: @@ -448,7 +453,7 @@ ACTION_SELECT_3|ACTION_SELECT_4; ata.generic.RegisterSelect = REG_DEVICE_CONTROL; ata.write.DeviceControlByte = ATA_DC_RESET_CONTROLLER; - srb->sc_data_direction = SCSI_DATA_NONE; + srb->sc_data_direction = DMA_NONE; break; case ACTION_REENABLE: @@ -457,7 +462,7 @@ ACTION_SELECT_3|ACTION_SELECT_4; ata.generic.RegisterSelect = REG_DEVICE_CONTROL; ata.write.DeviceControlByte = ATA_DC_REENABLE_CONTROLLER; - srb->sc_data_direction = SCSI_DATA_NONE; + srb->sc_data_direction = DMA_NONE; break; case ACTION_SOFT_RESET: @@ -466,14 +471,14 @@ ata.generic.RegisterSelect = REG_DEVICE_HEAD | REG_COMMAND; ata.write.DeviceHeadByte = info->DeviceHead; ata.write.CommandByte = WIN_SRST; - srb->sc_data_direction = SCSI_DATA_NONE; + srb->sc_data_direction = DMA_NONE; break; case ACTION_IDENTIFY: US_DEBUGP(" isd200_action(IDENTIFY)\n"); ata.generic.RegisterSelect = REG_COMMAND; ata.write.CommandByte = WIN_IDENTIFY; - srb->sc_data_direction = SCSI_DATA_READ; + srb->sc_data_direction = DMA_FROM_DEVICE; srb->request_buffer = (void *) info->id; srb->request_bufflen = sizeof(struct hd_driveid); break; @@ -535,7 +540,7 @@ * the device and receive the response. */ static void isd200_invoke_transport( struct us_data *us, - Scsi_Cmnd *srb, + struct scsi_cmnd *srb, union ata_cdb *ataCdb ) { int need_auto_sense = 0; @@ -839,7 +844,7 @@ unsigned long endTime; struct isd200_info *info = (struct isd200_info *)us->extra; unsigned char *regs = info->RegsBuf; - int recheckAsMaster = FALSE; + int recheckAsMaster = 0; if ( detect ) endTime = jiffies + ISD200_ENUM_DETECT_TIMEOUT * HZ; @@ -847,7 +852,7 @@ endTime = jiffies + ISD200_ENUM_BSY_TIMEOUT * HZ; /* loop until we detect !BSY or timeout */ - while(TRUE) { + while(1) { #ifdef CONFIG_USB_STORAGE_DEBUG char* mstr = master_slave == ATA_ADDRESS_DEVHEAD_STD ? "Master" : "Slave"; @@ -899,9 +904,9 @@ itself okay as a master also */ if ((master_slave & ATA_ADDRESS_DEVHEAD_SLAVE) && - (recheckAsMaster == FALSE)) { + !recheckAsMaster) { US_DEBUGP(" Identified ATAPI device as slave. Rechecking again as master\n"); - recheckAsMaster = TRUE; + recheckAsMaster = 1; master_slave = ATA_ADDRESS_DEVHEAD_STD; } else { US_DEBUGP(" Identified ATAPI device\n"); @@ -948,15 +953,15 @@ if (retStatus == ISD200_GOOD) { int isslave; /* master or slave? */ - retStatus = isd200_try_enum( us, ATA_ADDRESS_DEVHEAD_STD, FALSE ); + retStatus = isd200_try_enum( us, ATA_ADDRESS_DEVHEAD_STD, 0); if (retStatus == ISD200_GOOD) - retStatus = isd200_try_enum( us, ATA_ADDRESS_DEVHEAD_SLAVE, FALSE ); + retStatus = isd200_try_enum( us, ATA_ADDRESS_DEVHEAD_SLAVE, 0); if (retStatus == ISD200_GOOD) { retStatus = isd200_srst(us); if (retStatus == ISD200_GOOD) /* ata or atapi? */ - retStatus = isd200_try_enum( us, ATA_ADDRESS_DEVHEAD_STD, TRUE ); + retStatus = isd200_try_enum( us, ATA_ADDRESS_DEVHEAD_STD, 1); } isslave = (info->DeviceHead & ATA_ADDRESS_DEVHEAD_SLAVE) ? 1 : 0; @@ -1121,15 +1126,15 @@ * Translate SCSI commands to ATA commands. * * RETURNS: - * TRUE if the command needs to be sent to the transport layer - * FALSE otherwise + * 1 if the command needs to be sent to the transport layer + * 0 otherwise */ -static int isd200_scsi_to_ata(Scsi_Cmnd *srb, struct us_data *us, +static int isd200_scsi_to_ata(struct scsi_cmnd *srb, struct us_data *us, union ata_cdb * ataCdb) { struct isd200_info *info = (struct isd200_info *)us->extra; struct hd_driveid *id = info->id; - int sendToTransport = TRUE; + int sendToTransport = 1; unsigned char sectnum, head; unsigned short cylinder; unsigned long lba; @@ -1147,7 +1152,7 @@ usb_stor_set_xfer_buf((unsigned char *) &info->InquiryData, sizeof(info->InquiryData), srb); srb->result = SAM_STAT_GOOD; - sendToTransport = FALSE; + sendToTransport = 0; break; case MODE_SENSE: @@ -1167,7 +1172,7 @@ } else { US_DEBUGP(" Media Status not supported, just report okay\n"); srb->result = SAM_STAT_GOOD; - sendToTransport = FALSE; + sendToTransport = 0; } break; @@ -1185,7 +1190,7 @@ } else { US_DEBUGP(" Media Status not supported, just report okay\n"); srb->result = SAM_STAT_GOOD; - sendToTransport = FALSE; + sendToTransport = 0; } break; @@ -1209,7 +1214,7 @@ usb_stor_set_xfer_buf((unsigned char *) &readCapacityData, sizeof(readCapacityData), srb); srb->result = SAM_STAT_GOOD; - sendToTransport = FALSE; + sendToTransport = 0; } break; @@ -1293,7 +1298,7 @@ } else { US_DEBUGP(" Not removeable media, just report okay\n"); srb->result = SAM_STAT_GOOD; - sendToTransport = FALSE; + sendToTransport = 0; } break; @@ -1319,14 +1324,14 @@ } else { US_DEBUGP(" Nothing to do, just report okay\n"); srb->result = SAM_STAT_GOOD; - sendToTransport = FALSE; + sendToTransport = 0; } break; default: US_DEBUGP("Unsupported SCSI command - 0x%X\n", srb->cmnd[0]); srb->result = DID_ERROR << 16; - sendToTransport = FALSE; + sendToTransport = 0; break; } @@ -1424,9 +1429,9 @@ * */ -void isd200_ata_command(Scsi_Cmnd *srb, struct us_data *us) +void isd200_ata_command(struct scsi_cmnd *srb, struct us_data *us) { - int sendToTransport = TRUE; + int sendToTransport = 1; union ata_cdb ataCdb; /* Make sure driver was initialized */ diff -Nru a/drivers/usb/storage/isd200.h b/drivers/usb/storage/isd200.h --- a/drivers/usb/storage/isd200.h 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/storage/isd200.h 2004-08-04 17:58:03 -07:00 @@ -25,7 +25,7 @@ #ifndef _USB_ISD200_H #define _USB_ISD200_H -extern void isd200_ata_command(Scsi_Cmnd *srb, struct us_data *us); +extern void isd200_ata_command(struct scsi_cmnd *srb, struct us_data *us); extern int isd200_Initialization(struct us_data *us); #endif diff -Nru a/drivers/usb/storage/jumpshot.c b/drivers/usb/storage/jumpshot.c --- a/drivers/usb/storage/jumpshot.c 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/storage/jumpshot.c 2004-08-04 17:58:03 -07:00 @@ -47,15 +47,19 @@ * in that routine. */ +#include +#include +#include + +#include +#include + #include "transport.h" #include "protocol.h" #include "usb.h" #include "debug.h" #include "jumpshot.h" -#include -#include -#include static inline int jumpshot_bulk_read(struct us_data *us, unsigned char *data, @@ -319,7 +323,7 @@ } static int jumpshot_handle_mode_sense(struct us_data *us, - Scsi_Cmnd * srb, + struct scsi_cmnd * srb, int sense_6) { static unsigned char rw_err_page[12] = { @@ -426,7 +430,7 @@ // Transport for the Lexar 'Jumpshot' // -int jumpshot_transport(Scsi_Cmnd * srb, struct us_data *us) +int jumpshot_transport(struct scsi_cmnd * srb, struct us_data *us) { struct jumpshot_info *info; int rc; @@ -551,12 +555,12 @@ if (srb->cmnd[0] == MODE_SENSE) { US_DEBUGP("jumpshot_transport: MODE_SENSE_6 detected\n"); - return jumpshot_handle_mode_sense(us, srb, TRUE); + return jumpshot_handle_mode_sense(us, srb, 1); } if (srb->cmnd[0] == MODE_SENSE_10) { US_DEBUGP("jumpshot_transport: MODE_SENSE_10 detected\n"); - return jumpshot_handle_mode_sense(us, srb, FALSE); + return jumpshot_handle_mode_sense(us, srb, 0); } if (srb->cmnd[0] == ALLOW_MEDIUM_REMOVAL) { diff -Nru a/drivers/usb/storage/jumpshot.h b/drivers/usb/storage/jumpshot.h --- a/drivers/usb/storage/jumpshot.h 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/storage/jumpshot.h 2004-08-04 17:58:03 -07:00 @@ -24,7 +24,7 @@ #ifndef _USB_JUMPSHOT_H #define _USB_JUMPSHOT_H -extern int jumpshot_transport(Scsi_Cmnd *srb, struct us_data *us); +extern int jumpshot_transport(struct scsi_cmnd *srb, struct us_data *us); struct jumpshot_info { unsigned long sectors; // total sector count diff -Nru a/drivers/usb/storage/protocol.c b/drivers/usb/storage/protocol.c --- a/drivers/usb/storage/protocol.c 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/storage/protocol.c 2004-08-04 17:58:03 -07:00 @@ -45,6 +45,8 @@ */ #include +#include +#include #include "protocol.h" #include "usb.h" #include "debug.h" @@ -59,7 +61,7 @@ * Fix-up the return data from an INQUIRY command to show * ANSI SCSI rev 2 so we don't confuse the SCSI layers above us */ -static void fix_inquiry_data(Scsi_Cmnd *srb) +static void fix_inquiry_data(struct scsi_cmnd *srb) { unsigned char databuf[3]; unsigned int index, offset; @@ -91,7 +93,7 @@ * Fix-up the return data from a READ CAPACITY command. My Feiya reader * returns a value that is 1 too large. */ -static void fix_read_capacity(Scsi_Cmnd *srb) +static void fix_read_capacity(struct scsi_cmnd *srb) { unsigned int index, offset; u32 c; @@ -120,11 +122,11 @@ * Protocol routines ***********************************************************************/ -void usb_stor_qic157_command(Scsi_Cmnd *srb, struct us_data *us) +void usb_stor_qic157_command(struct scsi_cmnd *srb, struct us_data *us) { /* Pad the ATAPI command with zeros * - * NOTE: This only works because a Scsi_Cmnd struct field contains + * NOTE: This only works because a scsi_cmnd struct field contains * a unsigned char cmnd[16], so we know we have storage available */ for (; srb->cmd_len<12; srb->cmd_len++) @@ -141,11 +143,11 @@ } } -void usb_stor_ATAPI_command(Scsi_Cmnd *srb, struct us_data *us) +void usb_stor_ATAPI_command(struct scsi_cmnd *srb, struct us_data *us) { /* Pad the ATAPI command with zeros * - * NOTE: This only works because a Scsi_Cmnd struct field contains + * NOTE: This only works because a scsi_cmnd struct field contains * a unsigned char cmnd[16], so we know we have storage available */ @@ -166,12 +168,12 @@ } -void usb_stor_ufi_command(Scsi_Cmnd *srb, struct us_data *us) +void usb_stor_ufi_command(struct scsi_cmnd *srb, struct us_data *us) { /* fix some commands -- this is a form of mode translation * UFI devices only accept 12 byte long commands * - * NOTE: This only works because a Scsi_Cmnd struct field contains + * NOTE: This only works because a scsi_cmnd struct field contains * a unsigned char cmnd[16], so we know we have storage available */ @@ -213,7 +215,8 @@ } } -void usb_stor_transparent_scsi_command(Scsi_Cmnd *srb, struct us_data *us) +void usb_stor_transparent_scsi_command(struct scsi_cmnd *srb, + struct us_data *us) { /* send the command to the transport layer */ usb_stor_invoke_transport(srb, us); @@ -241,7 +244,7 @@ * pick up from where this one left off. */ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer, - unsigned int buflen, Scsi_Cmnd *srb, unsigned int *index, + unsigned int buflen, struct scsi_cmnd *srb, unsigned int *index, unsigned int *offset, enum xfer_buf_dir dir) { unsigned int cnt; @@ -327,7 +330,7 @@ /* Store the contents of buffer into srb's transfer buffer and set the * SCSI residue. */ void usb_stor_set_xfer_buf(unsigned char *buffer, - unsigned int buflen, Scsi_Cmnd *srb) + unsigned int buflen, struct scsi_cmnd *srb) { unsigned int index = 0, offset = 0; diff -Nru a/drivers/usb/storage/protocol.h b/drivers/usb/storage/protocol.h --- a/drivers/usb/storage/protocol.h 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/storage/protocol.h 2004-08-04 17:58:03 -07:00 @@ -41,9 +41,8 @@ #ifndef _PROTOCOL_H_ #define _PROTOCOL_H_ -#include -#include "scsi.h" -#include "usb.h" +struct scsi_cmnd; +struct us_data; /* Sub Classes */ @@ -60,18 +59,19 @@ #define US_SC_DEVICE 0xff /* Use device's value */ /* Protocol handling routines */ -extern void usb_stor_ATAPI_command(Scsi_Cmnd*, struct us_data*); -extern void usb_stor_qic157_command(Scsi_Cmnd*, struct us_data*); -extern void usb_stor_ufi_command(Scsi_Cmnd*, struct us_data*); -extern void usb_stor_transparent_scsi_command(Scsi_Cmnd*, struct us_data*); +extern void usb_stor_ATAPI_command(struct scsi_cmnd*, struct us_data*); +extern void usb_stor_qic157_command(struct scsi_cmnd*, struct us_data*); +extern void usb_stor_ufi_command(struct scsi_cmnd*, struct us_data*); +extern void usb_stor_transparent_scsi_command(struct scsi_cmnd*, + struct us_data*); -/* Scsi_Cmnd transfer buffer access utilities */ +/* struct scsi_cmnd transfer buffer access utilities */ enum xfer_buf_dir {TO_XFER_BUF, FROM_XFER_BUF}; extern unsigned int usb_stor_access_xfer_buf(unsigned char *buffer, - unsigned int buflen, Scsi_Cmnd *srb, unsigned int *index, + unsigned int buflen, struct scsi_cmnd *srb, unsigned int *index, unsigned int *offset, enum xfer_buf_dir dir); extern void usb_stor_set_xfer_buf(unsigned char *buffer, - unsigned int buflen, Scsi_Cmnd *srb); + unsigned int buflen, struct scsi_cmnd *srb); #endif diff -Nru a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c --- a/drivers/usb/storage/scsiglue.c 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/storage/scsiglue.c 2004-08-04 17:58:03 -07:00 @@ -44,17 +44,23 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "scsiglue.h" -#include "usb.h" -#include "debug.h" -#include "transport.h" -#include "protocol.h" #include #include + +#include +#include #include +#include +#include #include +#include "scsiglue.h" +#include "usb.h" +#include "debug.h" +#include "transport.h" +#include "protocol.h" + /*********************************************************************** * Host functions ***********************************************************************/ @@ -92,17 +98,15 @@ * the end, scatter-gather buffers follow page boundaries. */ blk_queue_dma_alignment(sdev->request_queue, (512 - 1)); - /* Devices using Genesys Logic chips cause a lot of trouble for - * high-speed transfers; they die unpredictably when given more - * than 64 KB of data at a time. If we detect such a device, - * reduce the maximum transfer size to 64 KB = 128 sectors. */ - -#define USB_VENDOR_ID_GENESYS 0x05e3 // Needs a standard location - + /* According to the technical support people at Genesys Logic, + * devices using their chips have problems transferring more than + * 32 KB at a time. In practice people have found that 64 KB + * works okay and that's what Windows does. But we'll be + * conservative; people can always use the sysfs interface to + * increase max_sectors. */ if (us->pusb_dev->descriptor.idVendor == USB_VENDOR_ID_GENESYS && - us->pusb_dev->speed == USB_SPEED_HIGH && - sdev->request_queue->max_sectors > 128) - blk_queue_max_sectors(sdev->request_queue, 128); + sdev->request_queue->max_sectors > 64) + blk_queue_max_sectors(sdev->request_queue, 64); /* We can't put these settings in slave_alloc() because that gets * called before the device type is known. Consequently these @@ -146,7 +150,8 @@ /* queue a command */ /* This is always called with scsi_lock(srb->host) held */ -static int queuecommand( Scsi_Cmnd *srb , void (*done)(Scsi_Cmnd *)) +static int queuecommand(struct scsi_cmnd *srb, + void (*done)(struct scsi_cmnd *)) { struct us_data *us = (struct us_data *)srb->device->host->hostdata[0]; @@ -176,7 +181,7 @@ /* Command abort */ /* This is always called with scsi_lock(srb->host) held */ -static int command_abort( Scsi_Cmnd *srb ) +static int command_abort(struct scsi_cmnd *srb ) { struct Scsi_Host *host = srb->device->host; struct us_data *us = (struct us_data *) host->hostdata[0]; @@ -223,7 +228,7 @@ /* This invokes the transport reset mechanism to reset the state of the * device */ /* This is always called with scsi_lock(srb->host) held */ -static int device_reset( Scsi_Cmnd *srb ) +static int device_reset(struct scsi_cmnd *srb) { struct us_data *us = (struct us_data *)srb->device->host->hostdata[0]; int result; @@ -258,7 +263,7 @@ /* It refuses to work if there's more than one interface in * the device, so that other users are not affected. */ /* This is always called with scsi_lock(srb->host) held */ -static int bus_reset( Scsi_Cmnd *srb ) +static int bus_reset(struct scsi_cmnd *srb) { struct us_data *us = (struct us_data *)srb->device->host->hostdata[0]; int result; @@ -444,10 +449,10 @@ * periodically someone should test to see which setting is more * optimal. */ - .use_clustering = TRUE, + .use_clustering = 1, /* emulated HBA */ - .emulated = TRUE, + .emulated = 1, /* we do our own delay after a device or bus reset */ .skip_settle_delay = 1, diff -Nru a/drivers/usb/storage/scsiglue.h b/drivers/usb/storage/scsiglue.h --- a/drivers/usb/storage/scsiglue.h 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/storage/scsiglue.h 2004-08-04 17:58:03 -07:00 @@ -41,17 +41,15 @@ #ifndef _SCSIGLUE_H_ #define _SCSIGLUE_H_ -#include -#include "scsi.h" #include -#include "usb.h" + +struct us_data; +struct scsi_cmnd; extern void usb_stor_report_device_reset(struct us_data *us); extern unsigned char usb_stor_sense_notready[18]; extern unsigned char usb_stor_sense_invalidCDB[18]; extern struct scsi_host_template usb_stor_host_template; -extern int usb_stor_scsiSense10to6(Scsi_Cmnd*); -extern int usb_stor_scsiSense6to10(Scsi_Cmnd*); #endif diff -Nru a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c --- a/drivers/usb/storage/sddr09.c 2004-08-04 17:58:04 -07:00 +++ b/drivers/usb/storage/sddr09.c 2004-08-04 17:58:04 -07:00 @@ -41,16 +41,19 @@ * EF: compute checksum (?) */ +#include +#include +#include + +#include +#include + #include "transport.h" #include "protocol.h" #include "usb.h" #include "debug.h" #include "sddr09.h" -#include -#include -#include -#include #define short_pack(lsb,msb) ( ((u16)(lsb)) | ( ((u16)(msb))<<8 ) ) #define LSB_of(s) ((s)&0xFF) @@ -1401,7 +1404,7 @@ /* * Transport for the Sandisk SDDR-09 */ -int sddr09_transport(Scsi_Cmnd *srb, struct us_data *us) +int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us) { static unsigned char sensekey = 0, sensecode = 0; static unsigned char havefakesense = 0; @@ -1581,13 +1584,13 @@ if (srb->request_bufflen == 0) return USB_STOR_TRANSPORT_GOOD; - if (srb->sc_data_direction == SCSI_DATA_WRITE || - srb->sc_data_direction == SCSI_DATA_READ) { - unsigned int pipe = (srb->sc_data_direction == SCSI_DATA_WRITE) + if (srb->sc_data_direction == DMA_TO_DEVICE || + srb->sc_data_direction == DMA_FROM_DEVICE) { + unsigned int pipe = (srb->sc_data_direction == DMA_TO_DEVICE) ? us->send_bulk_pipe : us->recv_bulk_pipe; US_DEBUGP("SDDR09: %s %d bytes\n", - (srb->sc_data_direction == SCSI_DATA_WRITE) ? + (srb->sc_data_direction == DMA_TO_DEVICE) ? "sending" : "receiving", srb->request_bufflen); diff -Nru a/drivers/usb/storage/sddr09.h b/drivers/usb/storage/sddr09.h --- a/drivers/usb/storage/sddr09.h 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/storage/sddr09.h 2004-08-04 17:58:03 -07:00 @@ -29,7 +29,7 @@ /* Sandisk SDDR-09 stuff */ -extern int sddr09_transport(Scsi_Cmnd *srb, struct us_data *us); +extern int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us); struct sddr09_card_info { unsigned long capacity; /* Size of card in bytes */ diff -Nru a/drivers/usb/storage/sddr55.c b/drivers/usb/storage/sddr55.c --- a/drivers/usb/storage/sddr55.c 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/storage/sddr55.c 2004-08-04 17:58:03 -07:00 @@ -24,15 +24,19 @@ * 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include +#include +#include + +#include +#include + #include "transport.h" #include "protocol.h" #include "usb.h" #include "debug.h" #include "sddr55.h" -#include -#include -#include #define short_pack(lsb,msb) ( ((u16)(lsb)) | ( ((u16)(msb))<<8 ) ) #define LSB_of(s) ((s)&0xFF) @@ -74,7 +78,7 @@ sddr55_bulk_transport(struct us_data *us, int direction, unsigned char *data, unsigned int len) { struct sddr55_card_info *info = (struct sddr55_card_info *)us->extra; - unsigned int pipe = (direction == SCSI_DATA_READ) ? + unsigned int pipe = (direction == DMA_FROM_DEVICE) ? us->recv_bulk_pipe : us->send_bulk_pipe; if (!len) @@ -99,7 +103,7 @@ command[5] = 0xB0; command[7] = 0x80; result = sddr55_bulk_transport(us, - SCSI_DATA_WRITE, command, 8); + DMA_TO_DEVICE, command, 8); US_DEBUGP("Result for send_command in status %d\n", result); @@ -110,7 +114,7 @@ } result = sddr55_bulk_transport(us, - SCSI_DATA_READ, status, 4); + DMA_FROM_DEVICE, status, 4); /* expect to get short transfer if no card fitted */ if (result == USB_STOR_XFER_SHORT || result == USB_STOR_XFER_STALLED) { @@ -139,7 +143,7 @@ /* now read status */ result = sddr55_bulk_transport(us, - SCSI_DATA_READ, status, 2); + DMA_FROM_DEVICE, status, 2); if (result != USB_STOR_XFER_GOOD) { set_sense_info (4, 0, 0); /* hardware error */ @@ -215,7 +219,7 @@ /* send command */ result = sddr55_bulk_transport(us, - SCSI_DATA_WRITE, command, 8); + DMA_TO_DEVICE, command, 8); US_DEBUGP("Result for send_command in read_data %d\n", result); @@ -227,7 +231,7 @@ /* read data */ result = sddr55_bulk_transport(us, - SCSI_DATA_READ, buffer, len); + DMA_FROM_DEVICE, buffer, len); if (result != USB_STOR_XFER_GOOD) { result = USB_STOR_TRANSPORT_ERROR; @@ -236,7 +240,7 @@ /* now read status */ result = sddr55_bulk_transport(us, - SCSI_DATA_READ, status, 2); + DMA_FROM_DEVICE, status, 2); if (result != USB_STOR_XFER_GOOD) { result = USB_STOR_TRANSPORT_ERROR; @@ -390,7 +394,7 @@ /* send command */ result = sddr55_bulk_transport(us, - SCSI_DATA_WRITE, command, 8); + DMA_TO_DEVICE, command, 8); if (result != USB_STOR_XFER_GOOD) { US_DEBUGP("Result for send_command in write_data %d\n", @@ -404,7 +408,7 @@ /* send the data */ result = sddr55_bulk_transport(us, - SCSI_DATA_WRITE, buffer, len); + DMA_TO_DEVICE, buffer, len); if (result != USB_STOR_XFER_GOOD) { US_DEBUGP("Result for send_data in write_data %d\n", @@ -417,7 +421,7 @@ } /* now read status */ - result = sddr55_bulk_transport(us, SCSI_DATA_READ, status, 6); + result = sddr55_bulk_transport(us, DMA_FROM_DEVICE, status, 6); if (result != USB_STOR_XFER_GOOD) { US_DEBUGP("Result for get_status in write_data %d\n", @@ -483,7 +487,7 @@ memset(command, 0, 8); command[5] = 0xB0; command[7] = 0x84; - result = sddr55_bulk_transport(us, SCSI_DATA_WRITE, command, 8); + result = sddr55_bulk_transport(us, DMA_TO_DEVICE, command, 8); US_DEBUGP("Result of send_control for device ID is %d\n", result); @@ -492,7 +496,7 @@ return USB_STOR_TRANSPORT_ERROR; result = sddr55_bulk_transport(us, - SCSI_DATA_READ, content, 4); + DMA_FROM_DEVICE, content, 4); if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; @@ -502,7 +506,7 @@ if (content[0] != 0xff) { result = sddr55_bulk_transport(us, - SCSI_DATA_READ, content, 2); + DMA_FROM_DEVICE, content, 2); } return USB_STOR_TRANSPORT_GOOD; @@ -624,21 +628,21 @@ command[6] = numblocks * 2 / 256; command[7] = 0x8A; - result = sddr55_bulk_transport(us, SCSI_DATA_WRITE, command, 8); + result = sddr55_bulk_transport(us, DMA_TO_DEVICE, command, 8); if ( result != USB_STOR_XFER_GOOD) { kfree (buffer); return -1; } - result = sddr55_bulk_transport(us, SCSI_DATA_READ, buffer, numblocks * 2); + result = sddr55_bulk_transport(us, DMA_FROM_DEVICE, buffer, numblocks * 2); if ( result != USB_STOR_XFER_GOOD) { kfree (buffer); return -1; } - result = sddr55_bulk_transport(us, SCSI_DATA_READ, command, 2); + result = sddr55_bulk_transport(us, DMA_FROM_DEVICE, command, 2); if ( result != USB_STOR_XFER_GOOD) { kfree (buffer); @@ -734,7 +738,7 @@ /* * Transport for the Sandisk SDDR-55 */ -int sddr55_transport(Scsi_Cmnd *srb, struct us_data *us) +int sddr55_transport(struct scsi_cmnd *srb, struct us_data *us) { int result; static unsigned char inquiry_response[8] = { diff -Nru a/drivers/usb/storage/sddr55.h b/drivers/usb/storage/sddr55.h --- a/drivers/usb/storage/sddr55.h 2004-08-04 17:58:04 -07:00 +++ b/drivers/usb/storage/sddr55.h 2004-08-04 17:58:04 -07:00 @@ -28,7 +28,7 @@ /* Sandisk SDDR-55 stuff */ -extern int sddr55_transport(Scsi_Cmnd *srb, struct us_data *us); +extern int sddr55_transport(struct scsi_cmnd *srb, struct us_data *us); extern int sddr55_reset(struct us_data *us); #endif diff -Nru a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c --- a/drivers/usb/storage/shuttle_usbat.c 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/storage/shuttle_usbat.c 2004-08-04 17:58:03 -07:00 @@ -39,16 +39,20 @@ * 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include +#include +#include +#include + +#include +#include + #include "transport.h" #include "protocol.h" #include "usb.h" #include "debug.h" #include "shuttle_usbat.h" -#include -#include -#include - #define short_pack(LSB,MSB) ( ((u16)(LSB)) | ( ((u16)(MSB))<<8 ) ) #define LSB_of(s) ((s)&0xFF) #define MSB_of(s) ((s)>>8) @@ -275,7 +279,7 @@ int minutes) { int result; - unsigned int pipe = (direction == SCSI_DATA_READ) ? + unsigned int pipe = (direction == DMA_FROM_DEVICE) ? us->recv_bulk_pipe : us->send_bulk_pipe; // Not really sure the 0x07, 0x17, 0xfc, 0xe7 is necessary here, @@ -315,9 +319,9 @@ } else cmdlen = 8; - command[cmdlen-8] = (direction==SCSI_DATA_WRITE ? 0x40 : 0xC0); + command[cmdlen-8] = (direction==DMA_TO_DEVICE ? 0x40 : 0xC0); command[cmdlen-7] = access | - (direction==SCSI_DATA_WRITE ? 0x05 : 0x04); + (direction==DMA_TO_DEVICE ? 0x05 : 0x04); command[cmdlen-6] = data_reg; command[cmdlen-5] = status_reg; command[cmdlen-4] = timeout; @@ -355,7 +359,7 @@ //US_DEBUGP("Transfer %s %d bytes, sg buffers %d\n", - // direction == SCSI_DATA_WRITE ? "out" : "in", + // direction == DMA_TO_DEVICE ? "out" : "in", // len, use_sg); result = usb_stor_bulk_transfer_sg(us, @@ -388,7 +392,7 @@ * the bulk output pipe only the first time. */ - if (direction==SCSI_DATA_READ && i==0) { + if (direction==DMA_FROM_DEVICE && i==0) { if (usb_stor_clear_halt(us, us->send_bulk_pipe) < 0) return USB_STOR_TRANSPORT_ERROR; @@ -399,7 +403,7 @@ */ result = usbat_read(us, USBAT_ATA, - direction==SCSI_DATA_WRITE ? 0x17 : 0x0E, + direction==DMA_TO_DEVICE ? 0x17 : 0x0E, status); if (result!=USB_STOR_XFER_GOOD) @@ -410,7 +414,7 @@ return USB_STOR_TRANSPORT_FAILED; US_DEBUGP("Redoing %s\n", - direction==SCSI_DATA_WRITE ? "write" : "read"); + direction==DMA_TO_DEVICE ? "write" : "read"); } else if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; @@ -420,7 +424,7 @@ } US_DEBUGP("Bummer! %s bulk data 20 times failed.\n", - direction==SCSI_DATA_WRITE ? "Writing" : "Reading"); + direction==DMA_TO_DEVICE ? "Writing" : "Reading"); return USB_STOR_TRANSPORT_FAILED; } @@ -520,7 +524,7 @@ static int usbat_handle_read10(struct us_data *us, unsigned char *registers, unsigned char *data, - Scsi_Cmnd *srb) + struct scsi_cmnd *srb) { int result = USB_STOR_TRANSPORT_GOOD; unsigned char *buffer; @@ -537,7 +541,7 @@ result = usbat_rw_block_test(us, USBAT_ATA, registers, data, 19, 0x10, 0x17, 0xFD, 0x30, - SCSI_DATA_READ, + DMA_FROM_DEVICE, srb->request_buffer, srb->request_bufflen, srb->use_sg, 1); @@ -606,7 +610,7 @@ result = usbat_rw_block_test(us, USBAT_ATA, registers, data, 19, 0x10, 0x17, 0xFD, 0x30, - SCSI_DATA_READ, + DMA_FROM_DEVICE, buffer, len, 0, 1); @@ -803,7 +807,7 @@ /* * Transport for the HP 8200e */ -int hp8200e_transport(Scsi_Cmnd *srb, struct us_data *us) +int hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us) { int result; unsigned char *status = us->iobuf; @@ -847,12 +851,12 @@ if (srb->cmnd[0] == TEST_UNIT_READY) transferred = 0; - if (srb->sc_data_direction == SCSI_DATA_WRITE) { + if (srb->sc_data_direction == DMA_TO_DEVICE) { result = usbat_rw_block_test(us, USBAT_ATA, registers, data, 19, 0x10, 0x17, 0xFD, 0x30, - SCSI_DATA_WRITE, + DMA_TO_DEVICE, srb->request_buffer, len, srb->use_sg, 10); @@ -900,7 +904,7 @@ // If there is response data to be read in // then do it here. - if (len != 0 && (srb->sc_data_direction == SCSI_DATA_READ)) { + if (len != 0 && (srb->sc_data_direction == DMA_FROM_DEVICE)) { // How many bytes to read in? Check cylL register diff -Nru a/drivers/usb/storage/shuttle_usbat.h b/drivers/usb/storage/shuttle_usbat.h --- a/drivers/usb/storage/shuttle_usbat.h 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/storage/shuttle_usbat.h 2004-08-04 17:58:03 -07:00 @@ -53,7 +53,7 @@ #define USBAT_UIO_ADPRST 0x01 // Reset SCM chip /* HP 8200e stuff */ -extern int hp8200e_transport(Scsi_Cmnd *srb, struct us_data *us); +extern int hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us); extern int init_8200e(struct us_data *us); #endif diff -Nru a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c --- a/drivers/usb/storage/transport.c 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/storage/transport.c 2004-08-04 17:58:03 -07:00 @@ -46,15 +46,20 @@ */ #include +#include +#include +#include + +#include +#include +#include + #include "transport.h" #include "protocol.h" #include "scsiglue.h" #include "usb.h" #include "debug.h" -#include -#include -#include /*********************************************************************** * Data transfer routines @@ -522,7 +527,7 @@ * This is used by the protocol layers to actually send the message to * the device and receive the response. */ -void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us) +void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) { int need_auto_sense; int result; @@ -569,7 +574,7 @@ * can signal most data-in errors by stalling the bulk-in pipe. */ if ((us->protocol == US_PR_CB || us->protocol == US_PR_DPCM_USB) && - srb->sc_data_direction != SCSI_DATA_READ) { + srb->sc_data_direction != DMA_FROM_DEVICE) { US_DEBUGP("-- CB transport device requiring auto-sense\n"); need_auto_sense = 1; } @@ -629,7 +634,7 @@ /* set the transfer direction */ old_sc_data_direction = srb->sc_data_direction; - srb->sc_data_direction = SCSI_DATA_READ; + srb->sc_data_direction = DMA_FROM_DEVICE; /* use the new buffer we have */ old_request_buffer = srb->request_buffer; @@ -749,7 +754,7 @@ * Control/Bulk/Interrupt transport */ -int usb_stor_CBI_transport(Scsi_Cmnd *srb, struct us_data *us) +int usb_stor_CBI_transport(struct scsi_cmnd *srb, struct us_data *us) { unsigned int transfer_length = srb->request_bufflen; unsigned int pipe = 0; @@ -778,7 +783,7 @@ /* DATA STAGE */ /* transfer the data payload for this command, if one exists*/ if (transfer_length) { - pipe = srb->sc_data_direction == SCSI_DATA_READ ? + pipe = srb->sc_data_direction == DMA_FROM_DEVICE ? us->recv_bulk_pipe : us->send_bulk_pipe; result = usb_stor_bulk_transfer_sg(us, pipe, srb->request_buffer, transfer_length, @@ -849,7 +854,7 @@ /* * Control/Bulk transport */ -int usb_stor_CB_transport(Scsi_Cmnd *srb, struct us_data *us) +int usb_stor_CB_transport(struct scsi_cmnd *srb, struct us_data *us) { unsigned int transfer_length = srb->request_bufflen; int result; @@ -877,7 +882,7 @@ /* DATA STAGE */ /* transfer the data payload for this command, if one exists*/ if (transfer_length) { - unsigned int pipe = srb->sc_data_direction == SCSI_DATA_READ ? + unsigned int pipe = srb->sc_data_direction == DMA_FROM_DEVICE ? us->recv_bulk_pipe : us->send_bulk_pipe; result = usb_stor_bulk_transfer_sg(us, pipe, srb->request_buffer, transfer_length, @@ -939,7 +944,7 @@ return -1; } -int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us) +int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us) { struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; struct bulk_cs_wrap *bcs = (struct bulk_cs_wrap *) us->iobuf; @@ -952,7 +957,7 @@ /* set up the command wrapper */ bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = cpu_to_le32(transfer_length); - bcb->Flags = srb->sc_data_direction == SCSI_DATA_READ ? 1 << 7 : 0; + bcb->Flags = srb->sc_data_direction == DMA_FROM_DEVICE ? 1 << 7 : 0; bcb->Tag = srb->serial_number; bcb->Lun = srb->device->lun; if (us->flags & US_FL_SCM_MULT_TARG) @@ -977,8 +982,14 @@ /* DATA STAGE */ /* send/receive data payload, if there is any */ + + /* Genesys Logic interface chips need a 100us delay between the + * command phase and the data phase */ + if (us->pusb_dev->descriptor.idVendor == USB_VENDOR_ID_GENESYS) + udelay(100); + if (transfer_length) { - unsigned int pipe = srb->sc_data_direction == SCSI_DATA_READ ? + unsigned int pipe = srb->sc_data_direction == DMA_FROM_DEVICE ? us->recv_bulk_pipe : us->send_bulk_pipe; result = usb_stor_bulk_transfer_sg(us, pipe, srb->request_buffer, transfer_length, diff -Nru a/drivers/usb/storage/transport.h b/drivers/usb/storage/transport.h --- a/drivers/usb/storage/transport.h 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/storage/transport.h 2004-08-04 17:58:03 -07:00 @@ -44,7 +44,8 @@ #include #include #include "usb.h" -#include "scsi.h" + +struct scsi_cmnd; /* Protocols */ @@ -150,16 +151,16 @@ #define US_CBI_ADSC 0 -extern int usb_stor_CBI_transport(Scsi_Cmnd*, struct us_data*); +extern int usb_stor_CBI_transport(struct scsi_cmnd *, struct us_data*); -extern int usb_stor_CB_transport(Scsi_Cmnd*, struct us_data*); +extern int usb_stor_CB_transport(struct scsi_cmnd *, struct us_data*); extern int usb_stor_CB_reset(struct us_data*); -extern int usb_stor_Bulk_transport(Scsi_Cmnd*, struct us_data*); +extern int usb_stor_Bulk_transport(struct scsi_cmnd *, struct us_data*); extern int usb_stor_Bulk_max_lun(struct us_data*); extern int usb_stor_Bulk_reset(struct us_data*); -extern void usb_stor_invoke_transport(Scsi_Cmnd*, struct us_data*); +extern void usb_stor_invoke_transport(struct scsi_cmnd *, struct us_data*); extern void usb_stor_stop_transport(struct us_data*); extern int usb_stor_control_msg(struct us_data *us, unsigned int pipe, diff -Nru a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h --- a/drivers/usb/storage/unusual_devs.h 2004-08-04 17:58:04 -07:00 +++ b/drivers/usb/storage/unusual_devs.h 2004-08-04 17:58:04 -07:00 @@ -45,11 +45,6 @@ * */ -UNUSUAL_DEV( 0x03ee, 0x0000, 0x0000, 0x0245, - "Mitsumi", - "CD-R/RW Drive", - US_SC_8020, US_PR_CBI, NULL, 0), - UNUSUAL_DEV( 0x03ee, 0x6901, 0x0000, 0x0100, "Mitsumi", "USB FDD", @@ -373,6 +368,15 @@ US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_SINGLE_LUN), +/* Reported by Johann Cardon + * This entry is needed only because the device reports + * bInterfaceClass = 0xff (vendor-specific) + */ +UNUSUAL_DEV( 0x057b, 0x0022, 0x0000, 0x9999, + "Y-E Data", + "Silicon Media R/W", + US_SC_DEVICE, US_PR_DEVICE, NULL, 0), + /* Fabrizio Fellini */ UNUSUAL_DEV( 0x0595, 0x4343, 0x0000, 0x2210, "Fujifilm", @@ -384,11 +388,15 @@ "USB Hard Disk", US_SC_RBC, US_PR_CB, NULL, 0 ), -/* Submitted by Jol Bourquard */ +/* Submitted by Joel Bourquard + * Some versions of this device need the SubClass and Protocol overrides + * while others don't. + */ UNUSUAL_DEV( 0x05ab, 0x0060, 0x1104, 0x1110, "In-System", "PyroGate External CD-ROM Enclosure (FCD-523)", - US_SC_SCSI, US_PR_BULK, NULL, 0 ), + US_SC_SCSI, US_PR_BULK, NULL, + US_FL_NEED_OVERRIDE ), #ifdef CONFIG_USB_STORAGE_ISD200 UNUSUAL_DEV( 0x05ab, 0x0031, 0x0100, 0x0110, @@ -685,7 +693,7 @@ "Trumpion", "t33520 USB Flash Card Controller", US_SC_DEVICE, US_PR_BULK, NULL, - US_FL_MODE_XLATE), + US_FL_NEED_OVERRIDE | US_FL_MODE_XLATE), /* Trumpion Microelectronics MP3 player (felipe_alfaro@linuxmail.org) */ UNUSUAL_DEV( 0x090a, 0x1200, 0x0000, 0x9999, diff -Nru a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c --- a/drivers/usb/storage/usb.c 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/storage/usb.c 2004-08-04 17:58:03 -07:00 @@ -50,6 +50,11 @@ #include #include #include + +#include +#include +#include + #include "usb.h" #include "scsiglue.h" #include "transport.h" @@ -322,7 +327,7 @@ /* reject the command if the direction indicator * is UNKNOWN */ - if (us->srb->sc_data_direction == SCSI_DATA_UNKNOWN) { + if (us->srb->sc_data_direction == DMA_BIDIRECTIONAL) { US_DEBUGP("UNKNOWN data direction\n"); us->srb->result = DID_ERROR << 16; } @@ -423,6 +428,13 @@ us->pusb_dev = interface_to_usbdev(intf); us->pusb_intf = intf; us->ifnum = intf->cur_altsetting->desc.bInterfaceNumber; + US_DEBUGP("Vendor: 0x%04x, Product: 0x%04x, Revision: 0x%04x\n", + us->pusb_dev->descriptor.idVendor, + us->pusb_dev->descriptor.idProduct, + us->pusb_dev->descriptor.bcdDevice); + US_DEBUGP("Interface Subclass: 0x%02x, Protocol: 0x%02x\n", + intf->cur_altsetting->desc.bInterfaceSubClass, + intf->cur_altsetting->desc.bInterfaceProtocol); /* Store our private data in the interface */ usb_set_intfdata(intf, us); @@ -453,11 +465,6 @@ struct us_unusual_dev *unusual_dev = &us_unusual_dev_list[id_index]; struct usb_device_id *id = &storage_usb_ids[id_index]; - if (unusual_dev->vendorName) - US_DEBUGP("Vendor: %s\n", unusual_dev->vendorName); - if (unusual_dev->productName) - US_DEBUGP("Product: %s\n", unusual_dev->productName); - /* Store the entries */ us->unusual_dev = unusual_dev; us->subclass = (unusual_dev->useProtocol == US_SC_DEVICE) ? @@ -528,6 +535,8 @@ } if (strlen(us->serial) == 0) strcpy(us->serial, "None"); + + US_DEBUGP("Vendor: %s, Product: %s\n", us->vendor, us->product); } /* Get the transport settings */ @@ -715,8 +724,6 @@ ep_int = ep; } } - US_DEBUGP("Endpoints: In: 0x%p Out: 0x%p Int: 0x%p (Period %d)\n", - ep_in, ep_out, ep_int, ep_int ? ep_int->bInterval : 0); if (!ep_in || !ep_out || (us->protocol == US_PR_CBI && !ep_int)) { US_DEBUGP("Endpoint sanity check failed! Rejecting dev.\n"); @@ -880,9 +887,6 @@ int result; US_DEBUGP("USB Mass Storage device detected\n"); - US_DEBUGP("altsetting is %d, id_index is %d\n", - intf->cur_altsetting->desc.bAlternateSetting, - id_index); /* Allocate the us_data structure and initialize the mutexes */ us = (struct us_data *) kmalloc(sizeof(*us), GFP_KERNEL); diff -Nru a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h --- a/drivers/usb/storage/usb.h 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/storage/usb.h 2004-08-04 17:58:03 -07:00 @@ -48,10 +48,9 @@ #include #include #include -#include "scsi.h" -#include struct us_data; +struct scsi_cmnd; /* * Unusual device list definitions @@ -102,9 +101,9 @@ #define US_IOBUF_SIZE 64 /* Size of the DMA-mapped I/O buffer */ -typedef int (*trans_cmnd)(Scsi_Cmnd*, struct us_data*); +typedef int (*trans_cmnd)(struct scsi_cmnd *, struct us_data*); typedef int (*trans_reset)(struct us_data*); -typedef void (*proto_cmnd)(Scsi_Cmnd*, struct us_data*); +typedef void (*proto_cmnd)(struct scsi_cmnd*, struct us_data*); typedef void (*extra_data_destructor)(void *); /* extra data destructor */ /* we allocate one of these for every device that we remember */ @@ -144,7 +143,7 @@ /* SCSI interfaces */ struct Scsi_Host *host; /* our dummy host data */ - Scsi_Cmnd *srb; /* current srb */ + struct scsi_cmnd *srb; /* current srb */ /* thread information */ int pid; /* control thread */ @@ -179,5 +178,9 @@ * single queue element srb for write access */ #define scsi_unlock(host) spin_unlock_irq(host->host_lock) #define scsi_lock(host) spin_lock_irq(host->host_lock) + + +/* Vendor ID list for devices that require special handling */ +#define USB_VENDOR_ID_GENESYS 0x05e3 /* Genesys Logic */ #endif diff -Nru a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c --- a/drivers/usb/usb-skeleton.c 2004-08-04 17:58:03 -07:00 +++ b/drivers/usb/usb-skeleton.c 2004-08-04 17:58:03 -07:00 @@ -1,42 +1,15 @@ /* - * USB Skeleton driver - 1.1 + * USB Skeleton driver - 2.0 * - * Copyright (C) 2001-2003 Greg Kroah-Hartman (greg@kroah.com) + * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, version 2. * - * - * This driver is to be used as a skeleton driver to be able to create a - * USB driver quickly. The design of it is based on the usb-serial and - * dc2xx drivers. - * - * Thanks to Oliver Neukum, David Brownell, and Alan Stern for their help - * in debugging this driver. - * - * - * History: - * - * 2003-05-06 - 1.1 - changes due to usb core changes with usb_register_dev() - * 2003-02-25 - 1.0 - fix races involving urb->status, unlink_urb(), and - * disconnect. Fix transfer amount in read(). Use - * macros instead of magic numbers in probe(). Change - * size variables to size_t. Show how to eliminate - * DMA bounce buffer. - * 2002_12_12 - 0.9 - compile fixes and got rid of fixed minor array. - * 2002_09_26 - 0.8 - changes due to USB core conversion to struct device - * driver. - * 2002_02_12 - 0.7 - zero out dev in probe function for devices that do - * not have both a bulk in and bulk out endpoint. - * Thanks to Holger Waechtler for the fix. - * 2001_11_05 - 0.6 - fix minor locking problem in skel_disconnect. - * Thanks to Pete Zaitcev for the fix. - * 2001_09_04 - 0.5 - fix devfs bug in skel_disconnect. Thanks to wim delvaux - * 2001_08_21 - 0.4 - more small bug fixes. - * 2001_05_29 - 0.3 - more bug fixes based on review from linux-usb-devel - * 2001_05_24 - 0.2 - bug fixes based on review from linux-usb-devel people - * 2001_05_01 - 0.1 - first version + * This driver is based on the 2.6.3 version of drivers/usb/usb-skeleton.c + * but has been rewritten to be easy to read and use, as no locks are now + * needed anymore. * */ @@ -46,31 +19,10 @@ #include #include #include -#include -#include +#include #include #include -#ifdef CONFIG_USB_DEBUG - static int debug = 1; -#else - static int debug; -#endif - -/* Use our own dbg macro */ -#undef dbg -#define dbg(format, arg...) do { if (debug) printk(KERN_DEBUG __FILE__ ": " format "\n" , ## arg); } while (0) - - -/* Version Information */ -#define DRIVER_VERSION "v1.0" -#define DRIVER_AUTHOR "Greg Kroah-Hartman, greg@kroah.com" -#define DRIVER_DESC "USB Skeleton Driver" - -/* Module parameters */ -MODULE_PARM(debug, "i"); -MODULE_PARM_DESC(debug, "Debug enabled or not"); - /* Define these values to match your devices */ #define USB_SKEL_VENDOR_ID 0xfff0 @@ -79,11 +31,8 @@ /* table of devices that work with this driver */ static struct usb_device_id skel_table [] = { { USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) }, - /* "Gadget Zero" firmware runs under Linux */ - { USB_DEVICE(0x0525, 0xa4a0) }, { } /* Terminating entry */ }; - MODULE_DEVICE_TABLE (usb, skel_table); @@ -92,413 +41,195 @@ /* Structure to hold all of our device specific stuff */ struct usb_skel { - struct usb_device * udev; /* save off the usb device pointer */ + struct usb_device * udev; /* the usb device for this device */ struct usb_interface * interface; /* the interface for this device */ - unsigned char minor; /* the starting minor number for this device */ - unsigned char num_ports; /* the number of ports this device has */ - char num_interrupt_in; /* number of interrupt in endpoints we have */ - char num_bulk_in; /* number of bulk in endpoints we have */ - char num_bulk_out; /* number of bulk out endpoints we have */ - unsigned char * bulk_in_buffer; /* the buffer to receive data */ size_t bulk_in_size; /* the size of the receive buffer */ __u8 bulk_in_endpointAddr; /* the address of the bulk in endpoint */ - - unsigned char * bulk_out_buffer; /* the buffer to send data */ - size_t bulk_out_size; /* the size of the send buffer */ - struct urb * write_urb; /* the urb used to send data */ __u8 bulk_out_endpointAddr; /* the address of the bulk out endpoint */ - atomic_t write_busy; /* true iff write urb is busy */ - struct completion write_finished; /* wait for the write to finish */ - - int open; /* if the port is open or not */ - int present; /* if the device is not disconnected */ - struct semaphore sem; /* locks this structure */ + struct kref kref; }; +#define to_skel_dev(d) container_of(d, struct usb_skel, kref) +static struct usb_driver skel_driver; -/* prevent races between open() and disconnect() */ -static DECLARE_MUTEX (disconnect_sem); - -/* local function prototypes */ -static ssize_t skel_read (struct file *file, char *buffer, size_t count, loff_t *ppos); -static ssize_t skel_write (struct file *file, const char *buffer, size_t count, loff_t *ppos); -static int skel_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); -static int skel_open (struct inode *inode, struct file *file); -static int skel_release (struct inode *inode, struct file *file); - -static int skel_probe (struct usb_interface *interface, const struct usb_device_id *id); -static void skel_disconnect (struct usb_interface *interface); - -static void skel_write_bulk_callback (struct urb *urb, struct pt_regs *regs); - -/* - * File operations needed when we register this driver. - * This assumes that this driver NEEDS file operations, - * of course, which means that the driver is expected - * to have a node in the /dev directory. If the USB - * device were for a network interface then the driver - * would use "struct net_driver" instead, and a serial - * device would use "struct tty_driver". - */ -static struct file_operations skel_fops = { - /* - * The owner field is part of the module-locking - * mechanism. The idea is that the kernel knows - * which module to increment the use-counter of - * BEFORE it calls the device's open() function. - * This also means that the kernel can decrement - * the use-counter again before calling release() - * or should the open() function fail. - */ - .owner = THIS_MODULE, - - .read = skel_read, - .write = skel_write, - .ioctl = skel_ioctl, - .open = skel_open, - .release = skel_release, -}; - -/* - * usb class driver info in order to get a minor number from the usb core, - * and to have the device registered with devfs and the driver core - */ -static struct usb_class_driver skel_class = { - .name = "usb/skel%d", - .fops = &skel_fops, - .mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, - .minor_base = USB_SKEL_MINOR_BASE, -}; - -/* usb specific object needed to register this driver with the usb subsystem */ -static struct usb_driver skel_driver = { - .owner = THIS_MODULE, - .name = "skeleton", - .probe = skel_probe, - .disconnect = skel_disconnect, - .id_table = skel_table, -}; - - -/** - * usb_skel_debug_data - */ -static inline void usb_skel_debug_data (const char *function, int size, const unsigned char *data) -{ - int i; - - if (!debug) - return; - - printk (KERN_DEBUG __FILE__": %s - length = %d, data = ", - function, size); - for (i = 0; i < size; ++i) { - printk ("%.2x ", data[i]); - } - printk ("\n"); -} - +static void skel_delete(struct kref *kref) +{ + struct usb_skel *dev = to_skel_dev(kref); -/** - * skel_delete - */ -static inline void skel_delete (struct usb_skel *dev) -{ + usb_put_dev(dev->udev); kfree (dev->bulk_in_buffer); - usb_buffer_free (dev->udev, dev->bulk_out_size, - dev->bulk_out_buffer, - dev->write_urb->transfer_dma); - usb_free_urb (dev->write_urb); kfree (dev); } - -/** - * skel_open - */ -static int skel_open (struct inode *inode, struct file *file) +static int skel_open(struct inode *inode, struct file *file) { - struct usb_skel *dev = NULL; + struct usb_skel *dev; struct usb_interface *interface; int subminor; int retval = 0; - dbg("%s", __FUNCTION__); - subminor = iminor(inode); - /* prevent disconnects */ - down (&disconnect_sem); - - interface = usb_find_interface (&skel_driver, subminor); + interface = usb_find_interface(&skel_driver, subminor); if (!interface) { err ("%s - error, can't find device for minor %d", __FUNCTION__, subminor); retval = -ENODEV; - goto exit_no_device; + goto exit; } dev = usb_get_intfdata(interface); if (!dev) { retval = -ENODEV; - goto exit_no_device; + goto exit; } - /* lock this device */ - down (&dev->sem); - - /* increment our usage count for the driver */ - ++dev->open; + /* increment our usage count for the device */ + kref_get(&dev->kref); /* save our object in the file's private structure */ file->private_data = dev; - /* unlock this device */ - up (&dev->sem); - -exit_no_device: - up (&disconnect_sem); +exit: return retval; } - -/** - * skel_release - */ -static int skel_release (struct inode *inode, struct file *file) +static int skel_release(struct inode *inode, struct file *file) { struct usb_skel *dev; - int retval = 0; dev = (struct usb_skel *)file->private_data; - if (dev == NULL) { - dbg ("%s - object is NULL", __FUNCTION__); + if (dev == NULL) return -ENODEV; - } - - dbg("%s - minor %d", __FUNCTION__, dev->minor); - - /* lock our device */ - down (&dev->sem); - - if (dev->open <= 0) { - dbg ("%s - device not opened", __FUNCTION__); - retval = -ENODEV; - goto exit_not_opened; - } - - /* wait for any bulk writes that might be going on to finish up */ - if (atomic_read (&dev->write_busy)) - wait_for_completion (&dev->write_finished); - - --dev->open; - if (!dev->present && !dev->open) { - /* the device was unplugged before the file was released */ - up (&dev->sem); - skel_delete (dev); - return 0; - } - -exit_not_opened: - up (&dev->sem); - - return retval; + /* decrement the count on our device */ + kref_put(&dev->kref, skel_delete); + return 0; } - -/** - * skel_read - */ -static ssize_t skel_read (struct file *file, char *buffer, size_t count, loff_t *ppos) +static ssize_t skel_read(struct file *file, char *buffer, size_t count, loff_t *ppos) { struct usb_skel *dev; int retval = 0; dev = (struct usb_skel *)file->private_data; - - dbg("%s - minor %d, count = %d", __FUNCTION__, dev->minor, count); - - /* lock this object */ - down (&dev->sem); - - /* verify that the device wasn't unplugged */ - if (!dev->present) { - up (&dev->sem); - return -ENODEV; - } - + /* do a blocking bulk read to get data from the device */ - retval = usb_bulk_msg (dev->udev, - usb_rcvbulkpipe (dev->udev, - dev->bulk_in_endpointAddr), - dev->bulk_in_buffer, - min (dev->bulk_in_size, count), - &count, HZ*10); + retval = usb_bulk_msg(dev->udev, + usb_rcvbulkpipe(dev->udev, dev->bulk_in_endpointAddr), + dev->bulk_in_buffer, + min(dev->bulk_in_size, count), + &count, HZ*10); /* if the read was successful, copy the data to userspace */ if (!retval) { - if (copy_to_user (buffer, dev->bulk_in_buffer, count)) + if (copy_to_user(buffer, dev->bulk_in_buffer, count)) retval = -EFAULT; else retval = count; } - /* unlock the device */ - up (&dev->sem); return retval; } +static void skel_write_bulk_callback(struct urb *urb, struct pt_regs *regs) +{ + struct usb_skel *dev; -/** - * skel_write - * - * A device driver has to decide how to report I/O errors back to the - * user. The safest course is to wait for the transfer to finish before - * returning so that any errors will be reported reliably. skel_read() - * works like this. But waiting for I/O is slow, so many drivers only - * check for errors during I/O initiation and do not report problems - * that occur during the actual transfer. That's what we will do here. - * - * A driver concerned with maximum I/O throughput would use double- - * buffering: Two urbs would be devoted to write transfers, so that - * one urb could always be active while the other was waiting for the - * user to send more data. - */ -static ssize_t skel_write (struct file *file, const char *buffer, size_t count, loff_t *ppos) + dev = (struct usb_skel *)urb->context; + + /* sync/async unlink faults aren't errors */ + if (urb->status && + !(urb->status == -ENOENT || + urb->status == -ECONNRESET || + urb->status == -ESHUTDOWN)) { + dbg("%s - nonzero write bulk status received: %d", + __FUNCTION__, urb->status); + } + + /* free up our allocated buffer */ + usb_buffer_free(urb->dev, urb->transfer_buffer_length, + urb->transfer_buffer, urb->transfer_dma); +} + +static ssize_t skel_write(struct file *file, const char *user_buffer, size_t count, loff_t *ppos) { struct usb_skel *dev; - ssize_t bytes_written = 0; int retval = 0; + struct urb *urb = NULL; + char *buf = NULL; dev = (struct usb_skel *)file->private_data; - dbg("%s - minor %d, count = %d", __FUNCTION__, dev->minor, count); - - /* lock this object */ - down (&dev->sem); - - /* verify that the device wasn't unplugged */ - if (!dev->present) { - retval = -ENODEV; + /* verify that we actually have some data to write */ + if (count == 0) goto exit; + + /* create a urb, and a buffer for it, and copy the data to the urb */ + urb = usb_alloc_urb(0, GFP_KERNEL); + if (!urb) { + retval = -ENOMEM; + goto error; } - /* verify that we actually have some data to write */ - if (count == 0) { - dbg("%s - write request of 0 bytes", __FUNCTION__); - goto exit; + buf = usb_buffer_alloc(dev->udev, count, GFP_KERNEL, &urb->transfer_dma); + if (!buf) { + retval = -ENOMEM; + goto error; } - /* wait for a previous write to finish up; we don't use a timeout - * and so a nonresponsive device can delay us indefinitely. - */ - if (atomic_read (&dev->write_busy)) - wait_for_completion (&dev->write_finished); - - /* we can only write as much as our buffer will hold */ - bytes_written = min (dev->bulk_out_size, count); - - /* copy the data from userspace into our transfer buffer; - * this is the only copy required. - */ - if (copy_from_user(dev->write_urb->transfer_buffer, buffer, - bytes_written)) { + if (copy_from_user(buf, user_buffer, count)) { retval = -EFAULT; - goto exit; + goto error; } - usb_skel_debug_data (__FUNCTION__, bytes_written, - dev->write_urb->transfer_buffer); - - /* this urb was already set up, except for this write size */ - dev->write_urb->transfer_buffer_length = bytes_written; + /* initialize the urb properly */ + usb_fill_bulk_urb(urb, dev->udev, + usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr), + buf, count, skel_write_bulk_callback, dev); + urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; /* send the data out the bulk port */ - /* a character device write uses GFP_KERNEL, - unless a spinlock is held */ - init_completion (&dev->write_finished); - atomic_set (&dev->write_busy, 1); - retval = usb_submit_urb(dev->write_urb, GFP_KERNEL); + retval = usb_submit_urb(urb, GFP_KERNEL); if (retval) { - atomic_set (&dev->write_busy, 0); - err("%s - failed submitting write urb, error %d", - __FUNCTION__, retval); - } else { - retval = bytes_written; + err("%s - failed submitting write urb, error %d", __FUNCTION__, retval); + goto error; } + /* release our reference to this urb, the USB core will eventually free it entirely */ + usb_free_urb(urb); + exit: - /* unlock the device */ - up (&dev->sem); + return count; +error: + usb_buffer_free(dev->udev, count, buf, urb->transfer_dma); + usb_free_urb(urb); return retval; } +static struct file_operations skel_fops = { + .owner = THIS_MODULE, + .read = skel_read, + .write = skel_write, + .open = skel_open, + .release = skel_release, +}; -/** - * skel_ioctl - */ -static int skel_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) -{ - struct usb_skel *dev; - - dev = (struct usb_skel *)file->private_data; - - /* lock this object */ - down (&dev->sem); - - /* verify that the device wasn't unplugged */ - if (!dev->present) { - up (&dev->sem); - return -ENODEV; - } - - dbg("%s - minor %d, cmd 0x%.4x, arg %ld", __FUNCTION__, - dev->minor, cmd, arg); - - /* fill in your device specific stuff here */ - - /* unlock the device */ - up (&dev->sem); - - /* return that we did not understand this ioctl call */ - return -ENOTTY; -} - - -/** - * skel_write_bulk_callback +/* + * usb class driver info in order to get a minor number from the usb core, + * and to have the device registered with devfs and the driver core */ -static void skel_write_bulk_callback (struct urb *urb, struct pt_regs *regs) -{ - struct usb_skel *dev = (struct usb_skel *)urb->context; - - dbg("%s - minor %d", __FUNCTION__, dev->minor); - - /* sync/async unlink faults aren't errors */ - if (urb->status && !(urb->status == -ENOENT || - urb->status == -ECONNRESET)) { - dbg("%s - nonzero write bulk status received: %d", - __FUNCTION__, urb->status); - } - - /* notify anyone waiting that the write has finished */ - atomic_set (&dev->write_busy, 0); - complete (&dev->write_finished); -} - +static struct usb_class_driver skel_class = { + .name = "usb/skel%d", + .fops = &skel_fops, + .mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, + .minor_base = USB_SKEL_MINOR_BASE, +}; -/** - * skel_probe - * - * Called by the usb core when a new device is connected that it thinks - * this driver might be interested in. - */ static int skel_probe(struct usb_interface *interface, const struct usb_device_id *id) { - struct usb_device *udev = interface_to_usbdev(interface); struct usb_skel *dev = NULL; struct usb_host_interface *iface_desc; struct usb_endpoint_descriptor *endpoint; @@ -506,28 +237,21 @@ int i; int retval = -ENOMEM; - /* See if the device offered us matches what we can accept */ - if ((udev->descriptor.idVendor != USB_SKEL_VENDOR_ID) || - (udev->descriptor.idProduct != USB_SKEL_PRODUCT_ID)) { - return -ENODEV; - } - /* allocate memory for our device state and initialize it */ - dev = kmalloc (sizeof(struct usb_skel), GFP_KERNEL); + dev = kmalloc(sizeof(*dev), GFP_KERNEL); if (dev == NULL) { - err ("Out of memory"); - return -ENOMEM; + err("Out of memory"); + goto error; } - memset (dev, 0x00, sizeof (*dev)); + memset(dev, 0x00, sizeof(*dev)); + kref_init(&dev->kref); - init_MUTEX (&dev->sem); - dev->udev = udev; + dev->udev = usb_get_dev(interface_to_usbdev(interface)); dev->interface = interface; /* set up the endpoint information */ - /* check out the endpoints */ /* use only the first bulk-in and bulk-out endpoints */ - iface_desc = &interface->altsetting[0]; + iface_desc = interface->cur_altsetting; for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { endpoint = &iface_desc->endpoint[i].desc; @@ -539,9 +263,9 @@ buffer_size = endpoint->wMaxPacketSize; dev->bulk_in_size = buffer_size; dev->bulk_in_endpointAddr = endpoint->bEndpointAddress; - dev->bulk_in_buffer = kmalloc (buffer_size, GFP_KERNEL); + dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL); if (!dev->bulk_in_buffer) { - err("Couldn't allocate bulk_in_buffer"); + err("Could not allocate bulk_in_buffer"); goto error; } } @@ -551,153 +275,85 @@ ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK)) { /* we found a bulk out endpoint */ - /* a probe() may sleep and has no restrictions on memory allocations */ - dev->write_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!dev->write_urb) { - err("No free urbs available"); - goto error; - } dev->bulk_out_endpointAddr = endpoint->bEndpointAddress; - - /* on some platforms using this kind of buffer alloc - * call eliminates a dma "bounce buffer". - * - * NOTE: you'd normally want i/o buffers that hold - * more than one packet, so that i/o delays between - * packets don't hurt throughput. - */ - buffer_size = endpoint->wMaxPacketSize; - dev->bulk_out_size = buffer_size; - dev->write_urb->transfer_flags = (URB_NO_TRANSFER_DMA_MAP | - URB_ASYNC_UNLINK); - dev->bulk_out_buffer = usb_buffer_alloc (udev, - buffer_size, GFP_KERNEL, - &dev->write_urb->transfer_dma); - if (!dev->bulk_out_buffer) { - err("Couldn't allocate bulk_out_buffer"); - goto error; - } - usb_fill_bulk_urb(dev->write_urb, udev, - usb_sndbulkpipe(udev, - endpoint->bEndpointAddress), - dev->bulk_out_buffer, buffer_size, - skel_write_bulk_callback, dev); } } if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr)) { - err("Couldn't find both bulk-in and bulk-out endpoints"); + err("Could not find both bulk-in and bulk-out endpoints"); goto error; } - /* allow device read, write and ioctl */ - dev->present = 1; + /* save our data pointer in this interface device */ + usb_set_intfdata(interface, dev); /* we can register the device now, as it is ready */ - usb_set_intfdata (interface, dev); - retval = usb_register_dev (interface, &skel_class); + retval = usb_register_dev(interface, &skel_class); if (retval) { /* something prevented us from registering this driver */ - err ("Not able to get a minor for this device."); - usb_set_intfdata (interface, NULL); + err("Not able to get a minor for this device."); + usb_set_intfdata(interface, NULL); goto error; } - dev->minor = interface->minor; - /* let the user know what node this device is now attached to */ - info ("USB Skeleton device now attached to USBSkel-%d", dev->minor); + info("USB Skeleton device now attached to USBSkel-%d", interface->minor); return 0; error: - skel_delete (dev); + if (dev) + kref_put(&dev->kref, skel_delete); return retval; } - -/** - * skel_disconnect - * - * Called by the usb core when the device is removed from the system. - * - * This routine guarantees that the driver will not submit any more urbs - * by clearing dev->udev. It is also supposed to terminate any currently - * active urbs. Unfortunately, usb_bulk_msg(), used in skel_read(), does - * not provide any way to do this. But at least we can cancel an active - * write. - */ static void skel_disconnect(struct usb_interface *interface) { struct usb_skel *dev; - int minor; + int minor = interface->minor; - /* prevent races with open() */ - down (&disconnect_sem); + /* prevent skel_open() from racing skel_disconnect() */ + lock_kernel(); - dev = usb_get_intfdata (interface); - usb_set_intfdata (interface, NULL); - - down (&dev->sem); - - minor = dev->minor; + dev = usb_get_intfdata(interface); + usb_set_intfdata(interface, NULL); /* give back our minor */ - usb_deregister_dev (interface, &skel_class); + usb_deregister_dev(interface, &skel_class); - /* terminate an ongoing write */ - if (atomic_read (&dev->write_busy)) { - usb_unlink_urb (dev->write_urb); - wait_for_completion (&dev->write_finished); - } - - /* prevent device read, write and ioctl */ - dev->present = 0; - - up (&dev->sem); + unlock_kernel(); - /* if the device is opened, skel_release will clean this up */ - if (!dev->open) - skel_delete (dev); - - up (&disconnect_sem); + /* decrement our usage count */ + kref_put(&dev->kref, skel_delete); info("USB Skeleton #%d now disconnected", minor); } +static struct usb_driver skel_driver = { + .owner = THIS_MODULE, + .name = "skeleton", + .probe = skel_probe, + .disconnect = skel_disconnect, + .id_table = skel_table, +}; - -/** - * usb_skel_init - */ static int __init usb_skel_init(void) { int result; /* register this driver with the USB subsystem */ result = usb_register(&skel_driver); - if (result) { - err("usb_register failed. Error number %d", - result); - return result; - } + if (result) + err("usb_register failed. Error number %d", result); - info(DRIVER_DESC " " DRIVER_VERSION); - return 0; + return result; } - -/** - * usb_skel_exit - */ static void __exit usb_skel_exit(void) { /* deregister this driver with the USB subsystem */ usb_deregister(&skel_driver); } - module_init (usb_skel_init); module_exit (usb_skel_exit); -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); diff -Nru a/fs/namei.c b/fs/namei.c --- a/fs/namei.c 2004-08-04 17:58:03 -07:00 +++ b/fs/namei.c 2004-08-04 17:58:03 -07:00 @@ -1659,7 +1659,7 @@ * if it cannot handle the case of removing a directory * that is still in use by something else.. */ -static void d_unhash(struct dentry *dentry) +void dentry_unhash(struct dentry *dentry) { dget(dentry); spin_lock(&dcache_lock); @@ -1689,7 +1689,7 @@ DQUOT_INIT(dir); down(&dentry->d_inode->i_sem); - d_unhash(dentry); + dentry_unhash(dentry); if (d_mountpoint(dentry)) error = -EBUSY; else { @@ -2032,7 +2032,7 @@ target = new_dentry->d_inode; if (target) { down(&target->i_sem); - d_unhash(new_dentry); + dentry_unhash(new_dentry); } if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry)) error = -EBUSY; @@ -2410,4 +2410,5 @@ EXPORT_SYMBOL(vfs_rmdir); EXPORT_SYMBOL(vfs_symlink); EXPORT_SYMBOL(vfs_unlink); +EXPORT_SYMBOL(dentry_unhash); EXPORT_SYMBOL(generic_readlink); diff -Nru a/include/linux/fs.h b/include/linux/fs.h --- a/include/linux/fs.h 2004-08-04 17:58:03 -07:00 +++ b/include/linux/fs.h 2004-08-04 17:58:03 -07:00 @@ -809,6 +809,11 @@ extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); /* + * VFS dentry helper functions. + */ +extern void dentry_unhash(struct dentry *dentry); + +/* * File types * * NOTE! These match bits 12..15 of stat.st_mode