Hello

Here it is : my full code.
I've done some improvements and now it seems to 
work. But only the first time. The second try kills the kernel :-(
I think I'll change to libusb (hope its much safer).


The problem was the not via kmalloc allocated buffer
,as you mentioned. Thanks a lot. But dynamically allocated
memory is very dangerous! reminds me of old dos times :-)
booting 100times/day


----------------- code starts here -------------------
/*
 Some USB test
 Hope i wont crash my system
*/

#include "linux/init.h"
#include "linux/kernel.h"
#include "linux/module.h"
#include "linux/slab.h"


/* file operarions */
#include "linux/fs.h"

/* put_user is here */
#include "asm/uaccess.h"

#include "linux/usb.h"

#include "linux/types.h"

#define USB_VENDOR_TRAVELER 0xd96
#define USB_PRODUCT_SX330Z 0x3300


#define USB_REQ_RESERVED 0x04
#define USB_DIR_VENDOR 0x40

#define DRIVER_VERSION "v0.1"
#define DRIVER_DESC "Traveler SX330z Camera Driver"

#define SX330Z_MINOR_BASE 65


MODULE_AUTHOR("Dominik Kuhlen <[EMAIL PROTECTED]>");
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");

struct traveler_sx330z
{
 int isOpen;
 int connected;
 struct usb_device *dev;
};



static struct traveler_sx330z sx330z_instance = {
 isOpen:        0,
 connected:     0,
 dev:           NULL,
};              // this pointer :-)

#define traveler_req_TOC 0x0003
#define traveler_req_Pic 0x0004

/* 32 Bytes*/
struct traveler_request
{
 int16_t always1;               // 0x01
 int16_t requesttype;           // 0x0003 : TOC , 0x0004 ThumbNail
 unsigned char data[4];
 int32_t timestamp;             // counter? only 24 bit  
 int32_t offset;
 int32_t size;
 char filename[12];
} __attribute__((packed));

/* 16 Bytes*/
struct traveler_ack
{
 int32_t always3;       // 3
 int32_t timestamp;     // not sure 
 int32_t size;          // for TOC
 int32_t dontknow;      // always 0
} __attribute__((packed));


/*******************************************************/
/*      Fileoperation   OPEN                    */
/*******************************************************/
static unsigned char *TOC;      // 
static int TCnt=0;
static unsigned char *ThumbNail;// 1 Tn: 0x5000 Bytes

static int sx330z_open(struct inode *inode,struct file *file)
{
 struct traveler_sx330z *sx330z=&sx330z_instance;//file->private_data;
 int res,length;
 unsigned char buf[512];
 
// char *ThumbNail;
 
 struct traveler_request trq;
 struct traveler_ack tack;
 unsigned int pipe;
 int numpics,pics;                      // pictures
 static int TOCSize=0;
 int TOCPage,tcnt;                      // TOC SIZE
 int subminor;
 subminor=MINOR(inode->i_rdev)-SX330Z_MINOR_BASE;
 if (sx330z->isOpen) return(-EBUSY);                    // 
 if ((!sx330z->connected)||(subminor!=0)) return(-ENODEV);              // Camera not 
connected / powered
 TCnt=0;  
 sx330z->isOpen=1;
 MOD_INC_USE_COUNT;
 
 
 
 printk("sx330z : open subminor=%d (vendor=%04x).\n",
        subminor,
        sx330z->dev->descriptor.idVendor);              
 

 pipe=usb_rcvctrlpipe(sx330z->dev,0);
 res=usb_control_msg(sx330z->dev,
                pipe,
                USB_REQ_RESERVED,               // traveler hack ???
                USB_DIR_IN | USB_DIR_VENDOR,
                0x0001, 
                0x0000, 
                &tack,16,HZ);
 printk("sx330z : 0x0001 (res=%d) : %08x %08x %08x %08x\n",
    res,tack.always3,tack.timestamp,tack.size,tack.dontknow);
 
 pipe=usb_rcvctrlpipe(sx330z->dev,0);
 res=usb_control_msg(sx330z->dev,
                pipe,
                USB_REQ_RESERVED,               // traveler hack ????
                USB_DIR_IN | USB_DIR_VENDOR,
                0x0002,                         // get TOC size ????
                0xd000, 
                &tack,16,HZ);
 printk("sx330z : Get TOCsize (res=%d) : %08x %08x %08x %08x\n",
    res,tack.always3,tack.timestamp,tack.size,tack.dontknow);
 
 TOCSize=tack.size;
 if (TOCSize<0) TOCSize=0x48;
 TOC= kmalloc(TOCSize,GFP_KERNEL);      // GFP_KERNEL ?
 if (!TOC) // very dangerous!
 {
  sx330z->isOpen=0;
  MOD_DEC_USE_COUNT;            // important
  return(-1);
 }
 printk("sx330z : TOCSize %d Bytes\n",TOCSize);
 /* set ????*/


/********************************************************/
/*              TOC     x. PAGEs                        */
/********************************************************/
 //memset(TOC,0,0x200);
 numpics=0;
 tcnt=0;        // toc counter
 for (TOCPage=0;(TOCSize>0)&&(TOCPage<3);TOCPage++)
 {
  trq.always1=1;
  trq.requesttype=0x03; // TOC
  trq.offset=0x0200*TOCPage;
  trq.timestamp=0x0046a7ee +0x20*TOCPage;
  trq.size=0x200;
  memset(trq.data,0,4);
  memset(trq.filename,0,12);
 
  res=usb_control_msg(sx330z->dev,
                usb_sndctrlpipe(sx330z->dev,0),
                USB_REQ_RESERVED,               // traveler hack ?????
                USB_DIR_OUT | USB_DIR_VENDOR,
                0x0003,                         // read TOC
                0xd000, 
                &trq,32,HZ);
  printk("sx330z : ReqTOCPage %d (res=%d)\n",TOCPage,res);

  
res=usb_bulk_msg(sx330z->dev,usb_rcvbulkpipe(sx330z->dev,2),buf,512,&length,HZ);
  numpics+=pics=buf[0xa];       // how many pics in this fragment
  memcpy(&TOC[tcnt],&buf[0x0c],pics*0x14);              // skip 12 bytes 
  tcnt+=pics*0x14;
  printk(KERN_INFO "sx330z : read TOC Page #%d %dpics (res=%d,length=%d bytes) 
: %02x %02x %02x %02x ... %02x\n",
    TOCPage,pics,res,length,buf[0],buf[1],buf[2],buf[3],buf[0x10]);
 
 // Get 16Byte Ack
  
res=usb_bulk_msg(sx330z->dev,usb_rcvbulkpipe(sx330z->dev,2),&tack,16,&length,HZ); 
  printk(KERN_INFO "sx330z : read ack (res=%d,length=%d) bytes :%08x %08x %08x 
%08x\n",res,length,
     tack.always3,tack.timestamp,tack.size,tack.dontknow);

 
  TOCSize-=(0x0c+pics*0x14);
 
 } // while TOCSize > 0
 if (TOCSize!=0) {printk(KERN_INFO "sx330z : TOCSize corrupted!!!! 
%d\n",TOCSize);}
 printk(KERN_INFO "sx330z : %d Pictures\n",numpics);
/************************************************/
/*              1. ThumbNail                    */
/************************************************/
 tcnt=0;
 ThumbNail=kmalloc(5*0x1000,GFP_KERNEL);
 if (!ThumbNail) {return(0);} // skip it ??
 for (tcnt=0;tcnt<5;tcnt++)
 {
  trq.always1=1;
  trq.requesttype=0x04;                 // Thumbnail
  trq.offset=0;
  trq.size=0x1000;
  trq.timestamp=0x0046a7ee +tcnt*0x41 +0x19f;
  memset(trq.data,0,4);
  sprintf(trq.filename,"SIMG0001JPG");
 
 // request for ThumbNail 
  res=usb_control_msg(sx330z->dev,
                usb_sndctrlpipe(sx330z->dev,0),
                USB_REQ_RESERVED,               // traveler hack ???
                USB_DIR_OUT | USB_DIR_VENDOR,
                0x0004, 
                0xd000, 
                &trq,32,HZ);
  printk("sx330z : req TN  (%d) : \n",res);

  
res=usb_bulk_msg(sx330z->dev,usb_rcvbulkpipe(sx330z->dev,2),ThumbNail,4096,&length,HZ);
  printk(KERN_INFO "sx330z : read TN (res=%d,length=%d bytes) : %02x %02x ... 
%02x\n",
    res,length,ThumbNail[0],ThumbNail[1],ThumbNail[0x10]);
 
  
res=usb_bulk_msg(sx330z->dev,usb_rcvbulkpipe(sx330z->dev,2),&tack,16,&length,HZ); 
  printk(KERN_INFO "sx330z : read ack? (res=%d,length=%d bytes): %08x %08x 
%08x %08x\n",res,length,
    tack.always3,tack.timestamp,tack.size,tack.dontknow);

 } // 5 Blocks TN data
 
 return(0);     // succeess
} /* fop open */

/*******************************************************/
/*      Fileoperation   RELEASE                 */
/*******************************************************/
static int sx330z_release(struct inode *inode,struct file *file)
{
 struct traveler_sx330z *sx330z=&sx330z_instance;//file->private_data;
 printk("sx330z : fops.release.\n");
 sx330z->isOpen=0;
 kfree (ThumbNail);
 kfree (TOC);
 MOD_DEC_USE_COUNT;
 return(0);
}

/*******************************************************/
/*      Fileoperation   READ                    */
/*******************************************************/
static ssize_t sx330z_read(struct file *file,char *buffer,size_t count,loff_t 
*ppos)
{
 ssize_t bytes=0;
 
 printk("sx330z : fops.read %d bytes. \n",count);
 
 while ((count>0)) 
   {
    put_user(TOC[TCnt],buffer++);               // copy message
    count--;
    bytes++;
    TCnt++;
    if (TCnt==1024) TCnt=0;
   }
 return(bytes);
}





/*******************************************************/
/*      probe function                                  */
/*******************************************************/
void *usb_sx330z_probe(struct usb_device *dev,unsigned intf,const struct 
usb_device_id *id)
{
 struct traveler_sx330z *sx330z=&sx330z_instance; 
 printk(KERN_INFO "SX330z : probe. interface : %d , Speed %d, addr: %d\n",
            intf,dev->speed,dev->devnum);
 if ((dev->descriptor.idVendor!=USB_VENDOR_TRAVELER)||
     (dev->descriptor.idProduct!=USB_PRODUCT_SX330Z)||
    (sx330z->connected)) return(NULL);          // only one instance allowed

 printk(KERN_INFO "SX330z : Vendor : %04x\n",dev->descriptor.idVendor);
 
 sx330z->dev=dev;               // save device context
 sx330z->connected=1;
 
 return(sx330z);                // return handler
}


/*******************************************************/
/*      disconnect function                             */
/*******************************************************/
void usb_sx330z_disconnect(struct usb_device *dev,void *ptr)
{
 struct traveler_sx330z *sx330z=ptr;
 if (sx330z->isOpen) printk(KERN_INFO "SX330z : Warning file open !!\n");
 sx330z->connected=0;
 printk(KERN_INFO "SX330z : disconnect.\n");
}


/*******************************************************/
/*  fileoperations                              */
/*******************************************************/
struct file_operations file_ops = {
 owner:         THIS_MODULE,
 open:          sx330z_open,
 read:          sx330z_read,
 release:       sx330z_release,
};


/****************************/
/*      ID Table        */
/****************************/
static struct usb_device_id usb_sx330z_id_table [] = {
    {USB_DEVICE(USB_VENDOR_TRAVELER,USB_PRODUCT_SX330Z)},
    {}  // terminating entry
 
};


MODULE_DEVICE_TABLE(usb,usb_sx330z_id_table);

/***********************/
/*      */
/**********************/
static struct usb_driver usb_sx330z_driver = {
 name:          "Traveler SX330z",
 probe:         usb_sx330z_probe,
 disconnect:    usb_sx330z_disconnect,
 id_table:      usb_sx330z_id_table,
 fops:          &file_ops, 
 minor:         SX330Z_MINOR_BASE,      
};




/*******************************************************/
/*      Module init     */
/*******************************************************/
static int __init usb_eumels_init(void)
{
 int stat;
 stat=usb_register(&usb_ser);
 printk(KERN_INFO "Traveler SX330z USB test loaded (ret=%d).\n",stat);
 if (stat<0) return(-1);
 info(DRIVER_DESC " " DRIVER_VERSION);
 return(0);
}

/*******************************************************/
/*      Module exit     */
/*******************************************************/
static void __exit usb_eumels_exit(void)
{
 usb_deregister(&usb_sx330z_driver);
 printk(KERN_INFO "Traveler SX330z USB test killed.\n" );
}



module_init(usb_eumels_init);
module_exit(usb_eumels_exit);

----------------- code ends here ----------------------

the userspace command was :
dd if=usbtest of=foo.toc bs=512 count=1 ; this works
doitagain and the system will crash :-( 


kernel log file looks like this: 
Apr  8 20:57:38 doku kernel: sx330z : fops.open subminor=0 (vendor=0d96).
Apr  8 20:57:38 doku kernel: sx330z : 0x0001 (res=16) : 00000003 00000000 
00000000 00000000
Apr  8 20:57:38 doku kernel: sx330z : Get TOCsize (res=16) : 00000003 00000000 
00000048 00000000
Apr  8 20:57:38 doku kernel: sx330z : TOCSize 72 Bytes
Apr  8 20:57:38 doku kernel: sx330z : ReqTOCPage 0 (res=32)
Apr  8 20:57:39 doku kernel: sx330z : read TOC Page #0 3pics (res=0,length=512 
bytes) : 00 00 00 00 ... 30
Apr  8 20:57:39 doku kernel: sx330z : read ack (res=0,length=16) bytes 
:00000003 0046a7ee 00000000 00000000
Apr  8 20:57:39 doku kernel: sx330z : 3 Pictures
Apr  8 20:57:39 doku kernel: sx330z : req TN  (32) :
Apr  8 20:57:39 doku kernel: sx330z : read TN (res=0,length=4096 bytes) : 
ff d8 ... 08
Apr  8 20:57:39 doku kernel: sx330z : read ack? (res=0,length=16 bytes): 
00000003 0046a98d 00000000 00000000
Apr  8 20:57:39 doku kernel: sx330z : req TN  (32) :
Apr  8 20:57:39 doku kernel: sx330z : read TN (res=0,length=4096 bytes) : 
19 79 ... bd
Apr  8 20:57:39 doku kernel: sx330z : read ack? (res=0,length=16 bytes): 
00000003 0046a9ce 00000000 00000000
Apr  8 20:57:39 doku kernel: sx330z : req TN  (32) :
Apr  8 20:57:39 doku kernel: sx330z : read TN (res=0,length=4096 bytes) : 
f8 02 ... b4
Apr  8 20:57:39 doku kernel: sx330z : read ack? (res=0,length=16 bytes): 
00000003 0046aa0f 00000000 00000000
Apr  8 20:57:39 doku kernel: sx330z : req TN  (32) :
Apr  8 20:57:39 doku kernel: sx330z : read TN (res=0,length=4096 bytes) : 
a2 98 ... 54
Apr  8 20:57:39 doku kernel: sx330z : read ack? (res=0,length=16 bytes): 
00000003 0046aa50 00000000 00000000
Apr  8 20:57:39 doku kernel: sx330z : req TN  (32) :
Apr  8 20:57:39 doku kernel: sx330z : read TN (res=0,length=4096 bytes) : 
62 36 ... 52
Apr  8 20:57:39 doku kernel: sx330z : read ack? (res=0,length=16 bytes): 
00000003 0046aa91 00000000 00000000
Apr  8 20:57:39 doku kernel: sx330z : fops.read 512 bytes.
Apr  8 20:57:39 doku kernel: sx330z : fops.release.
Apr  8 20:58:26 doku kernel: sx330z : fops.open subminor=0 (vendor=0d96).
Apr  8 20:58:26 doku kernel: sx330z : 0x0001 (res=16) : 00000003 00000000 
00000000 00000000
Apr  8 20:58:26 doku kernel: sx330z : Get TOCsize (res=16) : 00000003 00000000 
00000048 00000000
Apr  8 20:58:26 doku kernel: sx330z : TOCSize 72 Bytes
Apr  8 20:58:26 doku kernel: sx330z : ReqTOCPage 0 (res=32)
Apr  8 20:58:26 doku kernel: sx330z : read TOC Page #0 215pics           
(res=0,length=512 bytes) : 26 72 a4 64 ... 12
                                      ^^^^^ this is not right 

(0xff 0xd8 : start of jpeg picture :-))))

Thank you very much
        Dominik


_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to