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