Hello, The included patch (against 2.4.18 - a 2.5 one will be coming along soon) adds support for the Samsung Uproar MP3 phone, and the YP-20S MP3 player. It appears that the same protocol is used in all of Samsung's USB MP3 devices, so anyone with such a device not supported by this code should email its Device ID to me.
This patch is extremely rough - I need to do some major work on error reporting and stuff, but it gets the job done. The ioctl range used has not been officially designated for this driver yet, so future revisions may change ioctl numbers. A user-space API (libuproar) will be made available on my website within a couple days. I'm sending this out now, so that I can get comments, recommendations and device ID's for Samsung MP3 players that I may be able to support. Thanks, PK
diff -Nru a/Documentation/Configure.help b/Documentation/Configure.help --- a/Documentation/Configure.help Wed Apr 3 18:49:52 2002 +++ b/Documentation/Configure.help Wed Apr 3 18:55:04 2002 @@ -13610,6 +13610,22 @@ Say Y here to include additional code to support the Sandisk SDDR-09 SmartMedia reader in the USB Mass Storage driver. +USB Uproar support +CONFIG_USB_UPROAR + Say Y here if you want to connect a Samsung Uproar mp3 phone to your + computer's USB port. More information about this driver is available + at <http://hatari.dhs.org/~pkobly/uproar.html> + + This driver should also be usable for other Samsung USB MP3 players. + If you have such a device not supported by this driver, contact + <mailto:[EMAIL PROTECTED]>. The list of currently supported devices + is in <file:Documentation/usb/uproar.txt>. + + This code is also available as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module will be called uproar.o. If you want to compile it as + a module, say M here and read <file:Documentation/modules.txt>. + USB Diamond Rio500 support CONFIG_USB_RIO500 Say Y here if you want to connect a USB Rio500 mp3 player to your diff -Nru a/Documentation/usb/uproar.txt b/Documentation/usb/uproar.txt --- a/Documentation/usb/uproar.txt Wed Dec 31 17:00:00 1969 +++ b/Documentation/usb/uproar.txt Wed Apr 3 18:55:04 2002 @@ -0,0 +1,11 @@ +This driver currently supports: + +Samsung YP-20S +Samsung Uproar Phone (SPH-M100) + +If you have a Samsung MP3 USB player which is not supported by this driver, +please plug it into a USB port, and send the output of: + +# cat /proc/bus/usb/devices + +to [EMAIL PROTECTED] diff -Nru a/drivers/usb/Config.in b/drivers/usb/Config.in --- a/drivers/usb/Config.in Wed Apr 3 18:49:45 2002 +++ b/drivers/usb/Config.in Wed Apr 3 18:55:04 2002 @@ -98,5 +98,5 @@ comment 'USB Miscellaneous drivers' dep_tristate ' USB Diamond Rio500 support (EXPERIMENTAL)' CONFIG_USB_RIO500 $CONFIG_USB $CONFIG_EXPERIMENTAL - +dep_tristate ' USB Uproar suport (EXPERIMENTAL)' CONFIG_USB_UPROAR $CONFIG_USB +$CONFIG_EXPERIMENTAL endmenu diff -Nru a/drivers/usb/Makefile b/drivers/usb/Makefile --- a/drivers/usb/Makefile Wed Apr 3 18:49:45 2002 +++ b/drivers/usb/Makefile Wed Apr 3 18:55:04 2002 @@ -68,6 +68,7 @@ obj-$(CONFIG_USB_KAWETH) += kaweth.o obj-$(CONFIG_USB_CDCETHER) += CDCEther.o obj-$(CONFIG_USB_RIO500) += rio500.o +obj-$(CONFIG_USB_UPROAR) += uproar.o obj-$(CONFIG_USB_DSBR) += dsbr100.o obj-$(CONFIG_USB_MICROTEK) += microtek.o obj-$(CONFIG_USB_HPUSBSCSI) += hpusbscsi.o diff -Nru a/drivers/usb/uproar.c b/drivers/usb/uproar.c --- a/drivers/usb/uproar.c Wed Dec 31 17:00:00 1969 +++ b/drivers/usb/uproar.c Wed Apr 3 18:55:04 2002 @@ -0,0 +1,1275 @@ +/* + * USB Uproar driver - 0.4 + * + * Copyright (c) 2001 Patrick Kobly ([EMAIL PROTECTED]) + * + * Based on usb-skeleton.c + * Copyright (c) 2001 Greg Kroah-Hartman ([EMAIL PROTECTED]) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * + * This program is a driver for the Samsung Uproar PCS phone with MP3 + * capabilities. It may also be compatible with the Samsung Yepp MP3 player. + * + * Thanks to Kasima Tharnpipitchai ([EMAIL PROTECTED]) for his description of the + * protocol used by this device. + * (http://kasima.org/creations/uproar/protocol.html) + * + * TODO: + * - Error reporting/handling + * - Merge / patch with main usb-linux tree + * - Clean up code + * + * History: + * + * 2001-27-Nov 0.01 Initial working code. Supports Send, Get Device Info + * 2001-04-Dec 0.02 Get playlist now works, along with delete. + * 2001-13-Dec 0.03 All functions described in kasima's page implemented + * + */ + +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/signal.h> +#include <linux/errno.h> +#include <linux/poll.h> +#include <linux/init.h> +#include <linux/slab.h> +#include <linux/fcntl.h> +#include <linux/module.h> +#include <linux/spinlock.h> +#include <linux/list.h> +#include <linux/smp_lock.h> +#include <linux/devfs_fs_kernel.h> +#include <linux/usb.h> + +#include "uproarkern.h" +#ifdef CONFIG_USB_DEBUG + static int debug = 1; +#else + static int debug; +#endif + +/* Use our own dbg macro */ +#undef dbg +#define dbg(format, arg...) do { if (debug) printk(KERN_DEBUG __FILE__ ": " format +"\n" , ## arg); } while (0) + + +/* Version Information */ +#define DRIVER_VERSION "v0.01" +#define DRIVER_AUTHOR "Patrick Kobly, [EMAIL PROTECTED]" +#define DRIVER_DESC "Uproar PCS driver" + +/* Module paramaters */ +MODULE_PARM(debug, "i"); +MODULE_PARM_DESC(debug, "Debug enabled or not"); + + +/* Define these values to match your device */ +#define USB_UPROAR_VENDOR_ID 0x4e8 +#define USB_UPROAR_PRODUCT_ID 0x6600 + +#define USB_YEPP_VENDOR_ID 0x4e8 +#define USB_YEPP_PRODUCT_ID 0x5a03 + +/* table of devices that work with this driver */ +static struct usb_device_id uproar_table [] = { + { USB_DEVICE(USB_UPROAR_VENDOR_ID, USB_UPROAR_PRODUCT_ID) }, + { USB_DEVICE(USB_YEPP_VENDOR_ID, USB_YEPP_PRODUCT_ID) }, + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE (usb, uproar_table); + +static int charindices [] = {1,3,5,7,9,14,16,18,20,22,24,28,30}; + +#define MIN(x,y) (x<y?x:y) +/* Get a minor range for your devices from the usb maintainer */ +#define USB_UPROAR_MINOR_BASE 111 + +/* we can have up to this number of device plugged in at once */ +#define MAX_DEVICES 1 + +#define USB_UPROAR_COMMAND 0x0A +#define USB_UPROAR_RESPONSE 0x0C +#define USB_UPROAR_TRACKDATA 0x0B +#define USB_UPROAR_INITIATE 0x0A +#define USB_UPROAR_PLAYLISTCOMP 0x0C +#define USB_UPROAR_ENDTRANS 0x0C + +#define USB_UPROAR_INITIND 1 +#define USB_UPROAR_PLAYCOMPIND 1 +#define USB_UPROAR_ENDTRANSIND 0xFFFF + +#define USB_UPROAR_DEVINFO 0x59 +#define USB_UPROAR_FILECHUNK 0x8000 +/* Structure to hold all of our device specific stuff */ +struct usb_uproar { + struct usb_device * udev; /* save off the usb device pointer */ + devfs_handle_t devfs; /* devfs device node */ + unsigned char minor; /* the starting minor number for this +device */ + struct urb * write_urb; /* the urb used to send data */ + struct semaphore sem; /* locks this structure */ + struct semaphore readsem; /* Locks only the read buffer*/ + wait_queue_head_t wq; /* Signal completion */ + int open_count; /* number of times this*/ + /* Always have 1 bulk in, 1 bulk out */ + char num_bulk_in; /* number of bulk in endpoints we have +*/ + char num_bulk_out; /* number of bulk out endpoints we +have */ + + unsigned char * bulk_in_buffer; /* the buffer to receive data +*/ + int bulk_in_size; /* the size of the receive buffer */ + __u8 bulk_in_endpointAddr; /* the address of the bulk in endpoint +*/ + + unsigned char * bulk_out_buffer; /* the buffer to send data */ + int bulk_out_size; /* the size of the send buffer */ + __u8 bulk_out_endpointAddr; /* the address of the bulk out +endpoint */ + char filebuffer[USB_UPROAR_FILECHUNK]; /* The chunk we're currently + building */ + int offset; /* The offset that we're currently + indexing into filebuffer */ + size_t bytesleft; /* The number of bytes left to + transfer */ + unsigned char * readbuffer; + int readbuffersize; + /* int readoffset; */ +}; + +struct usb_uproar_message { + __u16 pad1; /* always 0x23 */ + __u8 len; /* length of buffer+pad2+1 (for term 0x2e) */ + __u8 pad2; /* always 3ah */ + char buf[60]; /* data plus ending 0x2e */ +}; + +#define USB_UPROAR_MAGIC {0x4d,0x90,0x17,0x02,0x20,0x28,0x61,0x63,0xcd} + +/* the global usb devfs handle */ +extern devfs_handle_t usb_devfs_handle; + + +/* local function prototypes */ +static int usb_uproar_recv_message(struct usb_uproar * dev,void *buf, int size); +static ssize_t uproar_read (struct file *file, char *buffer, size_t count, loff_t +*ppos); +static ssize_t uproar_write (struct file *file, const char *buffer, size_t count, +loff_t *ppos); +static int uproar_ioctl (struct inode *inode, struct file *file, +unsigned int cmd, unsigned long arg); +static int uproar_open (struct inode *inode, struct file *file); +static int uproar_release (struct inode *inode, struct file *file); + +static void * uproar_probe (struct usb_device *dev, unsigned int ifnum, const +struct usb_device_id *id); +static void uproar_disconnect (struct usb_device *dev, void *ptr); + +static void uproar_write_callback (struct urb *urb); + +static int uproar_get_devinfo(struct usb_uproar *dev, char * buf, size_t size); +static int usb_uproar_send_file(struct usb_uproar * dev, uproar_fileinfo * ufi); +static int usb_uproar_send_message(struct usb_uproar *dev, char *payload, int len); +static int usb_uproar_send_control(struct usb_uproar * dev, int request, int index); +static int usb_uproar_get_playlist(struct usb_uproar * dev, struct file * filp); +static int usb_uproar_delete_file(struct usb_uproar * dev, char * trackID); +static int usb_uproar_format(struct usb_uproar * dev); +static int usb_uproar_get_capacity(struct usb_uproar * dev, int * cap); +static int usb_uproar_get_freespace(struct usb_uproar * dev, int * free); + +/* array of pointers to our devices that are currently connected */ +static struct usb_uproar *minor_table[MAX_DEVICES]; + +/* lock to protect the minor_table structure */ +static DECLARE_MUTEX (minor_table_mutex); + +/* file operations needed when we register this driver */ +static struct file_operations uproar_fops = { + owner: THIS_MODULE, + read: uproar_read, + write: uproar_write, + ioctl: uproar_ioctl, + open: uproar_open, + release: uproar_release, +}; + + +/* usb specific object needed to register this driver with the usb subsystem */ +static struct usb_driver uproar_driver = { + name: "uproar", + probe: uproar_probe, + disconnect: uproar_disconnect, + fops: &uproar_fops, + minor: USB_UPROAR_MINOR_BASE, + id_table: uproar_table, +}; + + + + + +/** + * usb_uproar_debug_data + */ +static inline void usb_uproar_debug_data (const char *function, int size, const +unsigned char *data) +{ + int i; + + if (!debug) + return; + + printk (KERN_DEBUG __FILE__": %s - length = %d, data = ", + function, size); + for (i = 0; i < size; ++i) { + printk ("%.2x ", data[i]); + } + printk ("\n"); +} + + +/** + * uproar_delete + */ +static inline void uproar_delete (struct usb_uproar *dev) +{ + minor_table[dev->minor] = NULL; +/* if (dev->bulk_in_buffer != NULL) */ +/* kfree (dev->bulk_in_buffer); */ +/* if (dev->bulk_out_buffer != NULL) */ +/* kfree (dev->bulk_out_buffer); */ + if (dev->readbuffer != NULL) + kfree (dev->readbuffer); + if (dev->write_urb != NULL) + usb_free_urb (dev->write_urb); + kfree (dev); +} + + +/** + * uproar_open + */ +static int uproar_open (struct inode *inode, struct file *file) +{ + struct usb_uproar *dev = NULL; + int subminor; + int retval = 0; + + dbg(__FUNCTION__); + + subminor = MINOR (inode->i_rdev) - USB_UPROAR_MINOR_BASE; + if ((subminor < 0) || + (subminor >= MAX_DEVICES)) { + return -ENODEV; + } + + /* increment our usage count for the module */ + MOD_INC_USE_COUNT; + + /* lock our minor table and get our local data for this minor */ + down (&minor_table_mutex); + dev = minor_table[subminor]; + if (dev == NULL) { + up (&minor_table_mutex); + MOD_DEC_USE_COUNT; + return -ENODEV; + } + + /* lock this device */ + down (&dev->sem); + + /* unlock the minor table */ + up (&minor_table_mutex); + + /* increment our usage count for the driver */ + ++dev->open_count; + + /* save our object in the file's private structure */ + file->private_data = dev; + + /* unlock this device */ + up (&dev->sem); + + return retval; +} + + +/** + * uproar_release + */ +static int uproar_release (struct inode *inode, struct file *file) +{ + struct usb_uproar *dev; + int retval = 0; + + /* info ("release"); */ + dev = (struct usb_uproar *)file->private_data; + if (dev == NULL) { + dbg (__FUNCTION__ " - object is NULL"); + return -ENODEV; + } + + dbg(__FUNCTION__ " - minor %d", dev->minor); + + /* lock our minor table */ + down (&minor_table_mutex); + + /* lock our device */ + down (&dev->sem); + + if (dev->open_count <= 0) { + dbg (__FUNCTION__ " - device not opened"); + retval = -ENODEV; + goto exit_not_opened; + } + /* info("We must drop use count"); */ + if (dev->udev == NULL) { + /* the device was unplugged before the file was released */ + up (&dev->sem); + uproar_delete (dev); + MOD_DEC_USE_COUNT; + up (&minor_table_mutex); + return 0; + } + + /* decrement our usage count for the device */ + --dev->open_count; + if (dev->open_count <= 0) { + /* shutdown any bulk writes that might be going on */ + usb_unlink_urb (dev->write_urb); + dev->open_count = 0; + } + + /* decrement our usage count for the module */ + MOD_DEC_USE_COUNT; + +exit_not_opened: + up (&dev->sem); + up (&minor_table_mutex); + + return retval; +} + + +/** + * uproar_read + */ +static ssize_t uproar_read (struct file *file, char *buffer, size_t count, loff_t +*ppos) +{ + struct usb_uproar *dev; + int retval = 0; + + dev = (struct usb_uproar *)file->private_data; + + dbg(__FUNCTION__ " - minor %d, count = %d", dev->minor, count); + /* info ("Read called");*/ + /* lock this object */ + down (&dev->sem); + + /* verify that the device wasn't unplugged */ + if (dev->udev == NULL) { + up (&dev->sem); + return -ENODEV; + } + down (&dev->readsem); + up (&dev->sem); + if (dev->readbuffersize<=*ppos) { + /* info ("Ret 0"); */ + up(&dev->readsem); + return 0; + } + if (!dev->readbuffer) { + up (&dev->readsem); + return -EFAULT; + } + count=MIN(dev->readbuffersize - *ppos, count); + if (copy_to_user (buffer, dev->readbuffer+*ppos, count)) + retval = -EFAULT; + else { + retval = count; + *ppos+=count; + } + /* unlock the device */ + up (&dev->readsem); + return retval; +} + + +/** + * uproar_write + */ +static ssize_t uproar_write (struct file *file, const char *buffer, size_t count, +loff_t *ppos) +{ + struct usb_uproar *dev; + int retval = 0; + int status; + dev = (struct usb_uproar *)file->private_data; + + dbg(__FUNCTION__ " - minor %d, count = %d", dev->minor, count); + + /* lock this object */ + down (&dev->sem); + + /* verify that the device wasn't unplugged */ + if (dev->udev == NULL) { + retval = -ENODEV; + goto exit; + } + + /* verify that we actually have some data to write */ + if (count == 0) { + dbg(__FUNCTION__ " - write request of 0 bytes"); + goto exit; + } + + /* see if we are already in the middle of a write */ + if (dev->write_urb->status == -EINPROGRESS) { + dbg (__FUNCTION__ " - already writing"); + goto exit; + } + /* if (dev->bytesleft<1) { + retval=-EBUSY; + info("You gotta set up the write fool"); + goto exit; + }*/ + + /* copy the data from userspace into our urb */ + count=MIN(count,USB_UPROAR_FILECHUNK-dev->offset); + if (copy_from_user(dev->filebuffer+dev->offset, buffer,count)) { + retval = -EFAULT; + goto exit; + } + + dev->offset+=count; + dev->bytesleft-=count; + if (dev->offset==USB_UPROAR_FILECHUNK || dev->bytesleft==0) { + /* Push it out on the URB */ + memset(dev->filebuffer+dev->offset,0,USB_UPROAR_FILECHUNK-dev->offset); + dev->offset=0; /* Reset the offset for the next se4t of writes */ + FILL_BULK_URB(dev->write_urb, dev->udev, + usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr), + dev->filebuffer, USB_UPROAR_FILECHUNK, + uproar_write_callback, dev); + status=usb_submit_urb(dev->write_urb); + /*info("Pushed file URB out. Bytes left: %d sleeping status:%d", + dev->bytesleft,status);*/ + wait_event_interruptible(dev->wq, + (dev->write_urb->status!=-EINPROGRESS)); + /* Say how much we grabbed from this request */ + /*info("status: %d",dev->write_urb->status);*/ + if (dev->bytesleft==0) { + /*info ("I am done with this file");*/ + usb_uproar_send_control(dev, USB_UPROAR_COMMAND, + USB_UPROAR_ENDTRANSIND); + } + retval=count; + goto exit; + } else { + if (dev->offset>USB_UPROAR_FILECHUNK) { + /*info("Impossible: We've written more than we expected to");*/ + retval=-1; + goto exit; + } else { + /* info("Chunk not full. Waiting for next"); + info("bytesleft: %d\n",dev->bytesleft);*/ + retval=count; + goto exit; + } + } +exit: + /* unlock the device */ + up (&dev->sem); + + return retval; +} + + +/** + * uproar_ioctl + */ +static int uproar_ioctl (struct inode *inode, struct file *file, unsigned int cmd, +unsigned long arg) +{ + char devinfo[61]; + char* out; + int size; + + struct usb_uproar *dev; + + /* info ("ioctl");*/ + dev = (struct usb_uproar *)file->private_data; + + /* lock this object */ + down (&dev->sem); + + /* verify that the device wasn't unplugged */ + if (dev->udev == NULL) { + up (&dev->sem); + return -ENODEV; + } + + dbg(__FUNCTION__ " - minor %d, cmd 0x%.4x, arg %ld", + dev->minor, cmd, arg); + /* fill in your device specific stuff here */ + switch (cmd) { + case UPROAR_GETDEVINFO: + /*info("getdevinfo");*/ + out=(char *)arg; + if (out==NULL) { + up(&dev->sem); + return -EFAULT; + } else { + size=uproar_get_devinfo(dev,devinfo,61); + copy_to_user(out, devinfo, size); + } + up (&dev->sem); + return 0; + break; + case UPROAR_SENDFILE: + usb_uproar_send_file(dev,(uproar_fileinfo*) arg); + up(&dev->sem); + return 0; + break; + case UPROAR_DELETEFILE: + usb_uproar_delete_file(dev,(char *) arg); + up(&dev->sem); + return 0; + break; + case UPROAR_GETPLAYLIST: + usb_uproar_get_playlist(dev,file); + up(&dev->sem); + return 0; + break; + case UPROAR_FORMAT: + usb_uproar_format(dev); + up(&dev->sem); + return 0; + break; + case UPROAR_GETCAP: + usb_uproar_get_capacity(dev,(int *)arg); + up(&dev->sem); + return 0; + break; + case UPROAR_GETFREE: + usb_uproar_get_freespace(dev,(int *)arg); + up(&dev->sem); + return 0; + break; + default: + /* unlock the device */ + up (&dev->sem); + + /* return that we did not understand this ioctl call */ + return -ENOTTY; + } +} + + +/** + * uproar_write_callback + */ +static void uproar_write_callback (struct urb *urb) +{ + struct usb_uproar *dev = (struct usb_uproar *)urb->context; + + dbg(__FUNCTION__ " - minor %d", dev->minor); + /*info("Callback");*/ + if ((urb->status != -ENOENT) && + (urb->status != -ECONNRESET)) { + wake_up_interruptible(&dev->wq); + /*info("foo");*/ + dbg(__FUNCTION__ " - nonzero write bulk status received: %d", + urb->status); + return; + } + /* info("bar");*/ + wake_up_interruptible(&dev->wq); + return; +} + +static int usb_uproar_count_tracks(char * plist) { + char *cur; + int count; + + count=0; + cur=plist+8; + + while (*cur >> 4 == 4) { + count++; + cur+=((*cur & 0x0f)+1)*32; + } + return count; +} + +static int usb_uproar_process_plist(struct usb_uproar * dev, char * plist, + struct file * filp) { + __u32 capacity; + __u32 remaining; + char * cur; + char * curframe; + char numframes; + char x; + uproar_fileinfo fi; + int curoff; + int mychr; + int numtracks; + int track; + + numtracks=usb_uproar_count_tracks(plist); +/* info ("Processing %d tracks.",numtracks); */ + cur=plist; + memcpy(&capacity, cur, 4); + capacity=__be32_to_cpu(capacity); + cur+=4; + memcpy(&remaining, cur, 4); + remaining=__be32_to_cpu(remaining); + cur+=4; +/* info("Device capacity: %d B. Free: %d B",capacity,remaining); */ + /* Protect the buffer */ + up (&dev->readsem); + if (dev->readbuffer) { + kfree (dev->readbuffer); + } + dev->readbuffersize=sizeof(fi)*numtracks; + dev->readbuffer=kmalloc(sizeof(fi)*numtracks,GFP_KERNEL); + /* dev->readoffset=0;*/ + dev->readbuffersize=sizeof(fi)*numtracks; + for (track=0;track<numtracks;track++) { + numframes=*cur & 0x0f; /* How many title frames do we have before the info + Frame */ + curoff=0; + for (x=numframes;x>0;x--) { /* Count back... Frames are backwards */ + curframe=cur+((x-1)*32); + for (mychr=0;mychr<13;mychr++) { + if (curoff>=0) { + fi.trackName[curoff]=curframe[charindices[mychr]]; + /* Stop at '\0' */ + curoff=(fi.trackName[curoff]?curoff+1:-1); + } + } + } +/* info ("Track processed. Track name: %s",fi.trackName); */ + /* We've done all the title frames, now do the info frame */ + cur+=numframes*32; + strncpy(fi.trackID,cur,8); + fi.trackID[8]='\0'; + strcat(fi.trackID,"."); + strncat(fi.trackID,cur+8,3); + fi.trackID[12]='\0'; +/* info ("Track ID: %s",fi.trackID); */ + memcpy(&fi.tracksize,cur+28,4); + fi.tracksize=__le32_to_cpu(fi.tracksize); +/* info ("Track Size: %d",fi.tracksize); */ + /* Cat this track into the read buffer */ + memcpy(dev->readbuffer+(track*sizeof(fi)),&fi,sizeof(fi)); + cur+=32; + } + filp->f_pos=0; + down(&dev->readsem); + return 0; +} + +static int usb_uproar_get_playlist(struct usb_uproar * dev,struct file * filp) { + char msg[60]; + char *plist; + int status; + int actuallength; + __u16 plistsize; + msg[0]=0x4d; + msg[1]=0x47; + usb_uproar_send_control(dev,USB_UPROAR_COMMAND,0); + usb_uproar_send_message(dev,msg,2); + usb_uproar_send_control(dev, USB_UPROAR_COMMAND,USB_UPROAR_ENDTRANSIND); + usb_uproar_send_control(dev, USB_UPROAR_RESPONSE,0); + actuallength=usb_uproar_recv_message(dev,msg,60); +/* for (x=0;x<actuallength;x++) { */ +/* info("%X %c %d",msg[x],msg[x]>0?msg[x]:'.',msg[x]); */ +/* } */ + + memcpy(&plistsize,msg+2,2); + + plistsize=__be16_to_cpu(plistsize); +/* info("Getting playlist of size %d.",plistsize); */ + plistsize=((plistsize/64)+(plistsize%64?1:0))*64; +/* info("Next multiple of 64 is %d.",plistsize); */ + plist=kmalloc(plistsize,GFP_KERNEL); + usb_uproar_send_control(dev, USB_UPROAR_COMMAND,USB_UPROAR_ENDTRANSIND); + usb_uproar_send_control(dev, USB_UPROAR_INITIATE, USB_UPROAR_INITIND); + msg[0]=0x46; + usb_uproar_send_message(dev,msg,1); + usb_uproar_send_control(dev, USB_UPROAR_COMMAND,USB_UPROAR_ENDTRANSIND); + usb_uproar_send_control(dev, USB_UPROAR_PLAYLISTCOMP, USB_UPROAR_INITIND); + + /* Returns num of bytes put into buf. */ + + status = usb_bulk_msg (dev->udev, + usb_rcvbulkpipe (dev->udev, + dev->bulk_in_endpointAddr), + plist, plistsize, + &actuallength, HZ*10); + if (!status) { +/* info("Received stuff from device:%d",actuallength); */ + usb_uproar_send_control(dev, USB_UPROAR_COMMAND, USB_UPROAR_ENDTRANSIND); +/* for (x=0;x<plistsize;x++) { */ +/* info("%X %c %d",plist[x],plist[x]>0?plist[x]:'.',plist[x],plist[x]); */ +/* } */ + usb_uproar_process_plist(dev,plist,filp); + kfree(plist); + return 0; + } + kfree(plist); + usb_uproar_send_control(dev, USB_UPROAR_COMMAND, USB_UPROAR_ENDTRANSIND); + return -1; /* Did not read successfully */ + +} +static int usb_uproar_get_capacity(struct usb_uproar * dev, int * cap) { + char msg[60]; + char *plist; + int status; + int actuallength; + __u32 capacity; + __u16 plistsize; + msg[0]=0x4d; + msg[1]=0x47; + usb_uproar_send_control(dev,USB_UPROAR_COMMAND,0); + usb_uproar_send_message(dev,msg,2); + usb_uproar_send_control(dev, USB_UPROAR_COMMAND,USB_UPROAR_ENDTRANSIND); + usb_uproar_send_control(dev, USB_UPROAR_RESPONSE,0); + actuallength=usb_uproar_recv_message(dev,msg,60); + memcpy(&plistsize,msg+2,2); + plistsize=__be16_to_cpu(plistsize); +/* info("Getting playlist of size %d.",plistsize); */ + plistsize=((plistsize/64)+(plistsize%64?1:0))*64; +/* info("Next multiple of 64 is %d.",plistsize); */ + plist=kmalloc(plistsize,GFP_KERNEL); + usb_uproar_send_control(dev, USB_UPROAR_COMMAND,USB_UPROAR_ENDTRANSIND); + usb_uproar_send_control(dev, USB_UPROAR_INITIATE, USB_UPROAR_INITIND); + msg[0]=0x46; + usb_uproar_send_message(dev,msg,1); + usb_uproar_send_control(dev, USB_UPROAR_COMMAND,USB_UPROAR_ENDTRANSIND); + usb_uproar_send_control(dev, USB_UPROAR_PLAYLISTCOMP, USB_UPROAR_INITIND); + + /* Returns num of bytes put into buf. */ + + status = usb_bulk_msg (dev->udev, + usb_rcvbulkpipe (dev->udev, + dev->bulk_in_endpointAddr), + plist, plistsize, + &actuallength, HZ*10); + if (!status) { +/* info("Received stuff from device:%d",actuallength); */ + usb_uproar_send_control(dev, USB_UPROAR_COMMAND, USB_UPROAR_ENDTRANSIND); +/* for (x=0;x<plistsize;x++) { */ +/* info("%X %c %d",plist[x],plist[x]>0?plist[x]:'.',plist[x],plist[x]); */ +/* } */ + memcpy(&capacity, plist, 4); + capacity=__be32_to_cpu(capacity); + copy_to_user(cap,&capacity,4); + kfree(plist); + return 0; + } + kfree(plist); + usb_uproar_send_control(dev, USB_UPROAR_COMMAND, USB_UPROAR_ENDTRANSIND); + return -1; /* Did not read successfully */ +} + +static int usb_uproar_get_freespace(struct usb_uproar * dev,int *free) { + char msg[60]; + char *plist; + int status; + int actuallength; + __u32 freespace; + __u16 plistsize; + msg[0]=0x4d; + msg[1]=0x47; + usb_uproar_send_control(dev,USB_UPROAR_COMMAND,0); + usb_uproar_send_message(dev,msg,2); + usb_uproar_send_control(dev, USB_UPROAR_COMMAND,USB_UPROAR_ENDTRANSIND); + usb_uproar_send_control(dev, USB_UPROAR_RESPONSE,0); + actuallength=usb_uproar_recv_message(dev,msg,60); + memcpy(&plistsize,msg+2,2); + plistsize=__be16_to_cpu(plistsize); +/* info("Getting playlist of size %d.",plistsize); */ + plistsize=((plistsize/64)+(plistsize%64?1:0))*64; +/* info("Next multiple of 64 is %d.",plistsize); */ + plist=kmalloc(plistsize,GFP_KERNEL); + usb_uproar_send_control(dev, USB_UPROAR_COMMAND,USB_UPROAR_ENDTRANSIND); + usb_uproar_send_control(dev, USB_UPROAR_INITIATE, USB_UPROAR_INITIND); + msg[0]=0x46; + usb_uproar_send_message(dev,msg,1); + usb_uproar_send_control(dev, USB_UPROAR_COMMAND,USB_UPROAR_ENDTRANSIND); + usb_uproar_send_control(dev, USB_UPROAR_PLAYLISTCOMP, USB_UPROAR_INITIND); + + /* Returns num of bytes put into buf. */ + + status = usb_bulk_msg (dev->udev, + usb_rcvbulkpipe (dev->udev, + dev->bulk_in_endpointAddr), + plist, plistsize, + &actuallength, HZ*10); + if (!status) { +/* info("Received stuff from device:%d",actuallength); */ + usb_uproar_send_control(dev, USB_UPROAR_COMMAND, USB_UPROAR_ENDTRANSIND); +/* for (x=0;x<plistsize;x++) { */ +/* info("%X %c %d",plist[x],plist[x]>0?plist[x]:'.',plist[x],plist[x]); */ +/* } */ + memcpy(&freespace, plist+4, 4); + freespace=__be32_to_cpu(freespace); + copy_to_user(free,&freespace,4); + kfree(plist); + return 0; + } + kfree(plist); + usb_uproar_send_control(dev, USB_UPROAR_COMMAND, USB_UPROAR_ENDTRANSIND); + return -1; /* Did not read successfully */ +} + +static int usb_uproar_format(struct usb_uproar * dev) { + int actuallength; + char msg[60]; + msg[0]=0x4d; + msg[1]=0x46; + usb_uproar_send_control(dev,USB_UPROAR_COMMAND,0); + usb_uproar_send_message(dev,msg,2); + usb_uproar_send_control(dev, USB_UPROAR_COMMAND,USB_UPROAR_ENDTRANSIND); + usb_uproar_send_control(dev, USB_UPROAR_RESPONSE,0); + actuallength=usb_uproar_recv_message(dev,msg,60); + if ((actuallength != 2) || (msg[0]!=0x4d) || (msg[1]!=0x46)) { +/* info ("Device did not confirm correctly: actuallength %d, msg[0] %x, msg[1] +%x",actuallength,msg[0],msg[1]); */ + return -EBUSY; + } + usb_uproar_send_control(dev, USB_UPROAR_COMMAND,USB_UPROAR_ENDTRANSIND); + usb_uproar_send_control(dev, USB_UPROAR_INITIATE, USB_UPROAR_INITIND); + msg[0]=0x46; + usb_uproar_send_message(dev,msg,1); + usb_uproar_send_control(dev, USB_UPROAR_COMMAND,USB_UPROAR_ENDTRANSIND); + usb_uproar_send_control(dev, USB_UPROAR_PLAYLISTCOMP, USB_UPROAR_INITIND); + actuallength=usb_uproar_recv_message(dev,msg,60); + if ((actuallength != 1) || (msg[0]!=0x00)) { +/* info ("Device did not confirm correctly: actuallength %d, msg[0] +%x",actuallength,msg[0]); */ + return -EBUSY; + } + usb_uproar_send_control(dev, USB_UPROAR_COMMAND, USB_UPROAR_ENDTRANSIND); + return 0; +} +static int usb_uproar_delete_file(struct usb_uproar * dev, char * trackID) { + char delmessage[60]; + char *cur; + cur=delmessage; + *cur=0x4d; + cur++; + *cur=0x45; + cur++; + copy_from_user(cur,trackID,MIN(strlen(trackID),12)); + usb_uproar_send_control(dev,USB_UPROAR_COMMAND,0); + usb_uproar_send_message(dev,delmessage,2+MIN(strlen(trackID),12)); + usb_uproar_send_control(dev, USB_UPROAR_COMMAND,USB_UPROAR_ENDTRANSIND); + usb_uproar_send_control(dev, USB_UPROAR_RESPONSE,0); + usb_uproar_recv_message(dev,delmessage,60); + +/* for (x=0;x<60;x++) { */ +/* info("%X %c +%d",delmessage[x],delmessage[x]>0?delmessage[x]:'.',delmessage[x],delmessage[x]); */ +/* } */ + + usb_uproar_send_control(dev, USB_UPROAR_COMMAND,USB_UPROAR_ENDTRANSIND); + usb_uproar_send_control(dev, USB_UPROAR_INITIATE, USB_UPROAR_INITIND); + delmessage[0]=0x46; + usb_uproar_send_message(dev,delmessage,1); + usb_uproar_send_control(dev, USB_UPROAR_COMMAND,USB_UPROAR_ENDTRANSIND); + usb_uproar_send_control(dev, USB_UPROAR_PLAYLISTCOMP, USB_UPROAR_INITIND); + usb_uproar_recv_message(dev,delmessage,1); +/* for (x=0;x<60;x++) { */ +/* info("%X %c +%d",delmessage[x],delmessage[x]>0?delmessage[x]:'.',delmessage[x],delmessage[x]); */ +/* } */ + if (delmessage[0]!='\0') { +/* info ("Error: device responded with: %d\n",delmessage[0]); */ + } + usb_uproar_send_control(dev, USB_UPROAR_COMMAND,USB_UPROAR_ENDTRANSIND); + return 0; +} + +static int usb_uproar_send_file(struct usb_uproar * dev, uproar_fileinfo * ufi) { + /* We have the semaphore (invoked from ioctl) */ + char* cur; + char* curtn; + uproar_fileinfo fi; + int x; + __u32 betsize; + char sendfilemessage[124]=USB_UPROAR_MAGIC; + + copy_from_user(&fi,ufi,sizeof(uproar_fileinfo)); + cur=sendfilemessage+9; +/* info ("ts:%d",fi.tracksize); */ + betsize=__cpu_to_be32(fi.tracksize); + memcpy(cur,&betsize,4); + cur+=4; + *cur=0x32; + cur++; + *cur='\0'; + cur++; + *cur=MIN(strlen(fi.trackID),12); + cur++; + memcpy(cur,&fi.trackID,MIN(strlen(fi.trackID),12)); + cur+=MIN(strlen(fi.trackID),12); + *cur='\0'; + cur++; + *cur=MIN(strlen(fi.trackName)*2,66); + cur++; + curtn=fi.trackName; + for (x=0;x<MIN(strlen(fi.trackName),34);x++) { + *cur=*curtn; + cur++; + curtn++; + *cur='\0'; + cur++; + } +/* for (x=0;x<cur-sendfilemessage;x++) { */ +/* info("%X %c +%d",sendfilemessage[x],sendfilemessage[x]>0?sendfilemessage[x]:'.',sendfilemessage[x],sendfilemessage[x]); + */ +/* } */ + + usb_uproar_send_control(dev, USB_UPROAR_COMMAND,0); + usb_uproar_send_message(dev,sendfilemessage,cur-sendfilemessage); + usb_uproar_send_control(dev, USB_UPROAR_COMMAND,USB_UPROAR_ENDTRANSIND); + usb_uproar_send_control(dev, USB_UPROAR_RESPONSE,0); + usb_uproar_recv_message(dev,sendfilemessage,64); +/* for (x=0;x<64;x++) { */ +/* info("%X %c +%d",sendfilemessage[x],sendfilemessage[x]>0?sendfilemessage[x]:'.',sendfilemessage[x],sendfilemessage[x]); + */ +/* } */ + usb_uproar_send_control(dev, USB_UPROAR_COMMAND,USB_UPROAR_ENDTRANSIND); + usb_uproar_send_control(dev, USB_UPROAR_TRACKDATA,0); + dev->bytesleft=fi.tracksize; + dev->offset=0; + return 0; +} +static int usb_uproar_recv_message(struct usb_uproar * dev,void *buf, int size) { + /* Returns num of bytes put into buf. */ + int status; + int actuallength; + struct usb_uproar_message msg; + + status = usb_bulk_msg (dev->udev, + usb_rcvbulkpipe (dev->udev, + dev->bulk_in_endpointAddr), + &msg, dev->bulk_in_size, + &actuallength, HZ*10); + if (!status) { +/* info("Received stuff from device:%d, size: %d",actuallength,msg.len); */ + if ((msg.len-2)<=size) { + memcpy(buf,msg.buf,msg.len-2); + return msg.len-2; + } else { + memcpy(buf,msg.buf,size-1); + return size-1; /* Buffer too small or just right*/ + } + } + return -1; /* Did not read successfully */ +} + + +static int usb_uproar_send_message(struct usb_uproar *dev, char *payload, int len) { + char ext[64]; + char * tmp; + int x; + int status; + struct usb_uproar_message msg; + /* if (len+5 < sizeof(msg)) { */ + memset(&msg,0,sizeof(msg)); + msg.pad1=0x23; + msg.len=len+2; + msg.pad2=0x3a; +/* info ("sizeof(msg)%d",sizeof(msg)); */ + memcpy(msg.buf,payload,MIN(len,60)); + + if (len+5 < sizeof(msg)) { + msg.buf[len]=0x2e; /* Terminator */ + } else { + /* Need an extension buffer */ + memcpy(ext,payload+60,MIN(len-60,63)); + ext[MIN(len-60,63)]=0x2e; /* Terminator */ + } + tmp=(char *)&msg; + for (x=0;x<64;x++) { +/* info("%X %c %d",tmp[x],tmp[x]>0?tmp[x]:'.',tmp[x],tmp[x]); */ + } + + FILL_BULK_URB(dev->write_urb, dev->udev, + usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr), + &msg, sizeof(msg), + uproar_write_callback, dev); + status=usb_submit_urb(dev->write_urb); +/* info("Submitted URB. sleeping status:%d",status); */ + wait_event_interruptible(dev->wq, + (dev->write_urb->status!=-EINPROGRESS)); + if (len+5 >= sizeof(msg)) { + /* Send the extension */ + FILL_BULK_URB(dev->write_urb, dev->udev, + usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr), + ext, sizeof(ext), + uproar_write_callback, dev); + status=usb_submit_urb(dev->write_urb); +/* info("Submitted extension URB. sleeping status:%d",status); */ + wait_event_interruptible(dev->wq, + (dev->write_urb->status!=-EINPROGRESS)); + } + return dev->write_urb->status; +} + +static int usb_uproar_send_control(struct usb_uproar * dev, int request, int index) { + int status; + devrequest dr; + char response; + + dr.requesttype=0xC0; + dr.request=request; + dr.value=0x0; + dr.index=index; + dr.length=0x1; + FILL_CONTROL_URB(dev->write_urb, + dev->udev, + usb_rcvctrlpipe(dev->udev,0), + (unsigned char *)&dr, + &response, + 1, + uproar_write_callback, + dev); +/* info("Submitting URB"); */ + status=usb_submit_urb(dev->write_urb); +/* info("Submitted URB. sleeping status:%d",status); */ + wait_event_interruptible(dev->wq,(dev->write_urb->status!=-EINPROGRESS)); +/* info("Status: %d Device said: %d",dev->write_urb->status, response); */ + if (response==0x40) { + return 0; + } else { + return -1; + } +} + +static int uproar_get_devinfo(struct usb_uproar *dev, char * buf, size_t size) { + int status; + char devinfo=USB_UPROAR_DEVINFO; + if (!(status=usb_uproar_send_control(dev,USB_UPROAR_COMMAND,0))) { +/* info ("Device is happy"); */ + if (!(status=usb_uproar_send_message(dev,&devinfo,1))) { + /* We're happy */ +/* info ("Device happy, ending transaction"); */ + if (!(status=usb_uproar_send_control(dev,USB_UPROAR_COMMAND, + USB_UPROAR_ENDTRANSIND))) { + if (!(status=usb_uproar_send_control(dev,USB_UPROAR_RESPONSE, + 0))) { +/* info("Device is happy, we now get bulk xfer"); */ + status=usb_uproar_recv_message(dev,buf,size); +/* info("stat:%d",status); */ + if (status>0) { + buf[status]='\0'; + if (!(status=usb_uproar_send_control(dev,USB_UPROAR_COMMAND, + USB_UPROAR_ENDTRANSIND))) { +/* info("Device is happy, we finished xaction"); */ + } else { +/* info ("D'oh!"); */ + } + } else { +/* info ("D'oh-2"); */ + } + } else { +/* info("Shouldn't get here"); */ + } + } + } + } + return 0; +} +/** + * uproar_probe + * + * Called by the usb core when a new device is connected that it thinks + * this driver might be interested in. + */ +static void * uproar_probe(struct usb_device *udev, unsigned int ifnum, const struct +usb_device_id *id) +{ + char devinfo[61]; + + struct usb_uproar *dev = NULL; + struct usb_interface *interface; + struct usb_interface_descriptor *iface_desc; + struct usb_endpoint_descriptor *endpoint; + int minor; + int buffer_size; + int i; + char name[10]; + + /* See if the device offered us matches what we can accept */ + if (((udev->descriptor.idVendor != USB_UPROAR_VENDOR_ID) || + (udev->descriptor.idProduct != USB_UPROAR_PRODUCT_ID)) && + ((udev->descriptor.idVendor != USB_YEPP_VENDOR_ID) || + (udev->descriptor.idProduct != USB_YEPP_PRODUCT_ID))) { + return NULL; + } + + /* select a "subminor" number (part of a minor number) */ + down (&minor_table_mutex); + for (minor = 0; minor < MAX_DEVICES; ++minor) { + if (minor_table[minor] == NULL) + break; + } + if (minor >= MAX_DEVICES) { + info ("Too many devices plugged in, can not handle this device."); + goto exit; + } + + /* allocate memory for our device state and intialize it */ + dev = kmalloc (sizeof(struct usb_uproar), GFP_KERNEL); + if (dev == NULL) { + err ("Out of memory"); + goto exit; + } + minor_table[minor] = dev; + + interface = &udev->actconfig->interface[ifnum]; + + init_MUTEX (&dev->sem); + init_MUTEX (&dev->readsem); + init_waitqueue_head(&dev->wq); + dev->udev = udev; + /* dev->interface = interface; */ + dev->minor = minor; + dev->bytesleft=0; + dev->offset=0; + dev->readbuffer=NULL; + /*dev->readoffset=0;*/ + /* set up the endpoint information */ + /* check out the endpoints */ + iface_desc = &interface->altsetting[0]; + for (i = 0; i < iface_desc->bNumEndpoints; ++i) { + endpoint = &iface_desc->endpoint[i]; + + if ((endpoint->bEndpointAddress & 0x80) && + ((endpoint->bmAttributes & 3) == 0x02)) { + /* we found a bulk in endpoint */ + buffer_size = endpoint->wMaxPacketSize; + dev->bulk_in_size = buffer_size; + dev->bulk_in_endpointAddr = endpoint->bEndpointAddress; + dev->bulk_in_buffer = kmalloc (buffer_size, GFP_KERNEL); + if (!dev->bulk_in_buffer) { + err("Couldn't allocate bulk_in_buffer"); + goto error; + } + } + + if (((endpoint->bEndpointAddress & 0x80) == 0x00) && + ((endpoint->bmAttributes & 3) == 0x02)) { + /* we found a bulk out endpoint */ + dev->write_urb = usb_alloc_urb(0); + if (!dev->write_urb) { + err("No free urbs available"); + goto error; + } + buffer_size = endpoint->wMaxPacketSize; + dev->bulk_out_size = buffer_size; + dev->bulk_out_endpointAddr = endpoint->bEndpointAddress; + dev->bulk_out_buffer = kmalloc (buffer_size, GFP_KERNEL); + if (!dev->bulk_out_buffer) { + err("Couldn't allocate bulk_out_buffer"); + goto error; + } + FILL_BULK_URB(dev->write_urb, udev, + usb_sndbulkpipe(udev, + endpoint->bEndpointAddress), + dev->bulk_out_buffer, buffer_size, + uproar_write_callback, dev); + } + } + + /* initialize the devfs node for this device and register it */ + sprintf(name, "uproar%d", dev->minor); + + dev->devfs = devfs_register (usb_devfs_handle, name, + DEVFS_FL_DEFAULT, USB_MAJOR, + USB_UPROAR_MINOR_BASE + dev->minor, + S_IFCHR | S_IRUSR | S_IWUSR | + S_IRGRP | S_IWGRP | S_IROTH, + &uproar_fops, NULL); + + /* let the user know what node this device is now attached to */ + info ("USB Uproar device now attached to USBUproar%d", dev->minor); + uproar_get_devinfo(dev,devinfo,61); + info("Device Identifier: '%s' found",devinfo); + goto exit; + +error: + uproar_delete (dev); + dev = NULL; + +exit: + up (&minor_table_mutex); + return dev; +} + + +/** + * uproar_disconnect + * + * Called by the usb core when the device is removed from the system. + */ +static void uproar_disconnect(struct usb_device *udev, void *ptr) +{ + struct usb_uproar *dev; + int minor; + + dev = (struct usb_uproar *)ptr; + + down (&minor_table_mutex); + down (&dev->sem); + + minor = dev->minor; + + /* if the device is not opened, then we clean up right now */ + if (!dev->open_count) { + uproar_delete (dev); + } else { + dev->udev = NULL; + up (&dev->sem); + } + + /* remove our devfs node */ + devfs_unregister(dev->devfs); + + info("USB Uproar #%d now disconnected", minor); + up (&minor_table_mutex); +} + + + +/** + * usb_uproar_init + */ +static int __init usb_uproar_init(void) +{ + int result; + + /* register this driver with the USB subsystem */ + result = usb_register(&uproar_driver); + if (result < 0) { + err("usb_register failed for the "__FILE__" driver. Error number %d", + result); + return -1; + } + + info(DRIVER_DESC " " DRIVER_VERSION); + return 0; +} + + +/** + * usb_uproar_exit + */ +static void __exit usb_uproar_exit(void) +{ + /* deregister this driver with the USB subsystem */ +/* info("Going Away"); */ + usb_deregister(&uproar_driver); +} + + +module_init (usb_uproar_init); +module_exit (usb_uproar_exit); + +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); + diff -Nru a/drivers/usb/uproarkern.h b/drivers/usb/uproarkern.h --- a/drivers/usb/uproarkern.h Wed Dec 31 17:00:00 1969 +++ b/drivers/usb/uproarkern.h Wed Apr 3 18:55:04 2002 @@ -0,0 +1,33 @@ +#ifndef _UPROAR_KERN +#define _UPROAR_KERN +#include <linux/ioctl.h> +#ifndef __KERNEL__ +#include <sys/types.h> +#endif + + +#ifndef __UPROAR_FI +#define __UPROAR_FI +struct uproar_fileinfo_t { + size_t tracksize; + char trackID[13]; + char trackName[34]; +}; +#endif + +typedef struct uproar_fileinfo_t uproar_fileinfo; + + +#define USB_UPROAR_MAGIC_IOCTL 'u' + +#define UPROAR_GETDEVINFO _IOR( USB_UPROAR_MAGIC_IOCTL, 0x20, char[29]) +#define UPROAR_SENDFILE _IOW(USB_UPROAR_MAGIC_IOCTL,0x21,uproar_fileinfo) +#define UPROAR_DELETEFILE _IOW(USB_UPROAR_MAGIC_IOCTL,0x22,char[13]) +#define UPROAR_GETPLAYLIST _IO(USB_UPROAR_MAGIC_IOCTL,0x23) +#define UPROAR_FORMAT _IO(USB_UPROAR_MAGIC_IOCTL,0x24) +#define UPROAR_GETCAP _IOR(USB_UPROAR_MAGIC_IOCTL,0x25,int) +#define UPROAR_GETFREE _IOR(USB_UPROAR_MAGIC_IOCTL,0x26,int) +//_IOW(USB_UPROAR_MAGIC_IOCTL,0x21,uproar_fileinfo) + + +#endif
msg05571/pgp00000.pgp
Description: PGP signature
