hallo,
i have begun to play with linux usb drivers. at first i try to implement
a mouse driver, but it doesnt work. the completion routine is called
only once. but when i uncomment the last instruction (printk(KERN_INFO
"###>>> Button:% .... maus->daten[2])) in the completion routine works.
i would not use the input driver, like usbmouse.c in the kernel source.
can anybody help me?? or is there some magic with the completion
routine?? i use kernel 2.4.18 and a logitech cordless wheel mouse.
txl sebastian
--
Dietze Sebastian
HTWK Leipzig - Fb IMN
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/usb.h>
#include <linux/slab.h>
#include <asm/uaccess.h>
/* die Hersteller- und Produktnummer der Logitech Maus */
#define TREIBER_VENDOR_ID 0x046d
#define TREIBER_PRODUCT_ID 0xc501
/* Groesse der FIFO in Bytes */
#define FIFO_GROESSE 8
/* Prototypdefinietionen */
static void* treiber_probe(struct usb_device *dev, unsigned int intnr, const struct usb_device_id *id);
static void treiber_disconnect(struct usb_device *dev, void *zeiger);
static void treiber_comple_routine(struct urb *urb);
struct maus_daten
{
/* Zeiger auf die Daten der Maus */
int daten[FIFO_GROESSE];
struct urb u;
};
static struct usb_device_id treiber_ids [] =
{
{USB_DEVICE(TREIBER_VENDOR_ID,TREIBER_PRODUCT_ID)},
{}
};
/* unterstuetzte Geraete exportieren */
MODULE_DEVICE_TABLE(usb, treiber_ids);
static struct usb_driver treiber =
{
name: "treiber",
probe: treiber_probe,
disconnect: treiber_disconnect,
id_table: treiber_ids,
};
static void
treiber_comple_routine(struct urb *urb)
{
struct maus_daten *maus = urb->context;
if(urb->status != 0)
printk(KERN_INFO "### FEHLER IN usb->status\n");
printk(KERN_INFO "### Completion routine\n");
/* printk(KERN_INFO "###>>> Button:%i-X:%i-Y:%i\n",
maus->daten[0],
maus->daten[1],
maus->daten[2]);*/
}
static void*
treiber_probe(struct usb_device *dev, unsigned int internr, const struct usb_device_id *id)
{
struct maus_daten *maus;
struct usb_interface_descriptor *ifdesc;
struct usb_endpoint_descriptor *enddesc;
int pipe, retval;
printk(KERN_INFO "### probe()\n");
if((dev->descriptor.idVendor != TREIBER_VENDOR_ID) &&
(dev->descriptor.idProduct != TREIBER_PRODUCT_ID))
{
printk(KERN_INFO "### Hersteller- und Produktnummer stimmen nicht(V:0x%04x-P:0x%04x)\n", dev->descriptor.idVendor, dev->descriptor.idProduct);
return NULL;
}
/* Endpoint und Interface */
ifdesc = dev->config[0].interface[internr].altsetting+0;
enddesc = ifdesc->endpoint+0;
printk(KERN_INFO "###>> Class: %x\n", ifdesc->bInterfaceClass);
printk(KERN_INFO "###>> SClass: %x\n", ifdesc->bInterfaceSubClass);
printk(KERN_INFO "###>> PClass: %x\n", ifdesc->bInterfaceProtocol);
printk(KERN_INFO "###>> Endpoints: %x\n", ifdesc->bNumEndpoints);
printk(KERN_INFO "###>> EPAddress: 0x%x\n", enddesc->bEndpointAddress);
printk(KERN_INFO "###>> bmAttributes: 0x%x\n", enddesc->bmAttributes);
printk(KERN_INFO "###>> bInterval: 0x%x\n",enddesc->bInterval);
/*-----------------------------------*/
/* usb_set_protocol(dev, ifdesc->bInterfaceNumber, 0);
usb_set_idle(dev, ifdesc->bInterfaceNumber, 0, 0);*/
/*-----------------------------------*/
/* Datenbereich fuer die Maus alokieren */
maus = kmalloc(sizeof(struct maus_daten), GFP_KERNEL);
/* im Fall das kein Speicher reserviert werden konnte */
if(maus == NULL)
{
printk(KERN_INFO "### nicht genuegend Speicher\n");
return NULL;
}
memset(maus, 0, sizeof(*maus));
/* URB mit Daten fuellen */
pipe = usb_rcvintpipe(dev, enddesc->bEndpointAddress);
/*usb_fill_int_urb*/FILL_INT_URB(&maus->u,
dev,
pipe,
maus->daten,
8,
treiber_comple_routine,
maus,
enddesc->bInterval);
/* und los - wieder entfernen von hier */
retval = usb_submit_urb(&maus->u);
if(retval)
printk(KERN_INFO "#### FEHLER bei usb_submit_urb() - (%i)\n", retval);
else
printk(KERN_INFO "#### usb_submit_urb erfolreich - (%i)\n", retval);
printk(KERN_INFO "### verlasse probe() Funktion\n");
return maus;
}
static void
treiber_disconnect(struct usb_device *dev, void *zeiger)
{
struct maus_daten *maus = zeiger;
/* wieder an andere Stelle */
usb_unlink_urb(&maus->u);
/* Speicherbereich der alle Daten der Maus verwaltet wieder freigeben */
kfree(maus);
printk(KERN_INFO "### disconnect\n");
}
int
init_module()
{
int retval, ret = 0;
retval = usb_register(&treiber);
if(retval != 0)
{
printk(KERN_INFO "### Aufruf von usb_register() nicht erfolgreich(FEHLERNR:%i)\n", retval);
/* initialisieren war NICHT erfolgreich */
ret = 1;
}
else
{
printk(KERN_INFO "### Treiber geladen\n");
/* initialisieren war erfolgreich */
ret = 0;
}
return ret;
}
void
cleanup_module()
{
usb_deregister(&treiber);
printk(KERN_INFO "### Treiber entladen\n");
}