On Sun, 13 Oct 2002 13:36:22 +0300 Kari Hameenaho <[EMAIL PROTECTED]> wrote:
> > It seems to be some kind of problem with the minor sometimes used > starting from 0 and sometimes from SCN_BASE_MNR. The driver in > 2.4.20-pre10 works, maybe comparing to that helps you. > Maybe this patch looks better: added functions for minor to index mapping and read access for p_scn_table. Still the minor to index conversion is maybe wrong for dynamic minors. --- Kari Hämeenaho --- linux-2.5.42/drivers/usb/image/scanner.h Sat Oct 12 07:21:42 2002 +++ linux-2.5.42-kjh/drivers/usb/image/scanner.h Sat Oct 12 13:10:35 2002 @@ -216,7 +216,7 @@ #define IS_EP_BULK_OUT(ep) (IS_EP_BULK(ep) && ((ep).bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) #define IS_EP_INTR(ep) ((ep).bmAttributes == USB_ENDPOINT_XFER_INT ? 1 : 0) -#define USB_SCN_MINOR(X) minor((X)->i_rdev) - SCN_BASE_MNR +#define USB_SCN_MINOR(X) minor((X)->i_rdev) #ifdef DEBUG #define SCN_DEBUG(X) X --- linux-2.5.42/drivers/usb/image/scanner.c Sat Oct 12 07:21:36 2002 +++ linux-2.5.42-kjh/drivers/usb/image/scanner.c Sun Oct 13 16:18:30 2002 @@ -353,6 +353,29 @@ */ #include "scanner.h" +static int +scn_minor_to_index(int scn_minor) +{ + if (scn_minor < SCN_BASE_MNR) { + return -1; + } + if (scn_minor >= SCN_BASE_MNR + SCN_MAX_MNR) { + return -1; + } + return scn_minor - SCN_BASE_MNR; + +} + +static struct scn_usb_data * +scn_usb_data_ptr(int scn_minor) +{ + int scn_index = scn_minor_to_index(scn_minor); + if (scn_index < 0) { + return NULL; + } + return p_scn_table[scn_index]; +} + static void irq_scanner(struct urb *urb) { @@ -396,15 +419,14 @@ dbg("open_scanner: scn_minor:%d", scn_minor); - if (!p_scn_table[scn_minor]) { + scn = scn_usb_data_ptr(scn_minor); + if (!scn) { up(&scn_mutex); MOD_DEC_USE_COUNT; err("open_scanner(%d): Unable to access minor data", scn_minor); return -ENODEV; } - scn = p_scn_table[scn_minor]; - dev = scn->scn_dev; down(&(scn->sem)); /* Now protect the scn_usb_data structure */ @@ -457,14 +479,14 @@ dbg("close_scanner: scn_minor:%d", scn_minor); - if (!p_scn_table[scn_minor]) { + scn = scn_usb_data_ptr(scn_minor); + if (!scn) { err("close_scanner(%d): invalid scn_minor", scn_minor); return -ENODEV; } down(&scn_mutex); - scn = p_scn_table[scn_minor]; down(&(scn->sem)); scn->isopen = 0; @@ -687,18 +709,20 @@ ioctl_scanner(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { + struct scn_usb_data *scn; struct usb_device *dev; int scn_minor; scn_minor = USB_SCN_MINOR(inode); - if (!p_scn_table[scn_minor]) { + scn = scn_usb_data_ptr(scn_minor); + if (!scn) { err("ioctl_scanner(%d): invalid scn_minor", scn_minor); return -ENODEV; } - dev = p_scn_table[scn_minor]->scn_dev; + dev = scn->scn_dev; switch (cmd) { @@ -830,6 +854,7 @@ int ep_cnt; int ix; int scn_minor; + int scn_index; int retval; char valid_device = 0; @@ -979,9 +1004,18 @@ return -ENOMEM; } -/* Check to make sure that the last slot isn't already taken */ - if (p_scn_table[scn_minor]) { - err("probe_scanner: No more minor devices remaining."); + scn_index = scn_minor_to_index(scn_minor); + if (scn_index < 0) { + err("probe_scanner: Illegal minor device."); + up(&scn_mutex); + return -ENOMEM; + } + + + /* Check to make sure that this slot isn't already taken */ + scn = scn_usb_data_ptr(scn_minor); + if (scn) { + err("probe_scanner: This minor reserved already."); up(&scn_mutex); return -ENOMEM; } @@ -1074,13 +1108,13 @@ scn->devfs = devfs_register(usb_devfs_handle, name, DEVFS_FL_DEFAULT, USB_MAJOR, - SCN_BASE_MNR + scn->scn_minor, + scn->scn_minor, S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, &usb_scanner_fops, NULL); if (scn->devfs == NULL) dbg("scanner%d: device node registration failed", scn_minor); - p_scn_table[scn_minor] = scn; + p_scn_table[scn_index] = scn; up(&scn_mutex); @@ -1092,6 +1126,7 @@ disconnect_scanner(struct usb_interface *intf) { struct scn_usb_data *scn = dev_get_drvdata(&intf->dev); + int scn_index; dev_set_drvdata(&intf->dev, NULL); if (scn) { @@ -1111,7 +1146,10 @@ dbg("disconnect_scanner: De-allocating minor:%d", scn->scn_minor); devfs_unregister(scn->devfs); usb_deregister_dev(1, scn->scn_minor); - p_scn_table[scn->scn_minor] = NULL; + scn_index = scn_minor_to_index(scn->scn_minor); + if (scn_index >= 0) { + p_scn_table[scn_index] = NULL; + } usb_free_urb(scn->scn_irq); up (&(scn->sem)); kfree (scn); ------------------------------------------------------- This sf.net email is sponsored by:ThinkGeek Welcome to geek heaven. http://thinkgeek.com/sf _______________________________________________ [EMAIL PROTECTED] To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel