Hi,
On Thu, Dec 19, 2002 at 04:52:55PM -0800, Greg KH wrote:
> On Fri, Dec 20, 2002 at 01:45:16AM +0100, Oliver Neukum wrote:
> > This patch is wrong. Please do not apply.
>
> I agree. It tries to do several different things, and doesn't really
> seem to make much sense as to why it is trying to do them :(
Sorry for that. I only head a quick look at it before forwarding it.
I'll check other peoples patches more thoroughly in future.
> Henning, you might want to just split the logic of the reference
> counting logic out into a single patch, and work from there.
As I didn't really understand what Sergey wanted to do I started from
scratch using ideas from usb-skeleton.c. There are still some locking
issues in ioctl_scanner and read_scanner keeps trying to read until
timeout, if the device was disconnected in the middle of a read. But
as the issues are not directly realted, I'll check the later. The
patch works for me, that means: the module usage count is 0 even if an
opened device is disconnected and there is no kerenel crash any more
if someone writes to/reads from a disconnected device.
So what about this (on top of the interface and altsetting patches
from today):
[PATCH 2.4.21-pre1] scanner.c: fix for disconnect while open
Decrease module usage count even if device was disconnected while
open. Check if disconnected before read, write, and ioctl.
--- linux-2.4.21-pre1.altsetting/drivers/usb/scanner.c 2002-12-22 12:06:52.000000000
+0100
+++ linux-2.4.21-pre1.present/drivers/usb/scanner.c 2002-12-22 19:34:13.000000000
++0100
@@ -327,6 +327,8 @@
* - Accept devices with more than one interface. Only use interfaces that
* look like belonging to scanners.
* - Use altsetting[0], not altsetting[ifnum].
+ * - Decrease module usage count even if device was disconnected while open.
+ * Check if disconnected before read, write, and ioctl.
*
* TODO
* - Remove the 2/3 endpoint limitation
@@ -366,6 +368,17 @@
*/
#include "scanner.h"
+static inline void
+delete_scanner (struct scn_usb_data *scn)
+{
+ p_scn_table[scn->scn_minor] = NULL;
+ if (scn->ibuf != NULL)
+ kfree(scn->ibuf);
+ if (scn->obuf != NULL)
+ kfree(scn->obuf);
+ kfree (scn);
+}
+
static void
irq_scanner(struct urb *urb)
{
@@ -470,21 +483,27 @@
dbg("close_scanner: scn_minor:%d", scn_minor);
+ down(&scn_mutex);
if (!p_scn_table[scn_minor]) {
err("close_scanner(%d): invalid scn_minor", scn_minor);
+ up(&scn_mutex);
return -ENODEV;
}
- down(&scn_mutex);
-
scn = p_scn_table[scn_minor];
down(&(scn->sem));
scn->isopen = 0;
file->private_data = NULL;
+ if (!scn->present) {
+ up(&(scn->sem));
+ delete_scanner (scn);
+ } else {
+ up(&(scn->sem));
+ }
+
up(&scn_mutex);
- up(&(scn->sem));
MOD_DEC_USE_COUNT;
@@ -513,14 +532,20 @@
down(&(scn->sem));
+ scn_minor = scn->scn_minor;
+
+ if (!scn->present) {
+ err("write_scanner(%d): Scanner is not present", scn_minor);
+ up(&(scn->sem));
+ return -ENODEV;
+ }
+
if (!scn->bulk_out_ep) {
/* This scanner does not have a bulk-out endpoint */
up(&(scn->sem));
return -EINVAL;
}
- scn_minor = scn->scn_minor;
-
obuf = scn->obuf;
dev = scn->scn_dev;
@@ -609,6 +634,12 @@
scn_minor = scn->scn_minor;
+ if (!scn->present) {
+ err("read_scanner(%d): Scanner is not present", scn_minor);
+ up(&(scn->sem));
+ return -ENODEV;
+ }
+
ibuf = scn->ibuf;
dev = scn->scn_dev;
@@ -718,6 +749,11 @@
return -ENODEV;
}
+ if (!p_scn_table[scn_minor]->present) {
+ err("ioctl_scanner(%d): Scanner is not present", scn_minor);
+ return -ENODEV;
+ }
+
dev = p_scn_table[scn_minor]->scn_dev;
switch (cmd)
@@ -1121,14 +1157,16 @@
usb_driver_release_interface(&scanner_driver,
&scn->scn_dev->actconfig->interface[scn->ifnum]);
- kfree(scn->ibuf);
- kfree(scn->obuf);
-
dbg("disconnect_scanner: De-allocating minor:%d", scn->scn_minor);
devfs_unregister(scn->devfs);
- p_scn_table[scn->scn_minor] = NULL;
- up (&(scn->sem));
- kfree (scn);
+
+ if (scn->isopen) {
+ scn->present = 0;
+ up (&(scn->sem));
+ } else {
+ up (&(scn->sem));
+ delete_scanner (scn);
+ }
up (&scn_mutex);
}
-------------------------------------------------------
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