/** * (c) 2001-2004 Nathan Hjelm * v1.4 driver_standard.c * * Allows rioutil to communicate with the rio through kernel-level drivers. * * 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 distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. **/ #include "driver.h" #include #include #include #include #include /* moved this here since it is only internal to library */ #ifdef linux #include #define RIODEVICE "/dev/usb/rio" #elif defined(__FreeBSD__) #define RIODEVICE "/dev/urio" #elif defined(__NetBSD__) #define RIODEVICE "/dev/urio" #elif defined(__MacOSX__) #define RIODEVICE "" #endif /* Device descriptor */ struct usb_device_descriptor { u_int8_t bLength; u_int8_t bDescriptorType; u_int16_t bcdUSB; u_int8_t bDeviceClass; u_int8_t bDeviceSubClass; u_int8_t bDeviceProtocol; u_int8_t bMaxPacketSize0; u_int16_t idVendor; u_int16_t idProduct; u_int16_t bcdDevice; u_int8_t iManufacturer; u_int8_t iProduct; u_int8_t iSerialNumber; u_int8_t bNumConfigurations; }; #if !defined(bswap_16) short bswap_16 (short x) { short y; char *xp = (char *)&x, *yp = (char *)xp; yp[0] = xp[1]; yp[1] = xp[0]; return y; } #endif void usb_close_rio (rios_t *rio) { struct rioutil_usbdevice *dev = (struct rioutil_usbdevice *)rio->dev; close ((int)dev->dev); free (dev); } int read_bulk (rios_t *rio, unsigned char *buffer, u_int32_t size) { struct rioutil_usbdevice *dev = (struct rioutil_usbdevice *)rio->dev; if (dev) return read ((int)dev->dev, buffer, size); else return -1; } int write_bulk (rios_t *rio, unsigned char *buffer, u_int32_t size) { struct rioutil_usbdevice *dev = (struct rioutil_usbdevice *)rio->dev; if (dev) return write ((int)dev->dev, buffer, size); else return -1; } int usb_open_rio (rios_t *rio, int number) { char fileName[FILENAME_MAX+2]; struct rioutil_usbdevice *plyr; int fd; struct player_device_info *p; struct usb_device_descriptor desc; int id_product, id_vendor; snprintf(fileName, FILENAME_MAX, "%s%i", RIODEVICE, number); fd = open(fileName, O_RDWR, 0666); if (fd < 0) { perror ("rio_open"); return -1; } if (ioctl(fd, USB_REQ_GET_DESCRIPTOR, desc) < 0) { rio_log (rio, -errno, "couldn't get device descriptor for %s: %s\n", fileName, strerror(errno)); close (fd); return -errno; } #if BYTE_ORDER==BIG_ENDIAN id_product = bswap_16 (dev.idProduct); id_vendor = bswap_16 (dev.idVendor); #else id_product = desc.idProduct; id_vendor = desc.idVendor; #endif for (p = &player_devices[0] ; p->vendor_id ; p++) if (desc.idVendor == p->vendor_id && desc.idProduct == p->product_id) break; if (p->vendor_id == 0) { close (fd); return -1; } plyr = (struct rioutil_usbdevice *)calloc(1, sizeof(struct rioutil_usbdevice)); plyr->dev = (void *)fd; plyr->entry = p; rio->dev = (void *)plyr; return 0; } int control_msg(rios_t *rio, u_int8_t direction, u_int8_t request, u_int16_t value, u_int16_t index, u_int16_t length, unsigned char *buffer) { struct rioutil_usbdevice *dev = (struct rioutil_usbdevice *)rio->dev; struct RioCommand cmd; int ret = 0; cmd.timeout = 50; cmd.requesttype = 0; /* low level usb req. type. */ cmd.request = request; /* the actualy request */ cmd.value = value; /* value?? */ cmd.index = index; /* indexy thingy */ cmd.length = 0x0c; /* length? */ cmd.buffer = buffer; if ( ioctl ((int)dev->dev, RIO_RECV_COMMAND, &cmd) < 0) ret = errno; return URIO_SUCCESS; } void usb_setdebug(int i) { }