My name is Shawn Campbell and I am creating a linux device driver for a
previously unsupported device.  The device is a magtek swipe reader that has
a single endpoint that uses the usb "interrupt in" transfer method.  I can
get data from my read method, but the driver crashes my system.  I am stuck
in a "change cascade" where I keep changing things around trying to
determine the problem.  Another pair of eyes would be great.  I am new to
kernel development and I could use some help.  I will include my source as
an attachment.  The source is based on the usb-skeleton driver from the
2.4.18 kernel source.  I will be using the device driver on a 2.4.x kernel
once in production use.  Any suggestions or observations about why the code
would hangup my system would be appreciated.  Am I using spinlocks or
semaphores incorrectly?  What about my use of wait_queues?  Am I forgetting
to protect a data structure with a spinlock or semaphore at a key point?  Am
I kfree()ing a data structure too early?  Is the location and usage of
usb_submit_urb and usb_unlink_urb ok?  I read somewhere that the
probe/disconnect routines should have most of the code of the open/release
routines.  Is that true?  

Here is what I have attempted so far:

I have been reading the Linux Device Drivers 2nd Edition, the USB and HID
pdfs, linux/Documentation, posting to kernel newbies, can anyone recommend
any other books or information sources for a beginner?  Oh, add this list to
that list of sources, though this is my first post.  :)

My device is an HID device.  My first attempt was the hid driver.  The swipe
reader reports itself as neither a keyboard or mouse, just an hid device.
The hiddev driver was my next attempt.  It did claim my device and I could
interact with it in a limited way.  I talked to Paul Stewart and we emailed
back and forth for a while.  My issue with the hiddev device was that while
I could get the data from the input report via ioctl calls, if same card was
swiped twice, the second time I would get no notification from the device
that anything had happened.  I used read() to determine when a card was
swiped and an ioctl() call to get to the report.  I really needed the input
report to be returned via the read().  The read() call as it is now only
returns the differences between reports which isn't useful for my situation.
The hiddev driver was written to talk to ups(s), which only need to report
changes in state.  Paul told me about a enhancement to the hiddev driver in
the 2.5.x kernel, some new ioctl calls would allow the driver to be switched
into a mode that would return the full report.  Paul backported the patch to
the 2.4.x kernel.  I applied the patch, but it froze my system.  I tried
several smaller patches he sent me via email.  I didn't have any success.  I
really appreciated all the effort and time Paul took into to helping me.
While I was working with Paul, I started developing my own device driver
from scratch using the Linux Device Drivers book as a guide just in case
hiddev didn't pan out.  Then I happened to see a mention of kernel newbies
somewhere, perhaps in the kernel device driver book.  I jumped on irc and
started talking to Greg Kroah.  He suggested that I adapt the omninet driver
(usb-serial) to my needs and that it what I attempted.  I chatted back and
forth about how to get to work with  my device.  I made the changes and I
could get a read() to return all but the first 8 bytes.  I was loosing the
first packet.  I talked to Greg about it, and he thought that it would
probably be easier to mail him what I had done.  I sent him the code.  He
also suggested looking at usb-skeleton.  So I took my from scratch driver,
usb-skeleton, and my linux device driver book and constructed a new driver.
To my surprise, it actually worked.  I could read a full report from my
device.  But the driver wasn't being quite right.  I unplugged the driver in
the middle of cat /dev/test0 and sometimes it would segmentation fault, and
when it didn't, it wouldn't kill the process and return an error as it did
when I have cat(ed) other character devices.  I emailed Greg my current code
for the device driver I had crafted from usb-skeleton.  Greg is going to be
away for about a week though.  I asked him if he could recommend a mailing
list.  He told me about linux-usb-devel.  So I am posting this extremely
long message here.  I wanted to include all the information about my entire
experience so that anyone offering assistance would know what I have
attempted so far.

My code is attached to this document.  It is a module for 2.4.x.

Any help would be appreciated.

Shawn

p.s.  Thanks to Greg and Paul for patiently helping me.  I have learned a
lot.

Attachment: magtek.c
Description: Binary data

Reply via email to