Commit d4e0ae31 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge kroah.com:/home/greg/linux/BK/bleed-2.5

into kroah.com:/home/greg/linux/BK/gregkh-2.5
parents d210257e 7ea5b864
...@@ -330,7 +330,7 @@ static int usblp_open(struct inode *inode, struct file *file) ...@@ -330,7 +330,7 @@ static int usblp_open(struct inode *inode, struct file *file)
lock_kernel(); lock_kernel();
retval = -ENODEV; retval = -ENODEV;
intf = usb_find_interface(&usblp_driver, mk_kdev(USB_MAJOR,minor)); intf = usb_find_interface(&usblp_driver, minor);
if (!intf) { if (!intf) {
goto out; goto out;
} }
...@@ -920,9 +920,7 @@ static int usblp_probe(struct usb_interface *intf, ...@@ -920,9 +920,7 @@ static int usblp_probe(struct usb_interface *intf,
usblp->dev->descriptor.idProduct); usblp->dev->descriptor.idProduct);
usb_set_intfdata (intf, usblp); usb_set_intfdata (intf, usblp);
intf->minor = usblp->minor;
/* add device id so the device works when advertised */
intf->kdev = mk_kdev(USB_MAJOR,usblp->minor);
return 0; return 0;
...@@ -1109,7 +1107,7 @@ static void usblp_disconnect(struct usb_interface *intf) ...@@ -1109,7 +1107,7 @@ static void usblp_disconnect(struct usb_interface *intf)
struct usblp *usblp = usb_get_intfdata (intf); struct usblp *usblp = usb_get_intfdata (intf);
/* remove device id to disable open() */ /* remove device id to disable open() */
intf->kdev = NODEV; intf->minor = -1;
if (!usblp || !usblp->dev) { if (!usblp || !usblp->dev) {
err("bogus disconnect"); err("bogus disconnect");
......
...@@ -457,12 +457,13 @@ usb_match_id(struct usb_interface *interface, const struct usb_device_id *id) ...@@ -457,12 +457,13 @@ usb_match_id(struct usb_interface *interface, const struct usb_device_id *id)
/** /**
* usb_find_interface - find usb_interface pointer for driver and device * usb_find_interface - find usb_interface pointer for driver and device
* @drv: the driver whose current configuration is considered * @drv: the driver whose current configuration is considered
* @kdev: the desired device * @minor: the minor number of the desired device
* *
* This walks the driver device list and returns a pointer to the interface * This walks the driver device list and returns a pointer to the interface
* with the matching kdev_t. * with the matching minor. Note, this only works for devices that share the
* USB major number.
*/ */
struct usb_interface *usb_find_interface(struct usb_driver *drv, kdev_t kdev) struct usb_interface *usb_find_interface(struct usb_driver *drv, int minor)
{ {
struct list_head *entry; struct list_head *entry;
struct device *dev; struct device *dev;
...@@ -476,9 +477,10 @@ struct usb_interface *usb_find_interface(struct usb_driver *drv, kdev_t kdev) ...@@ -476,9 +477,10 @@ struct usb_interface *usb_find_interface(struct usb_driver *drv, kdev_t kdev)
continue; continue;
intf = to_usb_interface(dev); intf = to_usb_interface(dev);
if (kdev_same(intf->kdev,kdev)) { if (intf->minor == -1)
continue;
if (intf->minor == minor)
return intf; return intf;
}
} }
/* no device found that matches */ /* no device found that matches */
......
...@@ -116,8 +116,10 @@ static const char hcd_name [] = "ehci-hcd"; ...@@ -116,8 +116,10 @@ static const char hcd_name [] = "ehci-hcd";
#define EHCI_TUNE_MULT_TT 1 #define EHCI_TUNE_MULT_TT 1
#define EHCI_TUNE_FLS 2 /* (small) 256 frame schedule */ #define EHCI_TUNE_FLS 2 /* (small) 256 frame schedule */
#define EHCI_WATCHDOG_JIFFIES (HZ/100) /* arbitrary; ~10 msec */ #define EHCI_IAA_JIFFIES (HZ/100) /* arbitrary; ~10 msec */
#define EHCI_IO_JIFFIES (HZ/10) /* io watchdog > irq_thresh */
#define EHCI_ASYNC_JIFFIES (HZ/20) /* async idle timeout */ #define EHCI_ASYNC_JIFFIES (HZ/20) /* async idle timeout */
#define EHCI_SHRINK_JIFFIES (HZ/200) /* async qh unlink delay */
/* Initial IRQ latency: lower than default */ /* Initial IRQ latency: lower than default */
static int log2_irq_thresh = 0; // 0 to 6 static int log2_irq_thresh = 0; // 0 to 6
...@@ -266,16 +268,13 @@ static void ehci_watchdog (unsigned long param) ...@@ -266,16 +268,13 @@ static void ehci_watchdog (unsigned long param)
} }
} }
/* stop async processing after it's idled a bit */
if (test_bit (TIMER_ASYNC_OFF, &ehci->actions))
start_unlink_async (ehci, ehci->async);
/* ehci could run by timer, without IRQs ... */
ehci_work (ehci, NULL); ehci_work (ehci, NULL);
if (ehci->reclaim && !timer_pending (&ehci->watchdog))
mod_timer (&ehci->watchdog,
jiffies + EHCI_WATCHDOG_JIFFIES);
/* stop async processing after it's idled a while */
else if (ehci->async_idle) {
start_unlink_async (ehci, ehci->async);
ehci->async_idle = 0;
}
spin_unlock_irqrestore (&ehci->lock, flags); spin_unlock_irqrestore (&ehci->lock, flags);
} }
...@@ -658,11 +657,18 @@ static int ehci_resume (struct usb_hcd *hcd) ...@@ -658,11 +657,18 @@ static int ehci_resume (struct usb_hcd *hcd)
*/ */
static void ehci_work (struct ehci_hcd *ehci, struct pt_regs *regs) static void ehci_work (struct ehci_hcd *ehci, struct pt_regs *regs)
{ {
timer_action_done (ehci, TIMER_IO_WATCHDOG);
if (ehci->reclaim_ready) if (ehci->reclaim_ready)
end_unlink_async (ehci, regs); end_unlink_async (ehci, regs);
scan_async (ehci, regs); scan_async (ehci, regs);
if (ehci->next_uframe != -1) if (ehci->next_uframe != -1)
scan_periodic (ehci, regs); scan_periodic (ehci, regs);
/* the IO watchdog guards against hardware or driver bugs that
* misplace IRQs, and should let us run completely without IRQs.
*/
if ((ehci->async->qh_next.ptr != 0) || (ehci->periodic_sched != 0))
timer_action (ehci, TIMER_IO_WATCHDOG);
} }
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
......
...@@ -706,8 +706,7 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh) ...@@ -706,8 +706,7 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
/* (re)start the async schedule? */ /* (re)start the async schedule? */
head = ehci->async; head = ehci->async;
if (ehci->async_idle) timer_action_done (ehci, TIMER_ASYNC_OFF);
del_timer (&ehci->watchdog);
if (!head->qh_next.qh) { if (!head->qh_next.qh) {
u32 cmd = readl (&ehci->regs->command); u32 cmd = readl (&ehci->regs->command);
...@@ -733,8 +732,6 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh) ...@@ -733,8 +732,6 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
qh->qh_state = QH_STATE_LINKED; qh->qh_state = QH_STATE_LINKED;
/* qtd completions reported later by interrupt */ /* qtd completions reported later by interrupt */
ehci->async_idle = 0;
} }
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
...@@ -915,7 +912,7 @@ static void end_unlink_async (struct ehci_hcd *ehci, struct pt_regs *regs) ...@@ -915,7 +912,7 @@ static void end_unlink_async (struct ehci_hcd *ehci, struct pt_regs *regs)
struct ehci_qh *qh = ehci->reclaim; struct ehci_qh *qh = ehci->reclaim;
struct ehci_qh *next; struct ehci_qh *next;
del_timer (&ehci->watchdog); timer_action_done (ehci, TIMER_IAA_WATCHDOG);
// qh->hw_next = cpu_to_le32 (qh->qh_dma); // qh->hw_next = cpu_to_le32 (qh->qh_dma);
qh->qh_state = QH_STATE_IDLE; qh->qh_state = QH_STATE_IDLE;
...@@ -940,12 +937,8 @@ static void end_unlink_async (struct ehci_hcd *ehci, struct pt_regs *regs) ...@@ -940,12 +937,8 @@ static void end_unlink_async (struct ehci_hcd *ehci, struct pt_regs *regs)
* active but idle for a while once it empties. * active but idle for a while once it empties.
*/ */
if (HCD_IS_RUNNING (ehci->hcd.state) if (HCD_IS_RUNNING (ehci->hcd.state)
&& ehci->async->qh_next.qh == 0 && ehci->async->qh_next.qh == 0)
&& !timer_pending (&ehci->watchdog)) { timer_action (ehci, TIMER_ASYNC_OFF);
ehci->async_idle = 1;
mod_timer (&ehci->watchdog,
jiffies + EHCI_ASYNC_JIFFIES);
}
} }
if (next) if (next)
...@@ -980,6 +973,7 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) ...@@ -980,6 +973,7 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
wmb (); wmb ();
// handshake later, if we need to // handshake later, if we need to
} }
timer_action_done (ehci, TIMER_ASYNC_OFF);
return; return;
} }
...@@ -1005,9 +999,8 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) ...@@ -1005,9 +999,8 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
ehci->reclaim_ready = 0; ehci->reclaim_ready = 0;
cmd |= CMD_IAAD; cmd |= CMD_IAAD;
writel (cmd, &ehci->regs->command); writel (cmd, &ehci->regs->command);
/* posted write need not be known to HC yet ... */ (void) readl (&ehci->regs->command);
timer_action (ehci, TIMER_IAA_WATCHDOG);
mod_timer (&ehci->watchdog, jiffies + EHCI_WATCHDOG_JIFFIES);
} }
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
...@@ -1016,10 +1009,11 @@ static void ...@@ -1016,10 +1009,11 @@ static void
scan_async (struct ehci_hcd *ehci, struct pt_regs *regs) scan_async (struct ehci_hcd *ehci, struct pt_regs *regs)
{ {
struct ehci_qh *qh; struct ehci_qh *qh;
int unlink_delay = 0; enum ehci_timer_action action = TIMER_IO_WATCHDOG;
if (!++(ehci->stamp)) if (!++(ehci->stamp))
ehci->stamp++; ehci->stamp++;
timer_action_done (ehci, TIMER_ASYNC_SHRINK);
rescan: rescan:
qh = ehci->async->qh_next.qh; qh = ehci->async->qh_next.qh;
if (likely (qh != 0)) { if (likely (qh != 0)) {
...@@ -1051,17 +1045,14 @@ scan_async (struct ehci_hcd *ehci, struct pt_regs *regs) ...@@ -1051,17 +1045,14 @@ scan_async (struct ehci_hcd *ehci, struct pt_regs *regs)
*/ */
if (list_empty (&qh->qtd_list)) { if (list_empty (&qh->qtd_list)) {
if (qh->stamp == ehci->stamp) if (qh->stamp == ehci->stamp)
unlink_delay = 1; action = TIMER_ASYNC_SHRINK;
else if (!ehci->reclaim) { else if (!ehci->reclaim)
start_unlink_async (ehci, qh); start_unlink_async (ehci, qh);
unlink_delay = 0;
}
} }
qh = qh->qh_next.qh; qh = qh->qh_next.qh;
} while (qh); } while (qh);
} }
if (action == TIMER_ASYNC_SHRINK)
if (unlink_delay && !timer_pending (&ehci->watchdog)) timer_action (ehci, TIMER_ASYNC_SHRINK);
mod_timer (&ehci->watchdog, jiffies + EHCI_WATCHDOG_JIFFIES/2);
} }
...@@ -52,8 +52,7 @@ struct ehci_hcd { /* one per controller */ ...@@ -52,8 +52,7 @@ struct ehci_hcd { /* one per controller */
/* async schedule support */ /* async schedule support */
struct ehci_qh *async; struct ehci_qh *async;
struct ehci_qh *reclaim; struct ehci_qh *reclaim;
int reclaim_ready : 1, int reclaim_ready : 1;
async_idle : 1;
/* periodic schedule support */ /* periodic schedule support */
#define DEFAULT_I_TDPS 1024 /* some HCs can do less */ #define DEFAULT_I_TDPS 1024 /* some HCs can do less */
...@@ -83,6 +82,7 @@ struct ehci_hcd { /* one per controller */ ...@@ -83,6 +82,7 @@ struct ehci_hcd { /* one per controller */
struct timer_list watchdog; struct timer_list watchdog;
struct notifier_block reboot_notifier; struct notifier_block reboot_notifier;
unsigned long actions;
unsigned stamp; unsigned stamp;
/* irq statistics */ /* irq statistics */
...@@ -100,6 +100,53 @@ struct ehci_hcd { /* one per controller */ ...@@ -100,6 +100,53 @@ struct ehci_hcd { /* one per controller */
/* NOTE: urb->transfer_flags expected to not use this bit !!! */ /* NOTE: urb->transfer_flags expected to not use this bit !!! */
#define EHCI_STATE_UNLINK 0x8000 /* urb being unlinked */ #define EHCI_STATE_UNLINK 0x8000 /* urb being unlinked */
enum ehci_timer_action {
TIMER_IO_WATCHDOG,
TIMER_IAA_WATCHDOG,
TIMER_ASYNC_SHRINK,
TIMER_ASYNC_OFF,
};
static inline void
timer_action_done (struct ehci_hcd *ehci, enum ehci_timer_action action)
{
clear_bit (action, &ehci->actions);
}
static inline void
timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action)
{
if (!test_and_set_bit (action, &ehci->actions)) {
unsigned long t;
switch (action) {
case TIMER_IAA_WATCHDOG:
t = EHCI_IAA_JIFFIES;
break;
case TIMER_IO_WATCHDOG:
t = EHCI_IO_JIFFIES;
break;
case TIMER_ASYNC_OFF:
t = EHCI_ASYNC_JIFFIES;
break;
// case TIMER_ASYNC_SHRINK:
default:
t = EHCI_SHRINK_JIFFIES;
break;
}
t += jiffies;
// all timings except IAA watchdog can be overridden.
// async queue SHRINK often precedes IAA. while it's ready
// to go OFF neither can matter, and afterwards the IO
// watchdog stops unless there's still periodic traffic.
if (action != TIMER_IAA_WATCHDOG
&& t > ehci->watchdog.expires
&& timer_pending (&ehci->watchdog))
return;
mod_timer (&ehci->watchdog, t);
}
}
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
/* EHCI register interface, corresponds to EHCI Revision 0.95 specification */ /* EHCI register interface, corresponds to EHCI Revision 0.95 specification */
......
...@@ -464,7 +464,7 @@ open_scanner(struct inode * inode, struct file * file) ...@@ -464,7 +464,7 @@ open_scanner(struct inode * inode, struct file * file)
dbg("open_scanner: scn_minor:%d", scn_minor); dbg("open_scanner: scn_minor:%d", scn_minor);
intf = usb_find_interface(&scanner_driver, mk_kdev(USB_MAJOR,scn_minor)); intf = usb_find_interface(&scanner_driver, scn_minor);
if (!intf) { if (!intf) {
up(&scn_mutex); up(&scn_mutex);
err("open_scanner(%d): Unable to access minor data", scn_minor); err("open_scanner(%d): Unable to access minor data", scn_minor);
...@@ -1118,9 +1118,7 @@ probe_scanner(struct usb_interface *intf, ...@@ -1118,9 +1118,7 @@ probe_scanner(struct usb_interface *intf,
up(&scn_mutex); up(&scn_mutex);
usb_set_intfdata(intf, scn); usb_set_intfdata(intf, scn);
intf->minor = scn_minor;
/* add device id so the device works when advertised */
intf->kdev = mk_kdev(USB_MAJOR,scn->scn_minor);
return 0; return 0;
} }
...@@ -1130,8 +1128,8 @@ disconnect_scanner(struct usb_interface *intf) ...@@ -1130,8 +1128,8 @@ disconnect_scanner(struct usb_interface *intf)
{ {
struct scn_usb_data *scn = usb_get_intfdata(intf); struct scn_usb_data *scn = usb_get_intfdata(intf);
/* remove device id to disable open() */ /* disable open() */
intf->kdev = NODEV; intf->minor = -1;
usb_set_intfdata(intf, NULL); usb_set_intfdata(intf, NULL);
if(scn->intr_ep) { if(scn->intr_ep) {
......
...@@ -324,10 +324,8 @@ MODULE_DEVICE_TABLE (usb, scanner_device_ids); ...@@ -324,10 +324,8 @@ MODULE_DEVICE_TABLE (usb, scanner_device_ids);
#define SCN_CLASS_SCANJET 16 #define SCN_CLASS_SCANJET 16
#ifdef CONFIG_USB_DYNAMIC_MINORS #ifdef CONFIG_USB_DYNAMIC_MINORS
#define SCN_MAX_MNR 256
#define SCN_BASE_MNR 0 #define SCN_BASE_MNR 0
#else #else
#define SCN_MAX_MNR 16 /* We're allocated 16 minors */
#define SCN_BASE_MNR 48 /* USB Scanners start at minor 48 */ #define SCN_BASE_MNR 48 /* USB Scanners start at minor 48 */
#endif #endif
......
...@@ -1101,28 +1101,6 @@ static int vicam_read_proc_gain(char *page, char **start, off_t off, ...@@ -1101,28 +1101,6 @@ static int vicam_read_proc_gain(char *page, char **start, off_t off,
((struct vicam_camera *)data)->gain); ((struct vicam_camera *)data)->gain);
} }
static int vicam_write_proc_shutter(struct file *file, const char *buffer,
unsigned long count, void *data)
{
struct vicam_camera *cam = (struct vicam_camera *)data;
cam->shutter_speed = simple_strtoul(buffer, NULL, 10);
return count;
}
static int vicam_write_proc_gain(struct file *file, const char *buffer,
unsigned long count, void *data)
{
struct vicam_camera *cam = (struct vicam_camera *)data;
cam->gain = simple_strtoul(buffer, NULL, 10);
return count;
}
static void static void
vicam_create_proc_root(void) vicam_create_proc_root(void)
{ {
...@@ -1164,21 +1142,17 @@ vicam_create_proc_entry(struct vicam_camera *cam) ...@@ -1164,21 +1142,17 @@ vicam_create_proc_entry(struct vicam_camera *cam)
if ( !cam->proc_dir ) return; // We should probably return an error here if ( !cam->proc_dir ) return; // We should probably return an error here
ent = ent =
create_proc_entry("shutter", S_IFREG | S_IRUGO | S_IWUSR, create_proc_entry("shutter", S_IFREG | S_IRUGO, cam->proc_dir);
cam->proc_dir);
if (ent) { if (ent) {
ent->data = cam; ent->data = cam;
ent->read_proc = vicam_read_proc_shutter; ent->read_proc = vicam_read_proc_shutter;
ent->write_proc = vicam_write_proc_shutter;
ent->size = 64; ent->size = 64;
} }
ent = create_proc_entry("gain", S_IFREG | S_IRUGO | S_IWUSR, ent = create_proc_entry("gain", S_IFREG | S_IRUGO , cam->proc_dir);
cam->proc_dir);
if ( ent ) { if ( ent ) {
ent->data = cam; ent->data = cam;
ent->read_proc = vicam_read_proc_gain; ent->read_proc = vicam_read_proc_gain;
ent->write_proc = vicam_write_proc_gain;
ent->size = 64; ent->size = 64;
} }
} }
......
...@@ -74,6 +74,7 @@ ...@@ -74,6 +74,7 @@
#include <linux/atm.h> #include <linux/atm.h>
#include <linux/atmdev.h> #include <linux/atmdev.h>
#include <linux/crc32.h> #include <linux/crc32.h>
#include <linux/init.h>
/* /*
#define DEBUG 1 #define DEBUG 1
......
...@@ -160,7 +160,7 @@ static void ctrl_callback(struct urb *urb, struct pt_regs *regs) ...@@ -160,7 +160,7 @@ static void ctrl_callback(struct urb *urb, struct pt_regs *regs)
clear_bit(RX_REG_SET, &dev->flags); clear_bit(RX_REG_SET, &dev->flags);
} }
static int async_set_registers(rtl8150_t * dev, u16 indx, u16 size, void *data) static int async_set_registers(rtl8150_t * dev, u16 indx, u16 size)
{ {
int ret; int ret;
...@@ -537,7 +537,8 @@ static int enable_net_traffic(rtl8150_t * dev) ...@@ -537,7 +537,8 @@ static int enable_net_traffic(rtl8150_t * dev)
warn("%s - device reset failed", __FUNCTION__); warn("%s - device reset failed", __FUNCTION__);
} }
/* RCR bit7=1 attach Rx info at the end; =0 HW CRC (which is broken) */ /* RCR bit7=1 attach Rx info at the end; =0 HW CRC (which is broken) */
dev->rx_creg = rcr = 0x9e; rcr = 0x9e; /* bit7=1 attach Rx info at the end */
dev->rx_creg = cpu_to_le16(rcr);
tcr = 0xd8; tcr = 0xd8;
cr = 0x0c; cr = 0x0c;
if (!(rcr & 0x80)) if (!(rcr & 0x80))
...@@ -584,18 +585,18 @@ static void rtl8150_set_multicast(struct net_device *netdev) ...@@ -584,18 +585,18 @@ static void rtl8150_set_multicast(struct net_device *netdev)
dev = netdev->priv; dev = netdev->priv;
netif_stop_queue(netdev); netif_stop_queue(netdev);
if (netdev->flags & IFF_PROMISC) { if (netdev->flags & IFF_PROMISC) {
dev->rx_creg |= 0x0001; dev->rx_creg |= cpu_to_le16(0x0001);
info("%s: promiscuous mode", netdev->name); info("%s: promiscuous mode", netdev->name);
} else if ((netdev->mc_count > multicast_filter_limit) || } else if ((netdev->mc_count > multicast_filter_limit) ||
(netdev->flags & IFF_ALLMULTI)) { (netdev->flags & IFF_ALLMULTI)) {
dev->rx_creg &= 0xfffe; dev->rx_creg &= cpu_to_le16(0xfffe);
dev->rx_creg |= 0x0002; dev->rx_creg |= cpu_to_le16(0x0002);
info("%s: allmulti set", netdev->name); info("%s: allmulti set", netdev->name);
} else { } else {
/* ~RX_MULTICAST, ~RX_PROMISCUOUS */ /* ~RX_MULTICAST, ~RX_PROMISCUOUS */
dev->rx_creg &= 0x00fc; dev->rx_creg &= cpu_to_le16(0x00fc);
} }
async_set_registers(dev, RCR, 2, &dev->rx_creg); async_set_registers(dev, RCR, 2);
netif_wake_queue(netdev); netif_wake_queue(netdev);
} }
......
...@@ -133,7 +133,7 @@ static int __init usb_console_setup(struct console *co, char *options) ...@@ -133,7 +133,7 @@ static int __init usb_console_setup(struct console *co, char *options)
co->cflag = cflag; co->cflag = cflag;
/* grab the first serial port that happens to be connected */ /* grab the first serial port that happens to be connected */
serial = usb_serial_get_by_minor (0); serial = usb_serial_get_by_index(0);
if (serial_paranoia_check (serial, __FUNCTION__)) { if (serial_paranoia_check (serial, __FUNCTION__)) {
/* no device is connected yet, sorry :( */ /* no device is connected yet, sorry :( */
err ("No USB device connected to ttyUSB0"); err ("No USB device connected to ttyUSB0");
......
...@@ -280,7 +280,7 @@ static inline void usb_serial_console_exit (void) { } ...@@ -280,7 +280,7 @@ static inline void usb_serial_console_exit (void) { }
#endif #endif
/* Functions needed by other parts of the usbserial core */ /* Functions needed by other parts of the usbserial core */
extern struct usb_serial *usb_serial_get_by_minor (unsigned int minor); extern struct usb_serial *usb_serial_get_by_index (unsigned int minor);
extern int usb_serial_generic_open (struct usb_serial_port *port, struct file *filp); extern int usb_serial_generic_open (struct usb_serial_port *port, struct file *filp);
extern int usb_serial_generic_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count); extern int usb_serial_generic_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count);
extern void usb_serial_generic_close (struct usb_serial_port *port, struct file *filp); extern void usb_serial_generic_close (struct usb_serial_port *port, struct file *filp);
......
...@@ -98,6 +98,18 @@ UNUSUAL_DEV( 0x0451, 0x5409, 0x0001, 0x0001, ...@@ -98,6 +98,18 @@ UNUSUAL_DEV( 0x0451, 0x5409, 0x0001, 0x0001,
"Nex II Digital", "Nex II Digital",
US_SC_SCSI, US_PR_BULK, NULL, US_FL_START_STOP), US_SC_SCSI, US_PR_BULK, NULL, US_FL_START_STOP),
/* Patch submitted by Philipp Friedrich <philipp@void.at> */
UNUSUAL_DEV( 0x0482, 0x0100, 0x0100, 0x0100,
"Kyocera",
"Finecam S3x",
US_SC_8070, US_PR_CB, NULL, US_FL_FIX_INQUIRY),
/* Patch submitted by Philipp Friedrich <philipp@void.at> */
UNUSUAL_DEV( 0x0482, 0x0101, 0x0100, 0x0100,
"Kyocera",
"Finecam S4",
US_SC_8070, US_PR_CB, NULL, US_FL_FIX_INQUIRY),
/* Reported by Paul Stewart <stewart@wetlogic.net> /* Reported by Paul Stewart <stewart@wetlogic.net>
* This entry is needed because the device reports Sub=ff */ * This entry is needed because the device reports Sub=ff */
UNUSUAL_DEV( 0x04a4, 0x0004, 0x0001, 0x0001, UNUSUAL_DEV( 0x04a4, 0x0004, 0x0001, 0x0001,
...@@ -237,14 +249,6 @@ UNUSUAL_DEV( 0x0525, 0xa140, 0x0100, 0x0100, ...@@ -237,14 +249,6 @@ UNUSUAL_DEV( 0x0525, 0xa140, 0x0100, 0x0100,
US_SC_8070, US_PR_BULK, NULL, US_SC_8070, US_PR_BULK, NULL,
US_FL_FIX_INQUIRY | US_FL_START_STOP ), US_FL_FIX_INQUIRY | US_FL_START_STOP ),
/* Submitted by Lars Gemeinhardt <linux-usb@gemeinhardt.info>
* Needed for START_STOP flag */
UNUSUAL_DEV( 0x0547, 0x2810, 0x0001, 0x0001,
"Mello",
"MP3 Player",
US_SC_SCSI, US_PR_BULK, NULL,
US_FL_START_STOP),
/* This entry is needed because the device reports Sub=ff */ /* This entry is needed because the device reports Sub=ff */
UNUSUAL_DEV( 0x054c, 0x0010, 0x0106, 0x0450, UNUSUAL_DEV( 0x054c, 0x0010, 0x0106, 0x0450,
"Sony", "Sony",
...@@ -626,6 +630,26 @@ UNUSUAL_DEV( 0x1065, 0x2136, 0x0000, 0x0001, ...@@ -626,6 +630,26 @@ UNUSUAL_DEV( 0x1065, 0x2136, 0x0000, 0x0001,
US_SC_SCSI, US_PR_BULK, NULL, US_SC_SCSI, US_PR_BULK, NULL,
US_FL_MODE_XLATE | US_FL_START_STOP | US_FL_FIX_INQUIRY ), US_FL_MODE_XLATE | US_FL_START_STOP | US_FL_FIX_INQUIRY ),
/* This Pentax still camera is not conformant
* to the USB storage specification: -
* - It does not like the INQUIRY command. So we must handle this command
* of the SCSI layer ourselves.
* Tested on Rev. 10.00 (0x1000)
* Submitted by James Courtier-Dutton <James@superbug.demon.co.uk>
*/
UNUSUAL_DEV( 0x0a17, 0x0004, 0x1000, 0x1000,
"Pentax",
"Optio 2/3/400",
US_SC_8070, US_PR_CBI, NULL,
US_FL_FIX_INQUIRY ),
/* Submitted by Per Winkvist <per.winkvist@uk.com> */
UNUSUAL_DEV( 0x0a17, 0x006, 0x1000, 0x9009,
"Pentax",
"Optio S",
US_SC_8070, US_PR_CBI, NULL,
US_FL_FIX_INQUIRY ),
/* Submitted by Brian Hall <brihall@pcisys.net> /* Submitted by Brian Hall <brihall@pcisys.net>
* Needed for START_STOP flag */ * Needed for START_STOP flag */
UNUSUAL_DEV( 0x0c76, 0x0003, 0x0100, 0x0100, UNUSUAL_DEV( 0x0c76, 0x0003, 0x0100, 0x0100,
......
...@@ -87,12 +87,8 @@ static struct usb_device_id skel_table [] = { ...@@ -87,12 +87,8 @@ static struct usb_device_id skel_table [] = {
MODULE_DEVICE_TABLE (usb, skel_table); MODULE_DEVICE_TABLE (usb, skel_table);
#ifdef CONFIG_USB_DYNAMIC_MINORS
#define USB_SKEL_MINOR_BASE 0
#else
/* Get a minor range for your devices from the usb maintainer */ /* Get a minor range for your devices from the usb maintainer */
#define USB_SKEL_MINOR_BASE 192 #define USB_SKEL_MINOR_BASE 192
#endif
/* Structure to hold all of our device specific stuff */ /* Structure to hold all of our device specific stuff */
struct usb_skel { struct usb_skel {
...@@ -153,16 +149,6 @@ static struct file_operations skel_fops = { ...@@ -153,16 +149,6 @@ static struct file_operations skel_fops = {
* This also means that the kernel can decrement * This also means that the kernel can decrement
* the use-counter again before calling release() * the use-counter again before calling release()
* or should the open() function fail. * or should the open() function fail.
*
* Not all device structures have an "owner" field
* yet. "struct file_operations" and "struct net_device"
* do, while "struct tty_driver" does not. If the struct
* has an "owner" field, then initialize it to the value
* THIS_MODULE and the kernel will handle all module
* locking for you automatically. Otherwise, you must
* increment the use-counter in the open() function
* and decrement it again in the release() function
* yourself.
*/ */
.owner = THIS_MODULE, .owner = THIS_MODULE,
...@@ -236,8 +222,7 @@ static int skel_open (struct inode *inode, struct file *file) ...@@ -236,8 +222,7 @@ static int skel_open (struct inode *inode, struct file *file)
/* prevent disconnects */ /* prevent disconnects */
down (&disconnect_sem); down (&disconnect_sem);
interface = usb_find_interface (&skel_driver, interface = usb_find_interface (&skel_driver, subminor);
mk_kdev(USB_MAJOR, subminor));
if (!interface) { if (!interface) {
err ("%s - error, can't find device for minor %d", err ("%s - error, can't find device for minor %d",
__FUNCTION__, subminor); __FUNCTION__, subminor);
...@@ -619,8 +604,8 @@ static int skel_probe(struct usb_interface *interface, const struct usb_device_i ...@@ -619,8 +604,8 @@ static int skel_probe(struct usb_interface *interface, const struct usb_device_i
/* let the user know what node this device is now attached to */ /* 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", dev->minor);
/* add device id so the device works when advertised */ /* set the minor of the interface, so open() works */
interface->kdev = mk_kdev(USB_MAJOR, dev->minor); interface->minor = dev->minor;
goto exit; goto exit;
...@@ -667,8 +652,8 @@ static void skel_disconnect(struct usb_interface *interface) ...@@ -667,8 +652,8 @@ static void skel_disconnect(struct usb_interface *interface)
down (&dev->sem); down (&dev->sem);
/* remove device id to disable open() */ /* disable open() */
interface->kdev = NODEV; interface->minor = -1;
minor = dev->minor; minor = dev->minor;
......
...@@ -73,12 +73,20 @@ struct usb_host_interface { ...@@ -73,12 +73,20 @@ struct usb_host_interface {
/** /**
* struct usb_interface - what usb device drivers talk to * struct usb_interface - what usb device drivers talk to
* @altsetting: array of interface descriptors, one for each alternate * @altsetting: array of interface descriptors, one for each alternate
* setting that may be selected. each one includes a set of * setting that may be selected. Each one includes a set of
* endpoint configurations. * endpoint configurations and will be in numberic order,
* 0..num_altsetting.
* @num_altsetting: number of altsettings defined. * @num_altsetting: number of altsettings defined.
* @act_altsetting: index of current altsetting. this number is always * @act_altsetting: index of current altsetting. this number is always
* less than num_altsetting. after the device is configured, each * less than num_altsetting. after the device is configured, each
* interface uses its default setting of zero. * interface uses its default setting of zero.
* @max_altsetting:
* @minor: the minor number assigned to this interface, if this
* interface is bound to a driver that uses the USB major number.
* If this interface does not use the USB major, this field should
* be unused. The driver should set this value in the probe()
* function of the driver, after it has been assigned a minor
* number from the USB core by calling usb_register_dev().
* @dev: driver model's view of this device * @dev: driver model's view of this device
* *
* USB device drivers attach to interfaces on a physical device. Each * USB device drivers attach to interfaces on a physical device. Each
...@@ -111,7 +119,7 @@ struct usb_interface { ...@@ -111,7 +119,7 @@ struct usb_interface {
unsigned max_altsetting; /* total memory allocated */ unsigned max_altsetting; /* total memory allocated */
struct usb_driver *driver; /* driver */ struct usb_driver *driver; /* driver */
kdev_t kdev; /* node this interface is bound to */ int minor; /* minor number this interface is bound to */
struct device dev; /* interface specific device info */ struct device dev; /* interface specific device info */
}; };
#define to_usb_interface(d) container_of(d, struct usb_interface, dev) #define to_usb_interface(d) container_of(d, struct usb_interface, dev)
...@@ -279,7 +287,7 @@ extern void usb_driver_release_interface(struct usb_driver *driver, ...@@ -279,7 +287,7 @@ extern void usb_driver_release_interface(struct usb_driver *driver,
const struct usb_device_id *usb_match_id(struct usb_interface *interface, const struct usb_device_id *usb_match_id(struct usb_interface *interface,
const struct usb_device_id *id); const struct usb_device_id *id);
extern struct usb_interface *usb_find_interface(struct usb_driver *drv, kdev_t kdev); extern struct usb_interface *usb_find_interface(struct usb_driver *drv, int minor);
extern struct usb_interface *usb_ifnum_to_if(struct usb_device *dev, unsigned ifnum); extern struct usb_interface *usb_ifnum_to_if(struct usb_device *dev, unsigned ifnum);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment