diff options
| author | Michael Brown | 2006-03-17 15:09:45 +0100 |
|---|---|---|
| committer | Michael Brown | 2006-03-17 15:09:45 +0100 |
| commit | a2b15fd1febc77aecfc99b9d366b13f0bc17bebd (patch) | |
| tree | 47cef6e48756f1d39f6404af8de70023a72c10bb /src/filo/usb | |
| parent | Prefix semantics have changed (diff) | |
| download | ipxe-a2b15fd1febc77aecfc99b9d366b13f0bc17bebd.tar.gz ipxe-a2b15fd1febc77aecfc99b9d366b13f0bc17bebd.tar.xz ipxe-a2b15fd1febc77aecfc99b9d366b13f0bc17bebd.zip | |
GPXE code cleanup and purge.
Diffstat (limited to 'src/filo/usb')
| -rw-r--r-- | src/filo/usb/debug_x.c | 433 | ||||
| -rw-r--r-- | src/filo/usb/debug_x.h | 18 | ||||
| -rw-r--r-- | src/filo/usb/ohci.c | 1437 | ||||
| -rw-r--r-- | src/filo/usb/ohci.h | 316 | ||||
| -rw-r--r-- | src/filo/usb/scsi.h | 226 | ||||
| -rw-r--r-- | src/filo/usb/scsi_cmds.c | 512 | ||||
| -rw-r--r-- | src/filo/usb/scsi_cmds.h | 14 | ||||
| -rw-r--r-- | src/filo/usb/uhci.c | 1143 | ||||
| -rw-r--r-- | src/filo/usb/uhci.h | 175 | ||||
| -rw-r--r-- | src/filo/usb/usb.c | 803 | ||||
| -rw-r--r-- | src/filo/usb/usb.h | 435 | ||||
| -rw-r--r-- | src/filo/usb/usb_scsi_low.c | 172 | ||||
| -rw-r--r-- | src/filo/usb/usb_scsi_low.h | 10 | ||||
| -rw-r--r-- | src/filo/usb/usb_x.c | 163 |
14 files changed, 0 insertions, 5857 deletions
diff --git a/src/filo/usb/debug_x.c b/src/filo/usb/debug_x.c deleted file mode 100644 index 95a80b0a9..000000000 --- a/src/filo/usb/debug_x.c +++ /dev/null @@ -1,433 +0,0 @@ -#ifdef USB_DISK -/******************************************************************************* - * - * - * Copyright 2003 Steven James <pyro@linuxlabs.com> and - * LinuxLabs http://www.linuxlabs.com - * - * 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 <etherboot.h> -#include <pci.h> -#include <timer.h> -#include <lib.h> - -#define DEBUG_THIS DEBUG_USB -#include <debug.h> - -#define DPRINTF debug - -#include "usb.h" -#include "uhci.h" -#include "debug_x.h" - -//#include <string.h> - - -void dump_link( link_pointer_t *link, char *prefix) -{ - DPRINTF("%saddr: %08x\n", prefix, MEM_ADDR(link->link) ); - DPRINTF("%s raw addr: %04x\n", prefix, (link->link) <<4 ); - DPRINTF("%sterminate: %x\n", prefix, link->terminate); - DPRINTF("%squeue: %x\n", prefix, link->queue); - DPRINTF("%sdepth: %x\n", prefix, link->depth); -} - -void dump_frame_list( link_pointer_t *addr, char *prefix) -{ - int i; - - DPRINTF("%sFRAMELIST:\n",prefix); - - for(i=0;i<10; i++) { - dump_link(addr+i, prefix); - if(addr[i].queue) - dump_queue_head( MEM_ADDR(addr[i].link), ""); - else - dump_td( MEM_ADDR(addr[i].link), ""); - } -} - -void dump_hex(uchar *data, int len, char *prefix) -{ - int i=0; - - while(i<len) { - if(!i%16) { - DPRINTF("\n%s %04x: ", prefix, i); - } - else { - DPRINTF(": "); - } - - DPRINTF("%02x", data[i++]); - } - - DPRINTF("\n"); -} - -void dump_uhci(uint32_t port) -{ -#if 0 - unsigned long value; -#endif - - DPRINTF("HCI at %08x\n", port); -#if 0 - value = inw(port); - DPRINTF("Command: %04x\n", value); - - value = inw(port+2); - DPRINTF("USBSTS: %04x\n", value); - - value = inw(port+4); - DPRINTF("USBINTR: %04x\n", value); - - value = inw(port+6); - DPRINTF("FRNUM: %04x\n", value); - - value = inl(port+8); - DPRINTF("FLBASEADD: %08x\n", value); - - value = inb(port+0x0c); - DPRINTF("SOFMOD: %02x\n", value); - - value = inw(port+0x10); - DPRINTF("PORTSTS1: %04x\n", value); - - value = inw(port+0x12); - DPRINTF("PORTSTS2: %04x\n", value); - -#endif - -} - -void dump_td( td_t *td, char *prefix) -{ - char newpre[64]; - - newpre[0]='\t'; - strcpy(newpre+1, prefix); - - DPRINTF("%sTD(%08x):\n", prefix, td); - - switch(td->packet_type) { - case SETUP_TOKEN: - DPRINTF("%stype: SETUP\n", prefix); - break; - case OUT_TOKEN: - DPRINTF("%stype: OUT\n", prefix); - break; - case IN_TOKEN: - DPRINTF("%stype: IN\n", prefix); - break; - default: - DPRINTF("%stype: INVALID (%02x)\n", prefix, td->packet_type); - break; - } - - DPRINTF("%sretries: %x\n", prefix, td->retrys); - - if(td->isochronous) { - DPRINTF("%sisochronous\n", prefix); - } - - if(td->interrupt) { - DPRINTF("%sIOC\n", prefix); - } - - if(td->lowspeed) { - DPRINTF("%slowspeed\n", prefix); - } - - if(td->detect_short) { - DPRINTF("%sDETECT_SHORT\n", prefix); - } - - DPRINTF("%sactive: %04x\n", prefix, td->active); - DPRINTF("%sdevice_addr: %02x\n", prefix, td->device_addr); - DPRINTF("%sendpoint: %1x\n", prefix, td->endpoint); - DPRINTF("%sdata_toggle: %1x\n", prefix, td->data_toggle); - DPRINTF("%smax_transfer: %x\n", prefix, td->max_transfer); - DPRINTF("%sactual: %x\n", prefix, td->actual); - DPRINTF("%slink:\n", prefix); - - if(td->stall) { - DPRINTF("%sSTALL\n", prefix); - } - - if(td->bitstuff) { - DPRINTF("%sBITSTUFF ERROR\n", prefix); - } - - if(td->crc) { - DPRINTF("%sCRC ERROR\n", prefix); - } - - if(td->nak) { - DPRINTF("%sNAK ERROR\n", prefix); - } - - if(td->babble) { - DPRINTF("%sBABBLE ERROR\n", prefix); - } - - if(td->buffer_error) { - DPRINTF("%sBUFFER ERROR\n", prefix); - } - - if(MEM_ADDR(td->link.link) == td) { - DPRINTF("link loops back to me!\n"); - return; - } - - dump_link(&(td->link), newpre); - if(!td->link.terminate) { - if(td->link.queue) - dump_queue_head(MEM_ADDR(td->link.link), prefix ); - else - dump_td(MEM_ADDR(td->link.link), prefix); - } -} - -void dump_queue_head( queue_head_t *qh, char *prefix) -{ - char newpre[64]; - - newpre[0] = '\t'; - strcpy(newpre+1, prefix); - - DPRINTF("%sQUEUE HEAD(%x):\n", prefix, qh); - DPRINTF("%sdepth:\n", prefix); - dump_link( &(qh->depth), newpre); - - if(!qh->depth.terminate) { - if(qh->depth.queue) { - dump_queue_head(MEM_ADDR(qh->depth.link), newpre); - } - else { - dump_td( MEM_ADDR(qh->depth.link), newpre); - } - } - - - DPRINTF("%sbredth:\n", prefix); - dump_link( &(qh->bredth), newpre); - if(!qh->bredth.terminate) { - if(qh->bredth.queue) { - dump_queue_head(MEM_ADDR(qh->bredth.link), newpre); - } - else { - dump_td( MEM_ADDR(qh->bredth.link), newpre); - } - } -} - -void dump_transaction( transaction_t *trans, char *prefix) -{ - char newpre[64]; - - newpre[0] = '\t'; - strcpy(newpre+1, prefix); - - - DPRINTF("%s TRANSACTION(%x):\n", prefix, trans); - dump_queue_head( trans->qh, newpre); - - DPRINTF("%s TDs:\n", prefix); - dump_td( trans->td_list, newpre); - - DPRINTF("\n"); - if(trans->next) - dump_transaction(trans->next, prefix); -} - -void dump_usbdev( usbdev_t *dev, char *prefix) -{ - char newpre[64]; - int i; - - newpre[0] = '\t'; - strcpy(newpre+1, prefix); - - DPRINTF("%saddress: %x\n", prefix, dev->address); - DPRINTF("%sclass: %x\n", prefix, dev->class); - DPRINTF("%ssubclass: %x\n", prefix, dev->subclass); - DPRINTF("%sbulk_in: %x\n", prefix, dev->bulk_in); - DPRINTF("%sbulk_out: %x\n", prefix, dev->bulk_out); - DPRINTF("%sinterrupt: %x\n", prefix, dev->interrupt); - - DPRINTF("%sep toggle:\n", prefix); - for(i=0;i<MAX_EP;i++) { - DPRINTF("%s%x\n", newpre, dev->toggle[i]); - } - - DPRINTF("%sep max_packet:\n", prefix); - for(i=0;i<MAX_EP;i++) { - DPRINTF("%s%x\n", newpre, dev->max_packet[i]); - } -} - -void dump_all_usbdev(char *prefix) -{ - int i; - - for(i=0;i<MAX_USB_DEV;i++) { - if(usb_device[i].address) { - DPRINTF("%sDEVICE: %x\n", prefix, i); - dump_usbdev( usb_device +i, prefix); - } - } -} - -void dump_device_descriptor( device_descriptor_t *des, char *prefix) -{ - DPRINTF("%sbLength: %02x\n", prefix, des->bLength); - DPRINTF("%stype: %02x\n", prefix, des->type); - DPRINTF("%sbcdVersion: %1x%1x\n", prefix, des->bcdVersion[1], des->bcdVersion[0]); - DPRINTF("%sClass: %02x\n",prefix, des->Class); - DPRINTF("%sSubClass: %02x\n",prefix, des->SubClass); - DPRINTF("%sprotocol: %02x\n",prefix, des->protocol); - DPRINTF("%smax_packet: %x\n",prefix, des->max_packet); - DPRINTF("%sidVendor: %04x\n", prefix, des->idVendor); - DPRINTF("%sidProduct: %04x\n", prefix, des->idProduct); - DPRINTF("%sbcdDeviceVersion: %1x%1x\n", prefix, des->bcdDevice[1], des->bcdDevice[0]); - DPRINTF("%siManufacturor: %02x\n", prefix, des->iManufacturor); - DPRINTF("%siProduct: %02x\n", prefix, des->iProduct); - DPRINTF("%siSerial: %02x\n", prefix, des->iSerial); - DPRINTF("%sbNumConfig: %02x\n", prefix, des->bNumConfig); - -} - -void dump_interface_descriptor( interface_descriptor_t *iface, char *prefix) -{ - - DPRINTF("%sbLength: %02x\n", prefix, iface->bLength); - DPRINTF("%stype: %02x\n", prefix, iface->type); - DPRINTF("%sbInterfaceNumber: %02x\n", prefix, iface->bInterfaceNumber); - DPRINTF("%sbAlternateSetting: %02x\n", prefix, iface->bAlternateSetting); - DPRINTF("%sbNumEndpoints: %02x\n", prefix, iface->bNumEndpoints); - DPRINTF("%sbInterfaceClass: %02x\n", prefix, iface->bInterfaceClass); - DPRINTF("%sbInterfaceSubClass: %02x\n", prefix, iface->bInterfaceSubClass); - DPRINTF("%sbInterfaceProtocol: %02x\n", prefix, iface->bInterfaceProtocol); - DPRINTF("%siInterface: %02x\n", prefix, iface->iInterface); -} - -void dump_endpoint_descriptor( endpoint_descriptor_t *ep, char *prefix) -{ - - DPRINTF("%sbLength: %02x\n", prefix, ep->bLength); - DPRINTF("%stype: %02x\n", prefix, ep->type); - DPRINTF("%sbEndpointAddress: %02x\n", prefix, ep->bEndpointAddress); - DPRINTF("%sbmAttributes: %02x\n", prefix, ep->bmAttributes); - DPRINTF("%swMaxPacketSize: %02x\n", prefix, ep->wMaxPacketSize); - DPRINTF("%sbInterval: %02x\n", prefix, ep->bInterval); -} - -void dump_config_descriptor( uchar *des, char *prefix) // YES uchar * -{ - config_descriptor_t *config; - interface_descriptor_t *iface; - endpoint_descriptor_t *ep; - char newpre[64]; - int i; - - memset(newpre,0,sizeof(newpre)); - newpre[0] = '\t'; - strcpy(newpre+1, prefix); - - config = (config_descriptor_t *) des; - iface = (interface_descriptor_t *) (des + config->bLength); - ep = (endpoint_descriptor_t *) (des + config->bLength + iface->bLength); - - // now, the config itself - DPRINTF("%sbLength: %02x\n", prefix, config->bLength); - DPRINTF("%stype: %02x\n", prefix, config->type); - DPRINTF("%swTotalLength: %04x\n", prefix, config->wTotalLength); - DPRINTF("%sbNumInterfaces: %02x\n", prefix, config->bNumInterfaces); - DPRINTF("%sbConfigurationValue: %02x\n", prefix, config->bConfigurationValue); - DPRINTF("%siConfiguration: %02x\n", prefix, config->iConfiguration); - DPRINTF("%sbmAttributes: %02x\n", prefix, config->bmAttributes); - - DPRINTF("%sbMaxPower: %02x\n", prefix, config->bMaxPower); - - DPRINTF("\n%sInterface(%x):\n", prefix, iface); - dump_interface_descriptor(iface, newpre); - - newpre[1] = '\t'; - strcpy(newpre+2, prefix); - - for(i=0; i<iface->bNumEndpoints; i++) { - DPRINTF("\n%sEndpoint (%x):\n", newpre+1, ep+i); - dump_endpoint_descriptor( ep+i, newpre); - } -} - -// Some control message bmRequestType defines -#define CTRL_DEVICE 0 -#define CONTROL_INTERFACE 1 -#define CONTROL_ENDPOINT 2 -#define CONTROL_OTHER 3 -#define CONTROL_RECIPIENT_MASK 0x1f - -#define CONTROL_TYPE_STD 0 -#define CONTROL_TYPE_CLASS 0x20 -#define CONTROL_CLASS_VENDOR 0x40 -#define CONTROL_CLASS_MASK 0x60 - -#define CONTROL_OUT 0 -#define CONTROL_IN 0x80 -#define CONTROL_DIR_MASK 0x80 - -// bRequest values -#define GET_STATUS 0 -#define CLEAR_FEATURE 1 -#define SET_FEATURE 3 -#define SET_ADDRESS 5 - -#define GET_DESCRIPTOR 6 -#define SET_DESCRIPTOR 7 - -#define GET_CONFIGURATION 8 -#define SET_CONFIGURATION 9 - -#define GET_INTERFACE 10 -#define SET_INTERFACE 11 - -#define SYNC_FRAME 12 - -// descriptor types -#define DEVICE_DESC 1 -#define CONFIGURATION_DESC 2 -#define STRING_DESC 3 -#define INTERFACE_DESC 4 -#define ENDPOINT_DESC 5 -#define OTHERSPEED_DESC 7 -#define POWER_DESC 8 - -// features -#define FEATURE_HALT 0 -void dump_ctrlmsg( ctrl_msg_t *msg, char *prefix) -{ - DPRINTF("%sbmRequestType: %02x\n", prefix, msg->bmRequestType); - DPRINTF("%sbRequest: %02x\n", prefix, msg->bRequest); - DPRINTF("%swValue: %04x\n", prefix, msg->wValue); - DPRINTF("%swIndex: %04x\n", prefix, msg->wIndex); - DPRINTF("%swLength: %04x\n", prefix, msg->wLength); -} - -#endif diff --git a/src/filo/usb/debug_x.h b/src/filo/usb/debug_x.h deleted file mode 100644 index 109daae0e..000000000 --- a/src/filo/usb/debug_x.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef _DEBUG_X_H -#define _DEBUG_X_H - -void dump_hex(uchar *data, int len, char *prefix); -void dump_link( link_pointer_t *link, char *prefix); -void dump_td( td_t *td, char *prefix); -void dump_queue_head( queue_head_t *qh, char *prefix); -void dump_transaction( transaction_t *trans, char *prefix); -void dump_usbdev( usbdev_t *dev, char *prefix); -void dump_uhci(uint32_t port); -//void dump_all_usbdev(char *prefix); -void dump_device_descriptor( device_descriptor_t *des, char *prefix); -void dump_interface_descriptor( interface_descriptor_t *iface, char *prefix); -void dump_endpoint_descriptor( endpoint_descriptor_t *ep, char *prefix); -void dump_config_descriptor( uchar *des, char *prefix); -void dump_ctrlmsg( ctrl_msg_t *msg, char *prefix); - -#endif diff --git a/src/filo/usb/ohci.c b/src/filo/usb/ohci.c deleted file mode 100644 index 5c84c6376..000000000 --- a/src/filo/usb/ohci.c +++ /dev/null @@ -1,1437 +0,0 @@ -#ifdef USB_DISK - -/******************************************************************************* - * - * - * Copyright 2003 Steven James <pyro@linuxlabs.com> and - * LinuxLabs http://www.linuxlabs.com - * - * 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 <etherboot.h> -#include <pci.h> -#include <timer.h> -#include <lib.h> - -#define DEBUG_THIS DEBUG_USB -#include <debug.h> - -#define DPRINTF debug - -#define DEBUG_TD 0 -#define DEBUG_ED 0 - - -#include "usb.h" -#include "ohci.h" - - -extern int usec_offset; - -ohci_regs_t *ohci_regs; - -// It will clear the enable bit -void ohc_clear_stat(uchar dev) -{ - uint32_t value; - ohci_regs = (ohci_regs_t *)hc_base[dev]; - - value = readl(&ohci_regs->cmdstatus); - writel(value, &ohci_regs->cmdstatus); -} - -void clear_oport_stat(uint32_t port) -{ - uint32_t value; - - value = readl(port); - writel(value, port); -} - -void oport_suspend( uint32_t port) -{ - writel( RH_PS_PSS, port); - -} -void oport_wakeup( uint32_t port) -{ - writel( RH_PS_POCI, port); - -} -#if 0 -void oport_resume( uint32_t port) -{ - uint32_t value; - - value = readl(port); - value |= 0x40; - writel(value, port); - udelay(20000+usec_offset); - value &= ~0x40; - writel(value, port); - - do { - value = readl(port); - } while(value & 0x40); -} -#endif -void oport_enable( uint32_t port) -{ - uint32_t value; - - value = readl(port); - - if((value & RH_PS_CCS)) { // if connected - writel( RH_PS_PES, port); - udelay(10); - writel( RH_PS_PESC, port); // Clear Change bit - } - -} - - - -void oport_disable( uint32_t port) -{ - writel( RH_PS_CCS, port); -} - -void oport_reset(uint32_t port) -{ - - uint32_t value; - - writel( RH_PS_PRS, port); - do { - value = readl( port ); - } while (!(value & RH_PS_PRSC) ); - writel(RH_PS_PRSC, port); //Clear Change bit - -} - -void oport_reset_long(uint32_t port) -{ - oport_reset(port); -} - -#if 0 - -int ohc_stop(uchar dev) -{ - unsigned short tmp; - uint32_t ctl; - - ohci_regs = hc_base[dev]; - - ctl = readl( &ohci_regs->control); - ctl &= ~(OHCI_CTRL_PLE|OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_IE); - writel (ctl, &ohci_regs->control); - - return(0); -} -#endif - - -#define MAX_OHCI_TD 32 - -ohci_td_t *_ohci_td; -uint8_t _ohci_td_tag[MAX_OHCI_TD]; //1: used, 0:unused - -void init_ohci_td(){ - _ohci_td = allot2(sizeof(ohci_td_t)*MAX_OHCI_TD, 0x1f); // 32 byte aligna - if(_ohci_td==0) { - printf("init_ohci_td: NOMEM\n"); - } - memset(_ohci_td_tag, 0, sizeof(_ohci_td_tag)); -} - -ohci_td_t *td_alloc(ohci_t *ohci, int memflag){ - int i; - ohci_td_t *td; - for(i = 0; i< MAX_OHCI_TD; i++ ) { - if(_ohci_td_tag[i]==1) continue; - td = &_ohci_td[i]; - memset(td, 0, sizeof(ohci_td_t)); - td->td_dma = (void *)virt_to_phys(td); - _ohci_td_tag[i] = 1; - return td; - } - printf("td_alloc: no free slot\n"); - return 0; -} - -int td_free(ohci_t *ohci, ohci_td_t *td) { - int i; - for(i = 0; i< MAX_OHCI_TD; i++ ) { - if(_ohci_td_tag[i]==0) continue; - if(&_ohci_td[i] == td ) { - _ohci_td_tag[i] = 0; - return 1; - } - } - return 0; -} - - -struct ohci_td * -dma_to_td (struct ohci * hc, void *td_dma) -{ - int i; - ohci_td_t *td; - for(i = 0; i< MAX_OHCI_TD; i++ ) { - if(_ohci_td_tag[i]==0) continue; - td = &_ohci_td[i]; - if(td->td_dma == td_dma ) { - return td; - } - } - printf("dma_to_td: can not find td\n"); - return 0; - -} - -ohci_t _ohci_x[MAX_CONTROLLERS]; - -void ohci_init(void) -{ - init_ohci_td(); -} - -static int ohci_get_current_frame_number (struct usbdev *usb_dev) -{ - ohci_t * ohci = &_ohci_x[usb_dev->controller]; - - return le16_to_cpu (ohci->hcca->frame_no); -} - - - -static u32 roothub_a (struct ohci *hc) - { return readl (&hc->regs->roothub.a); } -static inline u32 roothub_b (struct ohci *hc) - { return readl (&hc->regs->roothub.b); } -static inline u32 roothub_status (struct ohci *hc) - { return readl (&hc->regs->roothub.status); } -static u32 roothub_portstatus (struct ohci *hc, int i) - { return readl (&hc->regs->roothub.portstatus[i]);} - - -#if DEBUG_USB==1 - -#define OHCI_VERBOSE_DEBUG - -# define dbg(...) \ - do { printf(__VA_ARGS__); printf("\n"); } while (0) - -static void urb_print (struct urb * urb, char * str, int small) -{ - unsigned int pipe= urb->pipe; - - if (!urb->dev ) { - dbg("%s URB: no dev", str); - return; - } - -#ifndef OHCI_VERBOSE_DEBUG - if (urb->status != 0) -#endif - dbg("%s URB:[%4x] dev:%2d,ep:%2d-%c,type:%s,flags:%4x,len:%d/%d,stat:%d(%x)", - str, - ohci_get_current_frame_number (urb->dev), - usb_pipedevice (pipe), - usb_pipeendpoint (pipe), - usb_pipeout (pipe)? 'O': 'I', - usb_pipetype (pipe) < 2? (usb_pipeint (pipe)? "INTR": "ISOC"): - (usb_pipecontrol (pipe)? "CTRL": "BULK"), - urb->transfer_flags, - urb->actual_length, - urb->transfer_buffer_length, - urb->status, urb->status); -#ifdef OHCI_VERBOSE_DEBUG -// if (!small) { - int i, len; - - if (usb_pipecontrol (pipe)) { - printf ("ohci.c: cmd(8):"); - for (i = 0; i < 8 ; i++) - printf (" %02x", ((u8 *) urb->setup_packet) [i]); - printf ("\n"); - } - if (urb->transfer_buffer_length > 0 && urb->transfer_buffer) { - printf("ohci.c: data(%d/%d):", - urb->actual_length, - urb->transfer_buffer_length); - len = usb_pipeout (pipe)? - urb->transfer_buffer_length: urb->actual_length; - for (i = 0; i < 16 && i < len; i++) - printf (" %02x", ((u8 *) urb->transfer_buffer) [i]); - printf ("%s stat:%d\n", i < len? "...": "", urb->status); - } -// } -#endif -} - -/* just for debugging; prints non-empty branches of the int ed tree inclusive iso eds*/ -void ep_print_int_eds (ohci_t * ohci, char * str) { - int i, j; - u32 * ed_p; - for (i= 0; i < 32; i++) { - j = 5; - ed_p = &(ohci->hcca->int_table [i]); - if (*ed_p == 0) - continue; - printf ("ohci.c: %s branch int %2d(%2x):", str, i, i); -#if 0 - while (*ed_p != 0 && j--) { - ed_t *ed = dma_to_ed (ohci, le32_to_cpup(ed_p)); - printk (" ed: %4x;", ed->hwINFO); - ed_p = &ed->hwNextED; - } -#endif - printf ("\n"); - } -} -static void ohci_dump_intr_mask (char *label, u32 mask) -{ - dbg ("%s: 0x%08x%s%s%s%s%s%s%s%s%s", - label, - mask, - (mask & OHCI_INTR_MIE) ? " MIE" : "", - (mask & OHCI_INTR_OC) ? " OC" : "", - (mask & OHCI_INTR_RHSC) ? " RHSC" : "", - (mask & OHCI_INTR_FNO) ? " FNO" : "", - (mask & OHCI_INTR_UE) ? " UE" : "", - (mask & OHCI_INTR_RD) ? " RD" : "", - (mask & OHCI_INTR_SF) ? " SF" : "", - (mask & OHCI_INTR_WDH) ? " WDH" : "", - (mask & OHCI_INTR_SO) ? " SO" : "" - ); -} -static void maybe_print_eds (char *label, u32 value) -{ - if (value) - dbg ("%s %08x", label, value); -} -static char *hcfs2string (int state) -{ - switch (state) { - case OHCI_USB_RESET: return "reset"; - case OHCI_USB_RESUME: return "resume"; - case OHCI_USB_OPER: return "operational"; - case OHCI_USB_SUSPEND: return "suspend"; - } - return "?"; -} -// dump control and status registers -static void ohci_dump_status (ohci_t *controller) -{ - struct ohci_regs *regs = controller->regs; - u32 temp; - - temp = readl (®s->revision) & 0xff; - if (temp != 0x10) - dbg ("spec %d.%d", (temp >> 4), (temp & 0x0f)); - - temp = readl (®s->control); - dbg ("control: 0x%08x%s%s%s HCFS=%s%s%s%s%s CBSR=%d", temp, - (temp & OHCI_CTRL_RWE) ? " RWE" : "", - (temp & OHCI_CTRL_RWC) ? " RWC" : "", - (temp & OHCI_CTRL_IR) ? " IR" : "", - hcfs2string (temp & OHCI_CTRL_HCFS), - (temp & OHCI_CTRL_BLE) ? " BLE" : "", - (temp & OHCI_CTRL_CLE) ? " CLE" : "", - (temp & OHCI_CTRL_IE) ? " IE" : "", - (temp & OHCI_CTRL_PLE) ? " PLE" : "", - temp & OHCI_CTRL_CBSR - ); - - temp = readl (®s->cmdstatus); - dbg ("cmdstatus: 0x%08x SOC=%d%s%s%s%s", temp, - (temp & OHCI_SOC) >> 16, - (temp & OHCI_OCR) ? " OCR" : "", - (temp & OHCI_BLF) ? " BLF" : "", - (temp & OHCI_CLF) ? " CLF" : "", - (temp & OHCI_HCR) ? " HCR" : "" - ); - - ohci_dump_intr_mask ("intrstatus", readl (®s->intrstatus)); - ohci_dump_intr_mask ("intrenable", readl (®s->intrenable)); - // intrdisable always same as intrenable - // ohci_dump_intr_mask ("intrdisable", readl (®s->intrdisable)); - - maybe_print_eds ("ed_periodcurrent", readl (®s->ed_periodcurrent)); - - maybe_print_eds ("ed_controlhead", readl (®s->ed_controlhead)); - maybe_print_eds ("ed_controlcurrent", readl (®s->ed_controlcurrent)); - - maybe_print_eds ("ed_bulkhead", readl (®s->ed_bulkhead)); - maybe_print_eds ("ed_bulkcurrent", readl (®s->ed_bulkcurrent)); - - maybe_print_eds ("donehead", readl (®s->donehead)); -} - -static void ohci_dump_roothub (ohci_t *controller, int verbose) -{ - u32 temp, ndp, i; - - temp = roothub_a (controller); - if (temp == ~(u32)0) - return; - ndp = (temp & RH_A_NDP); - - if (verbose) { - dbg ("roothub.a: %08x POTPGT=%d%s%s%s%s%s NDP=%d", temp, - ((temp & RH_A_POTPGT) >> 24) & 0xff, - (temp & RH_A_NOCP) ? " NOCP" : "", - (temp & RH_A_OCPM) ? " OCPM" : "", - (temp & RH_A_DT) ? " DT" : "", - (temp & RH_A_NPS) ? " NPS" : "", - (temp & RH_A_PSM) ? " PSM" : "", - ndp - ); - temp = roothub_b (controller); - dbg ("roothub.b: %08x PPCM=%04x DR=%04x", - temp, - (temp & RH_B_PPCM) >> 16, - (temp & RH_B_DR) - ); - temp = roothub_status (controller); - dbg ("roothub.status: %08x%s%s%s%s%s%s", - temp, - (temp & RH_HS_CRWE) ? " CRWE" : "", - (temp & RH_HS_OCIC) ? " OCIC" : "", - (temp & RH_HS_LPSC) ? " LPSC" : "", - (temp & RH_HS_DRWE) ? " DRWE" : "", - (temp & RH_HS_OCI) ? " OCI" : "", - (temp & RH_HS_LPS) ? " LPS" : "" - ); - } - - for (i = 0; i < ndp; i++) { - temp = roothub_portstatus (controller, i); - dbg ("roothub.portstatus [%d] = 0x%08x%s%s%s%s%s%s%s%s%s%s%s%s", - i, - temp, - (temp & RH_PS_PRSC) ? " PRSC" : "", - (temp & RH_PS_OCIC) ? " OCIC" : "", - (temp & RH_PS_PSSC) ? " PSSC" : "", - (temp & RH_PS_PESC) ? " PESC" : "", - (temp & RH_PS_CSC) ? " CSC" : "", - - (temp & RH_PS_LSDA) ? " LSDA" : "", - (temp & RH_PS_PPS) ? " PPS" : "", - (temp & RH_PS_PRS) ? " PRS" : "", - (temp & RH_PS_POCI) ? " POCI" : "", - (temp & RH_PS_PSS) ? " PSS" : "", - - (temp & RH_PS_PES) ? " PES" : "", - (temp & RH_PS_CCS) ? " CCS" : "" - ); - } -} - -static void ohci_dump (ohci_t *controller, int verbose) -{ - dbg ("OHCI controller usb-%x state", controller->regs); - - // dumps some of the state we know about - ohci_dump_status (controller); - if (verbose) - ep_print_int_eds (controller, "hcca"); - dbg ("hcca frame #%04x", controller->hcca->frame_no); - ohci_dump_roothub (controller, 1); -} -void ohci_dump_x(uchar controller) -{ - ohci_t *ohci; - ohci = &_ohci_x[controller]; - ohci_dump (ohci, 1); -} -#endif - -/* link an ed into one of the HC chains */ - -/* ED is only enqueued and dequeued by HCD - So ep_link may only to be called two times for every device (function) -- ed, one for controled and one for bulked - one ohci may have several controled and bulked. -*/ - -int ep_link (ohci_t * ohci, ed_t * edi) -{ - volatile ed_t * ed = edi; - - ed->state = ED_OPER; - - switch (ed->type) { - case PIPE_CONTROL: - ed->hwNextED = 0; - if (ohci->ed_controltail == NULL) { -// debug("ep_link control 21 ed->dma = %x\n", (uint32_t)ed->dma); - writel ((uint32_t)ed->dma, &ohci->regs->ed_controlhead); - } else { -// debug("ep_link control 22 ed->dma = %x\n", (uint32_t)ed->dma); - ohci->ed_controltail->hwNextED = cpu_to_le32 ((uint32_t)ed->dma); - } - ed->ed_prev = ohci->ed_controltail; - if (!ohci->ed_controltail) { - /* enable control ed list */ - ohci->hc_control |= OHCI_CTRL_CLE; //5 - writel (ohci->hc_control, &ohci->regs->control); - } - ohci->ed_controltail = edi; - break; - - case PIPE_BULK: - ed->hwNextED = 0; - if (ohci->ed_bulktail == NULL) { - // debug("ep_link control 31 ed->dma = %x\n", (uint32_t)ed->dma); - writel ((uint32_t)ed->dma, &ohci->regs->ed_bulkhead); - } else { - // debug("ep_link control 32 ed->dma = %x\n", (uint32_t)ed->dma); - ohci->ed_bulktail->hwNextED = cpu_to_le32 ((uint32_t)ed->dma); - } - ed->ed_prev = ohci->ed_bulktail; - if (!ohci->ed_bulktail) { - /* enable bulk ed list */ - ohci->hc_control |= OHCI_CTRL_BLE; //5 - writel (ohci->hc_control, &ohci->regs->control); - } - ohci->ed_bulktail = edi; - break; - } - return 0; -} -/* add/reinit an endpoint; this should be done once at the usb_set_configuration command, - * but the USB stack is a little bit stateless so we do it at every transaction - * if the state of the ed is ED_NEW then a dummy td is added and the state is changed to ED_UNLINK - * in all other cases the state is left unchanged - * the ed info fields are setted anyway even though most of them should not change */ - -ed_t * ep_add_ed ( - usbdev_t * usb_dev, - unsigned int pipe, - int interval, - int load, - int mem_flags -) -{ - ohci_t * ohci = &_ohci_x[usb_dev->controller]; - ohci_td_t * td; - ed_t * ed; - unsigned long flags; - int i; - - /* We use preallocate ed in ohci struct - numbering rule ??? - */ - i = (usb_pipeendpoint (pipe) << 1) |(usb_pipecontrol (pipe)? 0: usb_pipeout (pipe)); - ed = (ed_t *)&ohci->ed[i]; - -// debug("ep_add_ed: usb_dev port=%x, controller = %d ohci=%x ohci->ed=%x ed=%x ed->dma=%x\n", usb_dev->port,usb_dev->controller, ohci, ohci->ed, ed, ed->dma); - - if (ed->state == ED_NEW) { - ed->hwINFO = cpu_to_le32 (OHCI_ED_SKIP); /* skip ed */ - /* dummy td; end of td list for ed */ - td = td_alloc (ohci, 0); - - ed->hwTailP = cpu_to_le32 ((uint32_t)td->td_dma); - ed->hwHeadP = ed->hwTailP; - ed->state = ED_UNLINK; - ed->type = usb_pipetype (pipe); - ohci->ed_cnt++; // we will be used to calcaulate next pipe - -// debug("ep_add_ed 1 td=%x dma=%x ed->dma=%x ed->hwHeadP=%x ed->hwTailP=%x\n", td, td->td_dma, ed->dma, ed->hwHeadP, ed->hwTailP); - - } - - ohci->dev[usb_pipedevice (pipe)] = usb_dev; // marked the ed to this dev - - ed->hwINFO = cpu_to_le32 (usb_pipedevice (pipe) - | usb_pipeendpoint (pipe) << 7 - | (usb_pipeisoc (pipe)? 0x8000: 0) - | (usb_pipecontrol (pipe)? 0: (usb_pipeout (pipe)? 0x800: 0x1000)) - | usb_pipeslow (pipe) << 13 - | usb_maxpacket (usb_dev, pipe, usb_pipeout (pipe)) << 16); - -// debug("ep_add_ed: pipe=%x ed_num=%d ed->dma=%x ed->hwInfo=%x ed->hwHeadP=%x ed->hwTailP=%x\n", pipe, i, ed->dma, ed->hwINFO, ed->hwHeadP, ed->hwTailP); - - return ed; -} - -/* enqueue next TD for this URB (OHCI spec 5.2.8.2) */ - -void -td_fill (ohci_t * ohci, unsigned int info, - void *data, int len, - struct urb * urb, int index) // *data should dma address of buffer -{ - ohci_td_t * td, * td_pt; - urb_priv_t * urb_priv = urb->hcpriv; - - if (index >= urb_priv->length) { - printf("internal OHCI error: TD index > length"); - return; - } - - /* use this td as the next dummy */ - td_pt = urb_priv->td [index]; - td_pt->hwNextTD = 0; - - /* fill the old dummy TD */ - td = urb_priv->td [index] = dma_to_td (ohci, - (void *)(le32_to_cpup (&urb_priv->ed->hwTailP) & ~0xf)); - -// debug("td_fill 2 td = %x, dma=%x , ed->hwHeadP=%x, ed->hwTailP=%x \n", td, td->td_dma, urb_priv->ed->hwHeadP, urb_priv->ed->hwTailP ); - - td->ed = urb_priv->ed; - td->next_dl_td = NULL; - td->index = index; - td->urb = urb; - td->data_dma = data; - if (!len) - data = 0; - - - td->hwINFO = cpu_to_le32 (info); - td->hwCBP = cpu_to_le32 ((uint32_t)data); - if (data) - td->hwBE = cpu_to_le32 ((uint32_t)data + len - 1); - else - td->hwBE = 0; - td->hwNextTD = cpu_to_le32 ((uint32_t)td_pt->td_dma); - - /* append to queue */ - td->ed->hwTailP = td->hwNextTD; - // debug("td_fill 4 td->td_dma=%x, td->hwINFO=%x\n", td->td_dma, td->hwINFO ); - // debug("td_fill 5 ed->dma=%x, ed->hwHeadP=%x, ed->hwTailP=%x \n", urb_priv->ed->dma, urb_priv->ed->hwHeadP, urb_priv->ed->hwTailP ); -} - -/* prepare all TDs of a transfer */ - -void td_submit_urb (struct urb * urb) -{ - urb_priv_t * urb_priv = urb->hcpriv; - ohci_t * ohci = (ohci_t *) &_ohci_x[urb->dev->controller]; - void * data; - int data_len = urb->transfer_buffer_length; - int cnt = 0; - u32 info = 0; - unsigned int toggle = 0; - void *setup_buffer; - - /* OHCI handles the DATA-toggles itself, we just use the USB-toggle bits for reseting */ - if(usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe))) { - toggle = TD_T_TOGGLE; - } else { - toggle = TD_T_DATA0; - usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe), 1); - } - - urb_priv->td_cnt = 0; - - if (data_len) { - data = (void *)virt_to_phys(urb->transfer_buffer); - } else - data = 0; - switch (usb_pipetype (urb->pipe)) { - case PIPE_BULK: - info = usb_pipeout (urb->pipe)? - TD_CC | TD_DP_OUT : TD_CC | TD_DP_IN ; - while(data_len > 4096) { - td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), data, 4096, urb, cnt); - data += 4096; data_len -= 4096; cnt++; - } - info = usb_pipeout (urb->pipe)? - TD_CC | TD_DP_OUT : TD_CC | TD_R | TD_DP_IN ; - td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), data, data_len, urb, cnt); - cnt++; -#if 0 - /* If the transfer size is multiple of the pipe mtu, - * we may need an extra TD to create a empty frame - * Note : another way to check this condition is - * to test if(urb_priv->length > cnt) - Jean II */ - if ((urb->transfer_flags & USB_ZERO_PACKET) && - usb_pipeout (urb->pipe) && - (urb->transfer_buffer_length != 0) && - ((urb->transfer_buffer_length % maxps) == 0)) { - td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), 0, 0, urb, cnt); - cnt++; - } -#endif - -// debug("td_submit_urb 2 -- set OHCI_BLF\n"); - writel (OHCI_BLF, &ohci->regs->cmdstatus); /* start bulk list */ - (void)readl (&ohci->regs->intrdisable); /* PCI posting flush */ - break; - - - case PIPE_CONTROL: - info = TD_CC | TD_DP_SETUP | TD_T_DATA0; - setup_buffer = (void *)virt_to_phys(urb->setup_packet); -// debug("td_sumbit_urb 11 setup_buffer = %x\n", setup_buffer); - td_fill (ohci, info, setup_buffer , 8, urb, cnt++); - if (data_len > 0) { - info = usb_pipeout (urb->pipe)? - TD_CC | TD_R | TD_DP_OUT | TD_T_DATA1 : TD_CC | TD_R | TD_DP_IN | TD_T_DATA1; - /* NOTE: mishandles transfers >8K, some >4K */ - td_fill (ohci, info, data, data_len, urb, cnt++); - } - info = usb_pipeout (urb->pipe)? - TD_CC | TD_DP_IN | TD_T_DATA1: TD_CC | TD_DP_OUT | TD_T_DATA1; - td_fill (ohci, info, data, 0, urb, cnt++); -// debug("td_sumbit_urb 11 data = %x\n", data); - -// debug("td_submit_urb 2 -- set OHCI_CLF\n"); - writel (OHCI_CLF, &ohci->regs->cmdstatus); /* start Control list */ - (void)readl (&ohci->regs->intrdisable); /* PCI posting flush */ - break; - - } - if (urb_priv->length != cnt) { - debug("TD LENGTH %d != CNT %d", urb_priv->length, cnt); - } -} - -/* free HCD-private data associated with this URB */ - -void urb_free_priv (struct ohci *hc, urb_priv_t * urb_priv) -{ - int i; - int last = urb_priv->length - 1; - int len; - struct ohci_td *td; - - if (last >= 0) { -#if 0 - /* ISOC, BULK, INTR data buffer starts at td 0 - * CTRL setup starts at td 0 */ - td = urb_priv->td [0]; - - len = td->urb->transfer_buffer_length; - - /* unmap CTRL URB setup */ - if (usb_pipecontrol (td->urb->pipe)) { -// it should be freed in usb_control_msg_x -// forget2((void *)phys_to_virt((uint32_t)td->data_dma)); // 8 bytes - - /* CTRL data buffer starts at td 1 if len > 0 */ - if (len && last > 0) - td = urb_priv->td [1]; - } - - /* unmap data buffer */ - if (len && td->data_dma) { -// Don't need -// forget2((void *)phys_to_virt((uint32_t)td->data_dma)); - } -#endif - - for (i = 0; i <= last; i++) { - td = urb_priv->td [i]; - if (td) - td_free (hc, td); - } - } -#if URB_PRE_ALLOCATE!=1 - forget2((void *)urb_priv); -#endif -} - -/* get a transfer request */ - -int ohci_submit_urb (struct urb * urb) -{ - ohci_t * ohci; - ed_t * ed; - urb_priv_t * urb_priv; - unsigned int pipe = urb->pipe; - int i, size = 0; - int mem_flags = 0; - - if (!urb->dev) - return -ENODEV; - - if (urb->hcpriv) /* urb already in use */ - return -EINVAL; - - - ohci = (ohci_t *) &_ohci_x[urb->dev->controller]; -// printf("ohci_submit_urb: urb->dev port=%x, controller = %d ohci=%x ohci->ed=%x ohci->hcca=%x\n", urb->dev->port,urb->dev->controller, ohci, ohci->ed, ohci->hcca); - -#if DEBUG_USB==1 -// urb_print (urb, "SUB", usb_pipein (pipe)); -#endif - - -#if 0 - /* handle a request to the virtual root hub */ - if (usb_pipedevice (pipe) == ohci->rh.devnum) - return rh_submit_urb (urb); - - /* when controller's hung, permit only roothub cleanup attempts - * such as powering down ports */ - if (ohci->disabled) { - usb_dec_dev_use (urb->dev); - return -ESHUTDOWN; - } -#endif - - /* every endpoint has a ed, locate and fill it */ - if (!(ed = ep_add_ed (urb->dev, pipe, urb->interval, 1, mem_flags))) { - return -ENOMEM; - } -// debug("ohci_submit_usb: ed->dma=%x\n", ed->dma); - - /* for the private part of the URB we need the number of TDs (size) */ - switch (usb_pipetype (pipe)) { - case PIPE_BULK: /* one TD for every 4096 Byte */ - size = (urb->transfer_buffer_length - 1) / 4096 + 1; -#if 0 - /* If the transfer size is multiple of the pipe mtu, - * we may need an extra TD to create a empty frame - * Jean II */ - if ((urb->transfer_flags & USB_ZERO_PACKET) && - usb_pipeout (pipe) && - (urb->transfer_buffer_length != 0) && - ((urb->transfer_buffer_length % maxps) == 0)) - size++; -#endif - break; - case PIPE_CONTROL: /* 1 TD for setup, 1 for ACK and 1 for every 4096 B */ - size = (urb->transfer_buffer_length == 0)? 2: - (urb->transfer_buffer_length - 1) / 4096 + 3; - break; - } - - /* allocate the private part of the URB */ -#if URB_PRE_ALLOCATE!=1 - urb_priv = allot2 (sizeof (urb_priv_t) + size * sizeof (ohci_td_t *), 0xff); - if (urb_priv == 0) { - printf("ohci_submit_usb: urb_priv allocated no mem\n"); - return -ENOMEM; - } -#else - urb_priv = ohci->urb_priv; -#endif - memset (urb_priv, 0, sizeof (urb_priv_t) + size * sizeof (ohci_td_t *)); - - /* fill the private part of the URB */ - urb_priv->length = size; - urb_priv->ed = ed; - - /* allocate the TDs (updating hash chains) */ - for (i = 0; i < size; i++) { - urb_priv->td[i] = td_alloc (ohci, 0); - if (!urb_priv->td[i]) { - urb_priv->length = i; - urb_free_priv (ohci, urb_priv); - return -ENOMEM; - } - } - - if (ed->state == ED_NEW || (ed->state & ED_DEL)) { - urb_free_priv (ohci, urb_priv); - return -EINVAL; - } - - urb->actual_length = 0; - urb->hcpriv = urb_priv; - urb->status = USB_ST_URB_PENDING; - /* link the ed into a chain if is not already */ - if (ed->state != ED_OPER) { - ep_link (ohci, ed); - } - - /* fill the TDs and link it to the ed */ - td_submit_urb (urb); - -#if 0 - /* drive timeouts by SF (messy, but works) */ - writel (OHCI_INTR_SF, &ohci->regs->intrenable); - (void)readl (&ohci->regs->intrdisable); /* PCI posting flush */ -#endif - - return 0; -} -/* calculate the transfer length and update the urb */ - -void dl_transfer_length(ohci_td_t * td) -{ - u32 tdINFO, tdBE, tdCBP; - struct urb * urb = td->urb; - urb_priv_t * urb_priv = urb->hcpriv; - - tdINFO = le32_to_cpup (&td->hwINFO); - tdBE = le32_to_cpup (&td->hwBE); - tdCBP = le32_to_cpup (&td->hwCBP); - - - if (!(usb_pipetype (urb->pipe) == PIPE_CONTROL && - ((td->index == 0) || (td->index == urb_priv->length - 1)))) { - if (tdBE != 0) { - if (td->hwCBP == 0) - urb->actual_length += tdBE - (uint32_t)td->data_dma + 1; - else - urb->actual_length += tdCBP - (uint32_t)td->data_dma; - } - - } - -// debug("td->td_dma=%x, urb->actual_length=%d\n", td->td_dma, urb->actual_length); -} - -/*-------------------------------------------------------------------------*/ - -/* replies to the request have to be on a FIFO basis so - * we reverse the reversed done-list */ - -ohci_td_t * dl_reverse_done_list (ohci_t * ohci) -{ - u32 td_list_hc; - ohci_td_t * td_rev = NULL; - ohci_td_t * td_list = NULL; - urb_priv_t * urb_priv = NULL; - uint32_t value; - u32 td_list_hc2; - int timeout = 1000000; //1 second -// unsigned long flags; -// Here need to process across the frame tds - td_list_hc = le32_to_cpup (&ohci->hcca->done_head) & 0xfffffff0; - td_list_hc2 = readl(&ohci->regs->donehead); -// debug("ohci->hcca->done_head = %x ohci->hcca=%x ohci=%x ohci->regs->donehead=%x\n", td_list_hc, ohci->hcca, ohci, td_list_hc2); - - td_list = dma_to_td (ohci, (void *)td_list_hc); - urb_priv = (urb_priv_t *) td_list->urb->hcpriv; - - while(/*(td_list_hc2!=0) || */(td_list->index < urb_priv->length-1) && (timeout>0)) { // wait another update for donehead - // To handle 1. ohci->hcca->donehead !=0 and regs->donehead!=0 - // 2. ohci->hcca->donehead !=0 and regs->donehead ==0 but regs-->donehead will be filled - - ohci->hcca->done_head = 0; - - value = readl(&ohci->regs->intrstatus); - value &= readl(&ohci->regs->intrenable); - - // We need to clear that the bit, otherwise We will not get next return. - if(value & OHCI_INTR_WDH) { - writel(value, &ohci->regs->intrstatus); - (void)readl (&ohci->regs->intrdisable); /* PCI posting flush */ -// debug("OHCI_INTR_WDH cleared intrstatus=%x value=%x \n", readl(&ohci->regs->intrstatus), value); - } - while(timeout>0) { // wait for next DONEHEAD_WRITEBACK - value = readl(&ohci->regs->intrstatus); - if(!(value & OHCI_INTR_WDH)) { - udelay(1); - timeout--; - continue; - } else { - break; - } - } - - td_list_hc2 = le32_to_cpup (&ohci->hcca->done_head) & 0xfffffff0; - // merge td_list_hc the tail of td_list_hc2 - - if(td_list_hc2!=0) { - - while (td_list_hc2) { - td_list = dma_to_td (ohci, (void *)td_list_hc2); - td_list_hc2 = le32_to_cpup (&td_list->hwNextTD) & 0xfffffff0; - } - - td_list->hwNextTD = td_list_hc; - - td_list_hc = le32_to_cpup (&ohci->hcca->done_head) & 0xfffffff0; - - td_list = dma_to_td (ohci, (void *)td_list_hc); - } else { - printf("."); - } - - } - - ohci->hcca->done_head = 0; - - value = readl(&ohci->regs->intrstatus); -// debug("OHCI_INTR_WDH value=%x \n", value); - value &= readl(&ohci->regs->intrenable); - -// We need to clear that the bit, otherwise We will not get next return. -// if(value & OHCI_INTR_WDH) { - writel(value, &ohci->regs->intrstatus); - (void)readl (&ohci->regs->intrdisable); /* PCI posting flush */ -// debug("OHCI_INTR_WDH cleared intrstatus=%x value=%x \n", readl(&ohci->regs->intrstatus), value); -// } - -#if 0 - if (value & OHCI_INTR_SO) { - debug("USB Schedule overrun"); - writel (OHCI_INTR_SO, &ohci->regs->intrenable); - (void)readl (&ohci->regs->intrdisable); /* PCI posting flush */ - } -#endif - - - while (td_list_hc) { -// debug("td_list_hc = %x\n", td_list_hc); - td_list = dma_to_td (ohci, (void *)td_list_hc); - - if (TD_CC_GET (le32_to_cpup (&td_list->hwINFO))) { - urb_priv = (urb_priv_t *) td_list->urb->hcpriv; - debug(" USB-error/status: %x : %x\n", - TD_CC_GET (le32_to_cpup (&td_list->hwINFO)), td_list); - if (td_list->ed->hwHeadP & cpu_to_le32 (0x1)) { - if (urb_priv && ((td_list->index + 1) < urb_priv->length)) { - td_list->ed->hwHeadP = - (urb_priv->td[urb_priv->length - 1]->hwNextTD & cpu_to_le32 (0xfffffff0)) | - (td_list->ed->hwHeadP & cpu_to_le32 (0x2)); - urb_priv->td_cnt += urb_priv->length - td_list->index - 1; - } else - td_list->ed->hwHeadP &= cpu_to_le32 (0xfffffff2); - } - } - - td_list->next_dl_td = td_rev; - td_rev = td_list; - td_list_hc = le32_to_cpup (&td_list->hwNextTD) & 0xfffffff0; - } - return td_list; -} -/*-------------------------------------------------------------------------*/ -/* td done list */ - -void dl_done_list (ohci_t * ohci, ohci_td_t * td_list) -{ - ohci_td_t * td_list_next = NULL; - ed_t * ed; - // int cc = 0; - struct urb * urb; - urb_priv_t * urb_priv; - u32 tdINFO; //, edHeadP, edTailP; - -// unsigned long flags; - - while (td_list) { - td_list_next = td_list->next_dl_td; - - urb = td_list->urb; - urb_priv = urb->hcpriv; - tdINFO = le32_to_cpup (&td_list->hwINFO); - - ed = td_list->ed; - - dl_transfer_length(td_list); -#if 0 - /* error code of transfer */ - cc = TD_CC_GET (tdINFO); - if (cc == TD_CC_STALL) - usb_endpoint_halt(urb->dev, - usb_pipeendpoint(urb->pipe), - usb_pipeout(urb->pipe)); - - if (!(urb->transfer_flags & USB_DISABLE_SPD) - && (cc == TD_DATAUNDERRUN)) - cc = TD_CC_NOERROR; - - if (++(urb_priv->td_cnt) == urb_priv->length) { - if ((ed->state & (ED_OPER | ED_UNLINK)) - && (urb_priv->state != URB_DEL)) { - urb->status = cc_to_error[cc]; - ohci_return_urb (ohci, urb); - } - else { - dl_del_urb (urb); - } - } - - if (ed->state != ED_NEW) { - edHeadP = le32_to_cpup (&ed->hwHeadP) & 0xfffffff0; - edTailP = le32_to_cpup (&ed->hwTailP); - - /* unlink eds if they are not busy */ - if ((edHeadP == edTailP) && (ed->state == ED_OPER)) - ep_unlink (ohci, ed); - } -#endif - - td_list = td_list_next; - } -} - -void ohci_wait_urb_done(struct urb *urb, int timeout) { // timeout usually ==10000 --> 10milisecond - //here need to according the urb or ed type judge the BLF and CLF, We may need one time out in it - // Or need to check intrstatus and see if the hcca->done_head has been filled. - // We need to clear that the bit, otherwise We will get next return. - uint32_t pipe = urb->pipe; - uint32_t value; - usbdev_t *usb_dev = urb->dev; - ohci_t *ohci = &_ohci_x[usb_dev->controller]; - uint32_t type; - while(timeout>0) { -#if 1 - value = readl(&ohci->regs->intrstatus); - if(!(value & OHCI_INTR_WDH)) { - udelay(1); - timeout--; - continue; - } else { - break; - } -#endif - } -#if 1 - while (timeout>0) { - type = usb_pipetype (pipe); - if(type ==PIPE_BULK) { - if( (readl(&ohci->regs->cmdstatus) & OHCI_BLF) == 0) break; - } else if(type == PIPE_CONTROL) { - if( (readl(&ohci->regs->cmdstatus) & OHCI_CLF) == 0) break; - } - udelay(1); // - timeout--; - } -#endif - - -} -void ohci_urb_complete(struct urb *urb) { - - ohci_t *ohci = &_ohci_x[urb->dev->controller]; - // it will clear the done list. and urb's actual_length is updated - dl_done_list (ohci, dl_reverse_done_list (ohci)); - -#if DEBUG_USB==1 - urb_print (urb, "RET", usb_pipein (urb->pipe)); -#endif - - urb_free_priv(ohci, urb->hcpriv); // free the priv and td list - -} -/*-------------------------------------------------------------------*/ -// it will 1. call usb_bulk_msg_x -// 2. call dl_list and find the data return -int ohci_bulk_transfer( uchar devnum, uchar ep, unsigned int data_len, uchar *data) { - int actual_length; - uint32_t t = devnum; - uint32_t pipe = ((ep&0x80)? 0x80:0)|(t<<8)|(3<<30); - t = ep; - pipe |=(t&0xf)<<15; - - usb_bulk_msg_x(&usb_device[devnum], pipe, data, data_len, &actual_length, 10000, ohci_urb_complete); - - return actual_length; - - -} -// it will 1. Call usb_control_msg_x -// 2. call dl_done_list to get the data returned ----> should be packed in one usb_complete_t function -// and assigned that to urb - -int ohci_control_msg( uchar devnum, uchar request_type, uchar request, unsigned short wValue, unsigned short wIndex, unsigned short -wLength, void *data){ - - uint32_t t = devnum; - uint32_t pipe = ((request_type&0x80)? 0x80:0)|(t<<8)|(2<<30); - return usb_control_msg_x(&usb_device[devnum], pipe, request, request_type, wValue, wIndex, data, wLength, 10000, ohci_urb_complete); - -} - -int ohc_reset(uchar controller) -{ - - int timeout = 30; - int smm_timeout = 50; /* 0,5 sec */ - - debug("Resetting OHCI\n"); - ohci_regs = (ohci_regs_t *)hc_base[controller]; - ohci_t *ohci = &_ohci_x[controller]; - -#ifndef __hppa__ - /* PA-RISC doesn't have SMM, but PDC might leave IR set */ - if (readl (&ohci_regs->control) & OHCI_CTRL_IR) { /* SMM owns the HC */ - writel (OHCI_OCR, &ohci_regs->cmdstatus); /* request ownership */ - debug("USB HC TakeOver from SMM"); - while (readl (&ohci_regs->control) & OHCI_CTRL_IR) { - mdelay (10); - if (--smm_timeout == 0) { - printf("USB HC TakeOver failed!"); - return -1; - } - } - } -#endif - - debug("USB HC reset_hc usb-%08x: ctrl = 0x%x ;", - hc_base[controller], - readl (&ohci_regs->control)); - - /* Reset USB (needed by some controllers) */ - writel (0, &ohci_regs->control); - - /* Force a state change from USBRESET to USBOPERATIONAL for ALi */ - (void) readl (&ohci_regs->control); /* PCI posting */ - writel (ohci->hc_control = OHCI_USB_OPER, &ohci_regs->control); - - /* HC Reset requires max 10 ms delay */ - writel (OHCI_HCR, &ohci_regs->cmdstatus); - while ((readl (&ohci_regs->cmdstatus) & OHCI_HCR) != 0) { - if (--timeout == 0) { - printf("USB HC reset timed out!"); - return -1; - } - udelay (1); - } - return 0; -} - - -int ohc_start(uchar controller) { - // unsigned short tmp; - u32 mask; - unsigned int fminterval; - int delaytime; - ohci_regs = (ohci_regs_t *)hc_base[controller]; - ohci_t *ohci = &_ohci_x[controller]; - - debug("Starting OHCI\n"); - - writel (0, &ohci_regs->ed_controlhead); - writel (0, &ohci_regs->ed_bulkhead); - - writel ((uint32_t)ohci->hcca_dma, &ohci_regs->hcca); /* a reset clears this */ //3 - - fminterval = 0x2edf; //6 - writel ((fminterval * 9) / 10, &ohci_regs->periodicstart); // Don't worry, we can disable periodic in contol or let the ED list null - fminterval |= ((((fminterval - 210) * 6) / 7) << 16); - writel (fminterval, &ohci_regs->fminterval); - writel (0x628, &ohci_regs->lsthresh); - - /* start controller operations */ - - ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER; - writel (ohci->hc_control, &ohci_regs->control); // PIE and IE is disabled - // DO we need to enable that but leave all ISO ED and INT ED list null??? - - mask = OHCI_INTR_MIE | OHCI_INTR_UE | OHCI_INTR_WDH | OHCI_INTR_SO; - writel (mask, &ohci->regs->intrenable); - writel (mask, &ohci->regs->intrstatus); - - /* required for AMD-756 and some Mac platforms */ - writel ((roothub_a (ohci) | RH_A_NPS) & ~RH_A_PSM, &ohci->regs->roothub.a); - writel (RH_HS_LPSC, &ohci->regs->roothub.status); - - (void)readl (&ohci->regs->intrdisable); /* PCI posting flush */ - - // POTPGT delay is bits 24-31, in 2 ms units. - delaytime = ((roothub_a (ohci) >> 23) & 0x1fe)*5/2; // for apacer 256 usb 2.0 + NEC 2.0 chip -// delaytime = ((roothub_a (ohci) >> 23) & 0x1fe); - - mdelay (delaytime); - -// printf("delaytime: %d\n", delaytime); - - return(0); -} - - -int ohc_init(struct pci_device *dev) -{ - uint16_t word; - uint32_t dword; - ohci_t *ohci; - ed_t * ed; - int i,j, NDP; - int size; - - pci_read_config_dword(dev, 0x10, &dword); // it will be 4k range - hc_base[num_controllers] = (uint32_t)phys_to_virt(dword); - ohci = &_ohci_x[num_controllers]; - debug("ohc_init num_controllers=%d ohci=%x\n", num_controllers, (uint32_t)ohci); - memset(ohci, 0, sizeof(ohci_t)); - ohci->regs = (ohci_regs_t *)hc_base[num_controllers]; - ohci_regs = ohci->regs; - - ohci->hcca = allot2(sizeof (struct ohci_hcca), 0xff); //1 - if (!ohci->hcca) { - printf("ohc_init: hcca allocated no MEM\n"); - return -ENOMEM; - } - memset (ohci->hcca, 0, sizeof (struct ohci_hcca)); - ohci->hcca_dma = (void *)virt_to_phys(ohci->hcca); - - //init ed; - ohci->ed = allot2(sizeof(ed_t)*NUM_EDS,0xf); - if(ohci->ed==0) { - printf("ohci_init: ed allocate no MEM\n"); - } -// debug("ohci->ed = %x\n", ohci->ed); - for(i=0; i<NUM_EDS;i++) { - ed = (ed_t *)&ohci->ed[i]; - ed->dma = (void *)virt_to_phys(ed); -// debug("i=%d, ed dma = %x\n", i, (uint32_t)ed->dma); - ed->state = ED_NEW; - } - -// init urb and urb_priv - ohci->urb = (struct urb *)allot2(sizeof(struct urb),0xff); - if (!ohci->urb) { - printf("ohci_init: urb allocate failed"); - } - memset(ohci->urb, 0, sizeof(urb_t)); - - - /* allocate the private part of the URB */ - size = 4; - ohci->urb_priv = allot2 (sizeof (urb_priv_t) + size * sizeof (ohci_td_t *), 0xff); - if (ohci->urb_priv == 0) { - printf("ohci_init: urb_priv allocated no mem\n"); - } - memset (ohci->urb_priv, 0, sizeof (urb_priv_t) + size * sizeof (ohci_td_t *)); - - // set master - pci_read_config_word(dev, 0x04, &word); - word |= 0x04; - pci_write_config_word(dev, 0x04, word); - - - DPRINTF("Found OHCI at %08x\n", hc_base[num_controllers]); - ohc_reset(num_controllers); - - /* Here should or move to ohc_start - 1. Init HCCA - 2. Init ED and TD ---> in submit_urb - 3. Assign HCCA to ohci_regs->hcca ---> in ohc_init - 4. Set Intr to ohci_regs->intrenable ---> disable that in ohc_init - 5. enable all queue in ohci_regs->control ---> in ep_link and it is called by submit_urb - 6. set peridicstart to 0.9 of frameinterval ---> ohc_start - */ - -// writel( 0, &ohci_regs->intrenable); // no interrupts! //4 -// writel( 0xffffffff, &ohci_regs->intrdisable); - - NDP = readl(&ohci->regs->roothub.a) & 0xff; - for(j=0;j<NDP;j++) { - writel(RH_PS_PSS, &ohci->regs->roothub.portstatus[j]); - } - - /* FIXME this is a second HC reset; why?? */ - writel (ohci->hc_control = OHCI_USB_RESET, &ohci->regs->control); - (void)readl (&ohci->regs->intrdisable); /* PCI posting flush */ - mdelay (10); - - ohc_start(num_controllers); - - num_controllers++; - -#if DEBUG_USB==1 -// ohci_dump (ohci, 1); -#endif - -// debug("ohci->ed = %x\n", ohci->ed); - return(0); -} -int poll_o_root_hub(uint32_t port, uchar controller) -{ - uint32_t value; - int addr=0; - int i; - static uint32_t do_over=0; - uint8_t what; - ohci_t *ohci; - - value = readl(port); - - debug("poll_o_root_hub1 v=%08x port = %x, controller = %d\n", value, port, controller); - - if(value == 0xffffffff) return addr; // stupid port - - if((value & RH_PS_CSC) || do_over == port) { - debug("poll_o_root_hub2 v=%08x\t", value); - do_over=0; - if(value & RH_PS_CCS ) { // if port connected - debug("poll_o_root_hub21 v=%08x\t", value); - DPRINTF("Connection on port %04x\n", port); - - writel(value, port); - for(i=0; i<40; i++) { - udelay(10000+usec_offset); - value = readl(port); - if(value & RH_PS_CSC) { - writel(value, port); //Clear Change bit - i=0; - DPRINTF("BOUNCE!\n"); - } - } -// debug("poll_o_root_hub211 v=%08x\t", value); - - oport_wakeup(port); -// DPRINTF("Wakup %04x\n", port); - -// debug("poll_o_root_hub212 v=%08x\t", readl(port)); - oport_reset(port); -// debug("poll_o_root_hub213 v=%08x\t", readl(port)); - mdelay(10); - oport_enable(port); -// debug("poll_o_root_hub214 v=%08x\t", readl(port)); - - if(!(value & RH_PS_CCS)) { - DPRINTF("Device went away!\n"); - return(-1); - } - - addr = configure_device( port, controller, value & RH_PS_LSDA); - -#if DEBUG_USB==1 - // some one clear enable bit??? why??? It costs me one week to find it out. - ohci = &_ohci_x[controller]; - ohci_dump (ohci, 1); -#endif - -#if 1 -// usb_control_msg(addr, 0x21, 0xff, 0, 0, 0, NULL);// reset device -// mdelay(10); - usb_control_msg(addr, 0xa1, 0xfe, 0, 0, 1, &what); // get MAX L // get MAX LUN -#endif - -// debug("poll_o_root_hub215 v=%08x addr = %d\n", readl(port), addr); - - if(addr<0) { - oport_disable(port); - udelay(20000); -// oport_reset(port); - oport_reset_long(port); - oport_suspend(port); - do_over=port; - ohc_clear_stat(controller); - - } - } else { -// debug("poll_o_root_hub22 v=%08x\t", readl(port)); - oport_suspend(port); - oport_disable(port); - DPRINTF("Port %04x disconnected\n", port); - // wave hands, deconfigure devices on this port! - } - } - - return(addr); -} - - - - -#endif diff --git a/src/filo/usb/ohci.h b/src/filo/usb/ohci.h deleted file mode 100644 index 0c9c6ad57..000000000 --- a/src/filo/usb/ohci.h +++ /dev/null @@ -1,316 +0,0 @@ -#ifdef USB_DISK - -#ifndef _OHCI_H -#define _OHCI_H - -/******************************************************************************* - * - * - * Copyright 2003 Steven James <pyro@linuxlabs.com> and - * LinuxLabs http://www.linuxlabs.com - * - * 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. - * - ******************************************************************************/ - -// for OHCI - -/* ED States */ - -#define ED_NEW 0x00 -#define ED_UNLINK 0x01 -#define ED_OPER 0x02 -#define ED_DEL 0x04 -#define ED_URB_DEL 0x08 - -/* usb_ohci_ed */ -struct ed { - u32 hwINFO; - u32 hwTailP; - u32 hwHeadP; - u32 hwNextED; - - struct ed * ed_prev; - u8 int_period; // No use just for aligned - u8 int_branch; // No use just for aligned - u8 int_load; // No uae just for aligned - u8 int_interval; // No use just for aligned - u8 state; - u8 type; - u16 last_iso; // no use just for aligned - struct ed * ed_rm_list; // No use just for aligned - - void * dma; - - u32 unused[3]; -}; -// __attribute((aligned(16))); -typedef struct ed ed_t; - -/* TD info field */ -#define TD_CC 0xf0000000 -#define TD_CC_GET(td_p) ((td_p >>28) & 0x0f) -#define TD_CC_SET(td_p, cc) (td_p) = ((td_p) & 0x0fffffff) | (((cc) & 0x0f) << 28) -#define TD_EC 0x0C000000 -#define TD_T 0x03000000 -#define TD_T_DATA0 0x02000000 -#define TD_T_DATA1 0x03000000 -#define TD_T_TOGGLE 0x00000000 -#define TD_R 0x00040000 -#define TD_DI 0x00E00000 -#define TD_DI_SET(X) (((X) & 0x07)<< 21) -#define TD_DP 0x00180000 -#define TD_DP_SETUP 0x00000000 -#define TD_DP_IN 0x00100000 -#define TD_DP_OUT 0x00080000 - -#define TD_ISO 0x00010000 -#define TD_DEL 0x00020000 - -/* CC Codes */ -#define TD_CC_NOERROR 0x00 -#define TD_CC_CRC 0x01 -#define TD_CC_BITSTUFFING 0x02 -#define TD_CC_DATATOGGLEM 0x03 -#define TD_CC_STALL 0x04 -#define TD_DEVNOTRESP 0x05 -#define TD_PIDCHECKFAIL 0x06 -#define TD_UNEXPECTEDPID 0x07 -#define TD_DATAOVERRUN 0x08 -#define TD_DATAUNDERRUN 0x09 -#define TD_BUFFEROVERRUN 0x0C -#define TD_BUFFERUNDERRUN 0x0D -#define TD_NOTACCESSED 0x0F - - -#define MAXPSW 1 - -struct ohci_td { - u32 hwINFO; - u32 hwCBP; /* Current Buffer Pointer */ - u32 hwNextTD; /* Next TD Pointer */ - u32 hwBE; /* Memory Buffer End Pointer */ - u16 hwPSW[MAXPSW]; - u8 unused; - u8 index; - struct ed * ed; - struct ohci_td * next_dl_td; - struct urb * urb; //defined in usb.h - void * td_dma; - void * data_dma; - u32 unused2[2]; -}; -//__attribute((aligned(32))); /* normally 16, iso needs 32 */ -typedef struct ohci_td ohci_td_t; - -#define OHCI_ED_SKIP (1 << 14) - -/* - * The HCCA (Host Controller Communications Area) is a 256 byte - * structure defined in the OHCI spec. that the host controller is - * told the base address of. It must be 256-byte aligned. - */ - -#define NUM_INTS 32 /* part of the OHCI standard */ -struct ohci_hcca { - u32 int_table[NUM_INTS]; /* Interrupt ED table */ - u16 frame_no; /* current frame number */ - u16 pad1; /* set to 0 on each frame_no change */ - u32 done_head; /* info returned for an interrupt */ - u8 reserved_for_hc[116]; -} __attribute((aligned(256))); - - -#define MAX_ROOT_PORTS 15 - -struct ohci_regs { - /* control and status registers */ - u32 revision; - u32 control; - u32 cmdstatus; - u32 intrstatus; - u32 intrenable; - u32 intrdisable; - /* memory pointers */ - u32 hcca; - u32 ed_periodcurrent; - u32 ed_controlhead; - u32 ed_controlcurrent; - u32 ed_bulkhead; - u32 ed_bulkcurrent; - u32 donehead; - /* frame counters */ - u32 fminterval; - u32 fmremaining; - u32 fmnumber; - u32 periodicstart; - u32 lsthresh; - /* Root hub ports */ - struct ohci_roothub_regs { - u32 a; - u32 b; - u32 status; - u32 portstatus[MAX_ROOT_PORTS]; - } roothub; -} __attribute((aligned(32))); -typedef struct ohci_regs ohci_regs_t; - - -/* OHCI CONTROL AND STATUS REGISTER MASKS */ - -/* - * HcControl (control) register masks - */ -#define OHCI_CTRL_CBSR (3 << 0) /* control/bulk service ratio */ -#define OHCI_CTRL_PLE (1 << 2) /* periodic list enable */ -#define OHCI_CTRL_IE (1 << 3) /* isochronous enable */ -#define OHCI_CTRL_CLE (1 << 4) /* control list enable */ -#define OHCI_CTRL_BLE (1 << 5) /* bulk list enable */ -#define OHCI_CTRL_HCFS (3 << 6) /* host controller functional state */ -#define OHCI_CTRL_IR (1 << 8) /* interrupt routing */ -#define OHCI_CTRL_RWC (1 << 9) /* remote wakeup connected */ -#define OHCI_CTRL_RWE (1 << 10) /* remote wakeup enable */ - -/* pre-shifted values for HCFS */ -# define OHCI_USB_RESET (0 << 6) -# define OHCI_USB_RESUME (1 << 6) -# define OHCI_USB_OPER (2 << 6) -# define OHCI_USB_SUSPEND (3 << 6) - -/* - * HcCommandStatus (cmdstatus) register masks - */ -#define OHCI_HCR (1 << 0) /* host controller reset */ -#define OHCI_CLF (1 << 1) /* control list filled */ -#define OHCI_BLF (1 << 2) /* bulk list filled */ -#define OHCI_OCR (1 << 3) /* ownership change request */ -#define OHCI_SOC (3 << 16) /* scheduling overrun count */ - -/* - * masks used with interrupt registers: - * HcInterruptStatus (intrstatus) - * HcInterruptEnable (intrenable) - * HcInterruptDisable (intrdisable) - */ -#define OHCI_INTR_SO (1 << 0) /* scheduling overrun */ -#define OHCI_INTR_WDH (1 << 1) /* writeback of done_head */ -#define OHCI_INTR_SF (1 << 2) /* start frame */ -#define OHCI_INTR_RD (1 << 3) /* resume detect */ -#define OHCI_INTR_UE (1 << 4) /* unrecoverable error */ -#define OHCI_INTR_FNO (1 << 5) /* frame number overflow */ -#define OHCI_INTR_RHSC (1 << 6) /* root hub status change */ -#define OHCI_INTR_OC (1 << 30) /* ownership change */ -#define OHCI_INTR_MIE (1 << 31) /* master interrupt enable */ - - -/* For initializing controller (mask in an HCFS mode too) */ -#define OHCI_CONTROL_INIT \ - (OHCI_CTRL_CBSR & 0x3) -//| OHCI_CTRL_IE | OHCI_CTRL_PLE - -/* OHCI ROOT HUB REGISTER MASKS */ - -/* roothub.portstatus [i] bits */ -#define RH_PS_CCS 0x00000001 /* current connect status */ -#define RH_PS_PES 0x00000002 /* port enable status*/ -#define RH_PS_PSS 0x00000004 /* port suspend status */ -#define RH_PS_POCI 0x00000008 /* port over current indicator */ -#define RH_PS_PRS 0x00000010 /* port reset status */ -#define RH_PS_PPS 0x00000100 /* port power status */ -#define RH_PS_LSDA 0x00000200 /* low speed device attached */ -#define RH_PS_CSC 0x00010000 /* connect status change */ -#define RH_PS_PESC 0x00020000 /* port enable status change */ -#define RH_PS_PSSC 0x00040000 /* port suspend status change */ -#define RH_PS_OCIC 0x00080000 /* over current indicator change */ -#define RH_PS_PRSC 0x00100000 /* port reset status change */ - -/* roothub.status bits */ -#define RH_HS_LPS 0x00000001 /* local power status */ -#define RH_HS_OCI 0x00000002 /* over current indicator */ -#define RH_HS_DRWE 0x00008000 /* device remote wakeup enable */ -#define RH_HS_LPSC 0x00010000 /* local power status change */ -#define RH_HS_OCIC 0x00020000 /* over current indicator change */ -#define RH_HS_CRWE 0x80000000 /* clear remote wakeup enable */ - -/* roothub.b masks */ -#define RH_B_DR 0x0000ffff /* device removable flags */ -#define RH_B_PPCM 0xffff0000 /* port power control mask */ - -/* roothub.a masks */ -#define RH_A_NDP (0xff << 0) /* number of downstream ports */ -#define RH_A_PSM (1 << 8) /* power switching mode */ -#define RH_A_NPS (1 << 9) /* no power switching */ -#define RH_A_DT (1 << 10) /* device type (mbz) */ -#define RH_A_OCPM (1 << 11) /* over current protection mode */ -#define RH_A_NOCP (1 << 12) /* no over current protection */ -#define RH_A_POTPGT (0xff << 24) /* power on to power good time */ - -typedef struct -{ - ed_t * ed; - u16 length; // number of tds associated with this request - u16 td_cnt; // number of tds already serviced - int state; -#if 0 - wait_queue_head_t * wait; -#endif - ohci_td_t * td[0]; // list pointer to all corresponding TDs associated with this request - -} urb_priv_t; - -#define NUM_EDS 32 /* num of preallocated endpoint descriptors */ - -typedef struct ohci { - struct ohci_hcca *hcca; /* hcca */ - void * hcca_dma; - - ohci_regs_t * regs; /* OHCI controller's memory */ - - ed_t * ed_bulktail; /* last endpoint of bulk list */ - ed_t * ed_controltail; /* last endpoint of control list */ - - int intrstatus; - u32 hc_control; /* copy of the hc control reg */ - - uint32_t ed_cnt; - ed_t *ed; // Allocate that from ed_buffer in ohc_init - usbdev_t *dev[NUM_EDS]; - urb_t *urb; // one ohci one urb - urb_priv_t *urb_priv; - struct usb_ctrlrequest *dr; -} ohci_t; - - -extern ohci_t _ohci_x[MAX_CONTROLLERS]; - -#define usb_to_ohci(usb_dev) (&_ohci_x[(usb_dev)->controller]) - -extern ohci_regs_t *ohci_regs; - -void clear_oport_stat(uint32_t port); -int ohc_init(struct pci_device *dev); -int poll_o_root_hub(uint32_t port, uchar controller); - -int ohci_bulk_transfer( uchar devnum, uchar ep, unsigned int data_len, uchar *data); -int ohci_control_msg( uchar devnum, uchar request_type, uchar request, unsigned short wValue, unsigned short wIndex, unsigned short - wLength, void *data); -void ohci_wait_urb_done(struct urb *urb, int timeout); - -void ohci_init(void); -int ohc_init(struct pci_device *dev); -int ohci_submit_urb (struct urb * urb); -#endif - -#endif diff --git a/src/filo/usb/scsi.h b/src/filo/usb/scsi.h deleted file mode 100644 index 7c119a48a..000000000 --- a/src/filo/usb/scsi.h +++ /dev/null @@ -1,226 +0,0 @@ -/* Copyright (C) 1998, 1999 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -/* - * This header file contains public constants and structures used by - * the scsi code for linux. - */ - -#ifndef _SCSI_SCSI_H -#define _SCSI_SCSI_H 1 - -//#include <features.h> - -/* - * SCSI opcodes - */ - -#define TEST_UNIT_READY 0x00 -#define REZERO_UNIT 0x01 -#define REQUEST_SENSE 0x03 -#define FORMAT_UNIT 0x04 -#define READ_BLOCK_LIMITS 0x05 -#define REASSIGN_BLOCKS 0x07 -#define READ_6 0x08 -#define WRITE_6 0x0a -#define SEEK_6 0x0b -#define READ_REVERSE 0x0f -#define WRITE_FILEMARKS 0x10 -#define SPACE 0x11 -#define INQUIRY 0x12 -#define RECOVER_BUFFERED_DATA 0x14 -#define MODE_SELECT 0x15 -#define RESERVE 0x16 -#define RELEASE 0x17 -#define COPY 0x18 -#define ERASE 0x19 -#define MODE_SENSE 0x1a -#define START_STOP 0x1b -#define RECEIVE_DIAGNOSTIC 0x1c -#define SEND_DIAGNOSTIC 0x1d -#define ALLOW_MEDIUM_REMOVAL 0x1e - -#define SET_WINDOW 0x24 -#define READ_CAPACITY 0x25 -#define READ_10 0x28 -#define WRITE_10 0x2a -#define SEEK_10 0x2b -#define WRITE_VERIFY 0x2e -#define VERIFY 0x2f -#define SEARCH_HIGH 0x30 -#define SEARCH_EQUAL 0x31 -#define SEARCH_LOW 0x32 -#define SET_LIMITS 0x33 -#define PRE_FETCH 0x34 -#define READ_POSITION 0x34 -#define SYNCHRONIZE_CACHE 0x35 -#define LOCK_UNLOCK_CACHE 0x36 -#define READ_DEFECT_DATA 0x37 -#define MEDIUM_SCAN 0x38 -#define COMPARE 0x39 -#define COPY_VERIFY 0x3a -#define WRITE_BUFFER 0x3b -#define READ_BUFFER 0x3c -#define UPDATE_BLOCK 0x3d -#define READ_LONG 0x3e -#define WRITE_LONG 0x3f -#define CHANGE_DEFINITION 0x40 -#define WRITE_SAME 0x41 -#define READ_TOC 0x43 -#define LOG_SELECT 0x4c -#define LOG_SENSE 0x4d -#define MODE_SELECT_10 0x55 -#define RESERVE_10 0x56 -#define RELEASE_10 0x57 -#define MODE_SENSE_10 0x5a -#define PERSISTENT_RESERVE_IN 0x5e -#define PERSISTENT_RESERVE_OUT 0x5f -#define MOVE_MEDIUM 0xa5 -#define READ_12 0xa8 -#define WRITE_12 0xaa -#define WRITE_VERIFY_12 0xae -#define SEARCH_HIGH_12 0xb0 -#define SEARCH_EQUAL_12 0xb1 -#define SEARCH_LOW_12 0xb2 -#define READ_ELEMENT_STATUS 0xb8 -#define SEND_VOLUME_TAG 0xb6 -#define WRITE_LONG_2 0xea - -/* - * Status codes - */ - -#define GOOD 0x00 -#define CHECK_CONDITION 0x01 -#define CONDITION_GOOD 0x02 -#define BUSY 0x04 -#define INTERMEDIATE_GOOD 0x08 -#define INTERMEDIATE_C_GOOD 0x0a -#define RESERVATION_CONFLICT 0x0c -#define COMMAND_TERMINATED 0x11 -#define QUEUE_FULL 0x14 - -#define STATUS_MASK 0x3e - -/* - * SENSE KEYS - */ - -#define NO_SENSE 0x00 -#define RECOVERED_ERROR 0x01 -#define NOT_READY 0x02 -#define MEDIUM_ERROR 0x03 -#define HARDWARE_ERROR 0x04 -#define ILLEGAL_REQUEST 0x05 -#define UNIT_ATTENTION 0x06 -#define DATA_PROTECT 0x07 -#define BLANK_CHECK 0x08 -#define COPY_ABORTED 0x0a -#define ABORTED_COMMAND 0x0b -#define VOLUME_OVERFLOW 0x0d -#define MISCOMPARE 0x0e - - -/* - * DEVICE TYPES - */ - -#define TYPE_DISK 0x00 -#define TYPE_TAPE 0x01 -#define TYPE_PROCESSOR 0x03 /* HP scanners use this */ -#define TYPE_WORM 0x04 /* Treated as ROM by our system */ -#define TYPE_ROM 0x05 -#define TYPE_SCANNER 0x06 -#define TYPE_MOD 0x07 /* Magneto-optical disk - - * - treated as TYPE_DISK */ -#define TYPE_MEDIUM_CHANGER 0x08 -#define TYPE_ENCLOSURE 0x0d /* Enclosure Services Device */ -#define TYPE_NO_LUN 0x7f - -/* - * standard mode-select header prepended to all mode-select commands - * - * moved here from cdrom.h -- kraxel - */ - -struct ccs_modesel_head - { - unsigned char _r1; /* reserved. */ - unsigned char medium; /* device-specific medium type. */ - unsigned char _r2; /* reserved. */ - unsigned char block_desc_length; /* block descriptor length. */ - unsigned char density; /* device-specific density code. */ - unsigned char number_blocks_hi; /* number of blocks in this block - desc. */ - unsigned char number_blocks_med; - unsigned char number_blocks_lo; - unsigned char _r3; - unsigned char block_length_hi; /* block length for blocks in this - desc. */ - unsigned char block_length_med; - unsigned char block_length_lo; - }; - -/* - * MESSAGE CODES - */ - -#define COMMAND_COMPLETE 0x00 -#define EXTENDED_MESSAGE 0x01 -#define EXTENDED_MODIFY_DATA_POINTER 0x00 -#define EXTENDED_SDTR 0x01 -#define EXTENDED_EXTENDED_IDENTIFY 0x02 /* SCSI-I only */ -#define EXTENDED_WDTR 0x03 -#define SAVE_POINTERS 0x02 -#define RESTORE_POINTERS 0x03 -#define DISCONNECT 0x04 -#define INITIATOR_ERROR 0x05 -#define ABORT 0x06 -#define MESSAGE_REJECT 0x07 -#define NOP 0x08 -#define MSG_PARITY_ERROR 0x09 -#define LINKED_CMD_COMPLETE 0x0a -#define LINKED_FLG_CMD_COMPLETE 0x0b -#define BUS_DEVICE_RESET 0x0c - -#define INITIATE_RECOVERY 0x0f /* SCSI-II only */ -#define RELEASE_RECOVERY 0x10 /* SCSI-II only */ - -#define SIMPLE_QUEUE_TAG 0x20 -#define HEAD_OF_QUEUE_TAG 0x21 -#define ORDERED_QUEUE_TAG 0x22 - -/* - * Here are some scsi specific ioctl commands which are sometimes useful. - */ -/* These are a few other constants only used by scsi devices. */ - -#define SCSI_IOCTL_GET_IDLUN 0x5382 - -/* Used to turn on and off tagged queuing for scsi devices. */ - -#define SCSI_IOCTL_TAGGED_ENABLE 0x5383 -#define SCSI_IOCTL_TAGGED_DISABLE 0x5384 - -/* Used to obtain the host number of a device. */ -#define SCSI_IOCTL_PROBE_HOST 0x5385 - -/* Used to get the bus number for a device. */ -#define SCSI_IOCTL_GET_BUS_NUMBER 0x5386 - -#endif /* scsi/scsi.h */ diff --git a/src/filo/usb/scsi_cmds.c b/src/filo/usb/scsi_cmds.c deleted file mode 100644 index bd7b7fa8a..000000000 --- a/src/filo/usb/scsi_cmds.c +++ /dev/null @@ -1,512 +0,0 @@ -#ifdef USB_DISK -/******************************************************************************* - * - * - * Copyright 2003 Steven James <pyro@linuxlabs.com> and - * LinuxLabs http://www.linuxlabs.com - * - * 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 <etherboot.h> -#include <pci.h> -#include <timer.h> -#include <lib.h> - -#define DEBUG_THIS DEBUG_USB -#include <debug.h> - -#define DPRINTF debug - - -#include "scsi.h" - - -#include "usb_scsi_low.h" - -#ifndef NULL -#define NULL (void *) 0x0 -#endif - -#include "scsi_cmds.h" - -devhandle sgh; - -typedef struct sense_data { - uchar code; - - uchar sense_key:4; - uchar res1:4; - - uchar additional_code; - uchar qualifier; - - uchar res2[3]; - - uchar length; -} __attribute__ ((packed)) sense_data_t; - -typedef struct fixed_sense_data { - uchar code:7; - uchar valid:1; - - uchar obs1; - - uchar sense_key:4; - uchar res1:1; - uchar ili:1; - uchar eom:1; - uchar mark:1; - - unsigned int info; - - uchar add_len; -} __attribute__ ((packed)) fixed_sense_data_t; - -typedef struct additional_fixed_data { - unsigned int info; - - uchar code; - uchar qualifier; - uchar fru; - - uchar specific[3]; -} __attribute__ ((packed)) additional_fixed_data_t; - - -void PrintSense(uchar *sense, int len) -{ - int i; - - DPRINTF( "sense data "); - for(i=0;i<len; i++) { - DPRINTF( ":%02x", sense[i]); - } - DPRINTF("\n\n"); - - if( (sense[0] & 0x7f) >=0x72) { - sense_data_t *sd = (sense_data_t *) sense; - uchar *pos = sense+sizeof(sense_data_t); - uchar remaining = sd->length; - int dlen; - - DPRINTF("code = %02x, key = %1x, additional = %02x, qual = %02x\n", sd->code, sd->sense_key, sd->additional_code, sd->qualifier); - - while(remaining) { - DPRINTF("type = %02x", pos[0]); - dlen = pos[1]; - pos+=2; - remaining -=2; - - for(i=0; i<dlen; i++) - DPRINTF( ": %02x", pos[i]); - - DPRINTF("\n"); - pos+=i; - remaining -=i; - } - - } else { - fixed_sense_data_t *fd = (fixed_sense_data_t *) sense; - uchar remaining = fd->add_len; - additional_fixed_data_t *afd; - - - DPRINTF("code = %02x key = %1x\n", fd->code, fd->sense_key); - if(fd->mark) { - DPRINTF("filemark "); - } - - if(fd->eom) { - DPRINTF(" End Of Media "); - } - - if(fd->ili) { - DPRINTF("Illegal instruction"); - } - - DPRINTF("\n"); - - if(fd->valid) { - DPRINTF( "(valid) "); - } - - DPRINTF( "Info: %08x\n", ntohl(fd->info)); - - afd = (additional_fixed_data_t *) (sense + 8); - -// while(remaining) { - if(remaining) { - DPRINTF("command info = %08x\n", ntohl(afd->info)); - DPRINTF("code = %02x, qual = %02x, fru = %02x\n", afd->code, afd->qualifier, afd->fru); - DPRINTF("sense key data = %02x:%02x:%02x\n\n", afd->specific[2], afd->specific[1], afd->specific[0]); - - afd++; - remaining -= sizeof(additional_fixed_data_t); - } - } - -} - -typedef struct query_response { - uchar type:5; - uchar qualifier:3; - - uchar reserved1:7; - uchar removable:1; - - uchar version; - - uchar ResponseDataFormat:4; // should == 2 - uchar HiSup:1; // report luns cmd supported - uchar NormACA:1; - uchar obsolete:1; - uchar aerc:1; - - uchar AdditionalLength; // length of vendor specific data (beyond 96 bytes) - - uchar reserved2:7; - uchar sccs:1; // have raid controller - - uchar addr16:1; // - uchar obsolete2:2; - uchar MChnger:1; // media changer - uchar MultiP:1; // multi port - uchar vs:1; // ??? - uchar EncServ:1; // enclosure service - uchar BQue:1; // basic command queueing - - uchar vs2:1; - uchar CmdQue:1; // full command queueing - uchar obsolete4:1; - uchar linked:1; - uchar sync:1; - uchar wbus16:1; // - uchar obsolete3:1; - uchar RelAddr:1; // treletive addressing - - char vendor[8]; - char product[16]; - char revision[4]; - char vendor_data[20]; - - uchar ius:1; - uchar qas:1; - uchar clocking:2; // - uchar reserved3:4; - - unsigned short version_desc[8]; - - char reserved4[21]; -} query_response_t; - -typedef struct ReadBlockCMD { - uchar cmd; - - uchar reladdr:1; - uchar reserved:2; - uchar fua:1; // force unit access flush to media - uchar dpo:1; // direct page out, do not cache - uchar reserved2:3; - - unsigned int block_address; - uchar reserved3; - - unsigned short block_count; - - uchar control; -} __attribute__ ((packed)) ReadBlockCMD_t ; - -int ll_read_block(devhandle sgd, char *buffer, int blocknum, int count) -{ - int ret; - ReadBlockCMD_t rb; - char sensedat[32]; - - memset(&rb,0,sizeof(rb)); - rb.cmd = READ_10; - rb.block_address = htonl(blocknum); - rb.block_count = htons(count); - - ret = scsi_command( sgd, (uint8_t *)&rb, sizeof(rb), SG_DXFER_FROM_DEV, buffer, count * 512, sensedat, sizeof(sensedat)); - - if(ret<0) { - DPRINTF("ERROR: ll_read_block( %x, %x, %x, %x) = %d\n", sgd, buffer, blocknum, count, ret); - PrintSense(sensedat, 32); - } - - return(ret); - -} - -int ll_write_block(devhandle sgd, char *buffer, int blocknum, int count) -{ - int ret; - ReadBlockCMD_t rb; - char sensedat[32]; - - memset(&rb,0,sizeof(rb)); - rb.cmd = WRITE_10; - rb.block_address = htonl(blocknum); - rb.block_count = htons(count); - - ret = scsi_command( sgd, (uint8_t *)&rb, sizeof(rb), SG_DXFER_TO_DEV, buffer, count * 512, sensedat, sizeof(sensedat)); - - return(ret); -} - -typedef struct ReadLongCMD { - uchar cmd; - - uchar reladdr:1; - uchar correct:1; - uchar reserved:5; - - unsigned int block_address; - uchar reserved3; - - unsigned short length; - - uchar control; -} __attribute__ ((packed)) ReadLongCMD_t ; - -int ll_read_long(devhandle sgd, char *buffer, int blocknum, int size) -{ - int ret; - ReadLongCMD_t rb; - char sensedat[32]; - - memset(&rb,0,sizeof(rb)); - rb.cmd = READ_LONG; - rb.block_address = htonl(blocknum); - rb.length = htons(size); - - ret = scsi_command( sgd, (uint8_t *)&rb, sizeof(rb), SG_DXFER_FROM_DEV, buffer, size, sensedat, sizeof(sensedat)); - return(ret); -} - -unsigned char ReadCapacityCMD[10] = { READ_CAPACITY, 0, 0,0,0,0, 0,0,0, 0}; - -struct ReadCapacityResponse { - unsigned int block_address; - unsigned int block_length; -}; - -int get_capacity(devhandle sgd, unsigned long *block_count, unsigned int *blk_len) -{ - int ret; - struct ReadCapacityResponse response; - char sensedat[32]; - - ret = scsi_command(sgd, ReadCapacityCMD, sizeof(ReadCapacityCMD), SG_DXFER_FROM_DEV, (uint8_t *)&response, sizeof(response), sensedat, sizeof(sensedat) ); - if(ret<0) { - DPRINTF("ERROR:get capacity: %d\n", ret); - PrintSense(sensedat,32); - } - - - *block_count = ntohl(response.block_address) +1; - *blk_len = ntohl(response.block_length); - - return(ret); -} - -#define INQ_REP_LEN 96 -unsigned char InquiryCMD[6] = { INQUIRY, 0, 0, 0, INQ_REP_LEN, 0}; - -int query(devhandle sgd, query_response_t *qr) -{ - int ret; - char sensedat[32]; - - ret = scsi_command(sgd, InquiryCMD, sizeof(InquiryCMD), SG_DXFER_FROM_DEV, (uint8_t *)qr, sizeof(query_response_t), sensedat, sizeof(sensedat) ); - - if(ret<0){ - DPRINTF("query: IOCTL"); - } - - return(ret); -} - -typedef struct lun_list { - unsigned int list_length; - unsigned int reserved; - unsigned long long lun[16]; -} lun_list_t; - -#define REPORT_LUNS 0xa0 -unsigned char ReportLunsCMD[12] = { REPORT_LUNS, 0, 2, 0, 0, 0, 0, 0, 0, 128, 0, 0 }; - -int ReportLUNS(devhandle sgd, lun_list_t *list) -{ - int ret; - char sensedat[32]; - - memset (list, 0, sizeof(lun_list_t)); - ret = scsi_command(sgd, ReportLunsCMD, sizeof(ReportLunsCMD), SG_DXFER_FROM_DEV, (uint8_t *)list, sizeof(lun_list_t), sensedat, sizeof(sensedat) ); - - if(ret<0) { - DPRINTF("Report Luns: IOCTL"); - } - - list->list_length = ntohl(list->list_length); - - return(ret); -} - -typedef struct command_descriptor { - uchar opcode; - uchar reserved; - unsigned short service_action; - uchar reserved2; - - uchar action_valid:1; - uchar reserved3:7; - - unsigned short cdb_len; -} __attribute__ ((packed)) command_descriptor_t; - -typedef struct report_opcodes_result { - unsigned long length; - - command_descriptor_t command[256]; -} __attribute__ ((packed)) report_opcode_result_t; - - -#define REPORT_OPCODES 0xa3 - -typedef struct report_opcodes_cmd { - uchar cmd; - uchar reserved[5]; - unsigned int reply_len; - uchar reserved2; - uchar control; -} __attribute__ ((packed)) ReportOpcodesCMD_t; - -//ReportOpcodesCMD_t ReportOpcodesCMD = { cmd : REPORT_OPCODES, reply_len: htonl(sizeof(report_opcode_result_t)) }; - -int ReportOpCodes(devhandle sgd, report_opcode_result_t *list) -{ - int ret; - char sensedat[32]; - ReportOpcodesCMD_t ReportOpcodesCMD; - - memset (list, 0, sizeof(report_opcode_result_t)); - ReportOpcodesCMD.cmd = REPORT_OPCODES; - ReportOpcodesCMD.reply_len = htonl( sizeof(report_opcode_result_t)); - - ret = scsi_command(sgd, (uint8_t *)&ReportOpcodesCMD, sizeof(ReportOpcodesCMD_t), SG_DXFER_FROM_DEV, (uint8_t *)list, sizeof(report_opcode_result_t), sensedat, sizeof(sensedat) ); - - if(ret<0) { - DPRINTF("Report Luns: IOCTL"); - } - - list->length = ntohl(list->length); - - return(ret); -} - - -#define READ_ATTRIBUTE 0x8c -#define VOLUME_LIST 2 -#define PARTITION_LIST 3 - -typedef struct read_attribute_cmd { - uchar cmd; - - uchar action:5; - uchar res:3; - - uchar restricted[3]; - - uchar volume; - uchar res2; - uchar partition; - - ushort attribute; - unsigned int reply_len; - uchar res3; - uchar control; -} __attribute__ ((packed)) ReadAttributeCMD_t; - -int CheckVolumes(devhandle sgd) -{ - int ret; - uchar reply[4]; - uchar sensedat[32]; - ReadAttributeCMD_t cmd; - - memset(&cmd,0,sizeof(cmd)); - - cmd.cmd=READ_ATTRIBUTE; - cmd.action = VOLUME_LIST; - cmd.reply_len = htonl(4); - - ret = scsi_command(sgd, (uint8_t *)&cmd, sizeof(cmd), SG_DXFER_FROM_DEV, reply, sizeof(reply), sensedat, sizeof(sensedat) ); - if(ret<0) { - DPRINTF("Report Volumes: IOCTL"); - return(-1); - } - - if(! reply[0] && !reply[1]) - return(0); - - return(reply[3]); -} - -int CheckPartitions(devhandle sgd) -{ - int ret; - uchar reply[4]; - uchar sensedat[32]; - ReadAttributeCMD_t cmd; - - memset(&cmd,0,sizeof(cmd)); - - cmd.cmd=READ_ATTRIBUTE; - cmd.action = PARTITION_LIST; - cmd.reply_len = htonl(4); - - ret = scsi_command(sgd, (uint8_t *)&cmd, sizeof(cmd), SG_DXFER_FROM_DEV, reply, sizeof(reply), sensedat, sizeof(sensedat) ); - if(ret<0) { - DPRINTF("Report PARTITIONVolumes: IOCTL"); - return(-1); - } - - if(! reply[0] && !reply[1]) - return(0); - - return(reply[3]); -} - -int UnitReady(devhandle sgd) -{ - uchar cmd[6]; - uchar sensedat[32]; - int ret; - - memset(cmd,0,sizeof(cmd)); - - ret = scsi_command(sgd, &cmd, sizeof(cmd), SG_DXFER_FROM_DEV, NULL, 0, sensedat, sizeof(sensedat) ); - if(ret<0) { - DPRINTF("UnitReady :"); - return(0); - } - - return(1); -} - - -#endif diff --git a/src/filo/usb/scsi_cmds.h b/src/filo/usb/scsi_cmds.h deleted file mode 100644 index 1c64a3bf3..000000000 --- a/src/filo/usb/scsi_cmds.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _SCSI_CMDS_H -#define _SCSI_CMDS_H - -#define devhandle uint8_t - -#define uchar uint8_t -#define ushort uint16_t - -void PrintSense(uchar *sense, int len); -int ll_read_block(devhandle sgd, char *buffer, int blocknum, int count); - -int get_capacity(devhandle sgd, unsigned long *block_count, unsigned int *blk_len); -int UnitReady(uchar sgd); -#endif diff --git a/src/filo/usb/uhci.c b/src/filo/usb/uhci.c deleted file mode 100644 index 4ce4b499c..000000000 --- a/src/filo/usb/uhci.c +++ /dev/null @@ -1,1143 +0,0 @@ -#ifdef USB_DISK - -/******************************************************************************* - * - * - * Copyright 2003 Steven James <pyro@linuxlabs.com> and - * LinuxLabs http://www.linuxlabs.com - * - * 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 <etherboot.h> -#include <pci.h> -#include <timer.h> -#include <lib.h> - -#define DEBUG_THIS DEBUG_USB -#include <debug.h> - -#define DPRINTF debug - - -#include "usb.h" -#include "uhci.h" -#include "debug_x.h" - -#define ALLOCATE 1 - -extern int usec_offset; - -int wait_head( queue_head_t *head, int count) -{ - td_t *td; - - - while(!head->depth.terminate) { - td = MEM_ADDR(head->depth.link); - if(!td->active) - return(-1); // queue failed - - if(count) - if(! --count) - return(0); // still active - - udelay(500); // give it some time - } - - return(1); // success -} - -queue_head_t *free_qh; -queue_head_t _queue_heads[MAX_QUEUEHEAD]; -queue_head_t *queue_heads = _queue_heads; - -queue_head_t *new_queue_head(void) -{ - queue_head_t *qh; - - if(!free_qh) - return(NULL); - - qh = free_qh; - free_qh = MEM_ADDR(qh->bredth.link); - - memset(qh,0,sizeof(queue_head_t)); - qh->bredth.terminate = qh->depth.terminate=1; - - return(qh); -} - -void free_queue_head( queue_head_t *qh) -{ - - qh->bredth.link = LINK_ADDR(free_qh); - if(!free_qh) - qh->bredth.terminate=1; - - qh->depth.terminate=1; - free_qh = qh; -} - -void init_qh(void) -{ - int i; - - for(i=0; i<MAX_QUEUEHEAD-1; i++) { - memset(queue_heads+i, 0, sizeof(queue_head_t)); - queue_heads[i].bredth.link = LINK_ADDR( &queue_heads[i+1] ); - queue_heads[i].depth.terminate=1; - } - - queue_heads[MAX_QUEUEHEAD-1].depth.terminate=1; - queue_heads[MAX_QUEUEHEAD-1].bredth.terminate=1; - - free_qh = queue_heads; -} - -td_t *free_td_list; -td_t _tds[MAX_TD]; -td_t *tds = _tds; // indirection added for kernel testing - - -void init_td(void) -{ - int i; - - for(i=0; i<MAX_TD-1; i++) { - memset(tds+i, 0, sizeof(td_t)); - tds[i].link.link = LINK_ADDR( &tds[i+1]); - } - - memset( &tds[MAX_TD-1], 0, sizeof(td_t)); - tds[MAX_TD-1].link.terminate=1; - - free_td_list = tds; -} - -td_t *new_td(void) -{ - td_t *td; - - if(!free_td_list) - return(NULL); - -// DPRINTF("new_td: free_td = %p\n", free_td_list); - td = free_td_list; - - free_td_list = MEM_ADDR( td->link.link); -// DPRINTF("new_td: free_td_list = %p\n", free_td_list); - - memset(td, 0, sizeof(td_t)); - td->link.terminate=1; - -// DPRINTF("new_td: returning %p\n", td); - return(td); -} - -td_t *find_last_td(td_t *td) -{ - td_t *last; - - last = td; - - while(!last->link.terminate) - last = MEM_ADDR(last->link.link); - - return(last); -} - -void free_td( td_t *td) -{ - td_t *last_td; - - last_td = find_last_td(td); - - last_td->link.link = LINK_ADDR(free_td_list); - if(!free_td_list) - last_td->link.terminate=1; - else - last_td->link.terminate=0; - - free_td_list = td; - -} - -link_pointer_t *queue_end( queue_head_t *queue) -{ - link_pointer_t *link; - - link = &(queue->depth); - - while(!link->terminate) - link = MEM_ADDR(link->link); - - return(link); -} - -void add_td( queue_head_t *head, td_t *td) -{ - link_pointer_t *link; - - link = queue_end(head); - - link->link = LINK_ADDR(td); - link->terminate=0; -} - -transaction_t transactions[MAX_TRANSACTIONS]; -transaction_t *free_transactions; - -void init_transactions(void) -{ - int i; - - memset(transactions, 0, sizeof(transactions)); - - for(i=0; i<MAX_TRANSACTIONS-1; i++) - transactions[i].next = &transactions[i+1]; - - free_transactions = transactions; -} - -void free_transaction( transaction_t *trans ) -{ - transaction_t *my_current, *last; - - my_current = trans; - - if(my_current==0) return; - - while(my_current) { - free_td( my_current->td_list ); - free_queue_head( my_current->qh ); - - last = my_current; - my_current = my_current->next; - } - - last->next = free_transactions; - free_transactions = trans; -} - -transaction_t *new_transaction(td_t *td) -{ - transaction_t *trans = free_transactions; - queue_head_t *qh; - - if(!trans) { - DPRINTF("new_transaction( td = %x) failed!\n", td); - return(NULL); - } - - free_transactions = trans->next; - - memset(trans, 0, sizeof(transaction_t)); - - if(td) { - qh = new_queue_head(); - if(!qh) { - free_transaction(trans); - return(NULL); - } - - trans->qh = qh; - trans->td_list = td; - qh->depth.link = LINK_ADDR(td); - qh->depth.terminate = 0; - qh->bredth.terminate=1; - } - - return(trans); -} - -transaction_t *add_transaction( transaction_t *trans, td_t *td) -{ - transaction_t *t1; - - - t1 = new_transaction(td); - if(!t1) - return(NULL); - - trans->next = t1; - trans->qh->bredth.terminate=0; - trans->qh->bredth.link = LINK_ADDR(t1->qh); - trans->qh->bredth.queue=1; - - return(trans); -} - -link_pointer_t *frame_list[MAX_CONTROLLERS]; -#if 0 -uchar fl_buffer[MAX_CONTROLLERS][8192]; -#endif - -void init_framelist(uchar dev) -{ - - int i; -#if 0 - DPRINTF("raw frame_list is at %x\n", fl_buffer[dev]); - frame_list[dev] = (link_pointer_t *) ((bus_to_virt)(((unsigned int)virt_to_bus(fl_buffer[dev]) & ~0xfff) + 0x1000)); -#else - frame_list[dev] = (link_pointer_t *) allot2(sizeof(link_pointer_t)*1024, 0xfff); // 4K alignment - if(frame_list[dev]==0) { - printf("init_framelist: no mem\n"); - } -#endif - memset(frame_list[dev], 0, 1024 * sizeof(link_pointer_t)); - - - DPRINTF("frame_list is at %x\n", frame_list[dev]); - - for(i=0;i<1024;i++) - frame_list[dev][i].terminate=1; - -} - - -extern int num_controllers; - -extern uint32_t hc_base[MAX_CONTROLLERS]; -extern uint8_t hc_type[MAX_CONTROLLERS]; - -void uhc_clear_stat() -{ - unsigned short value; - - value = inw(USBSTS(0)); - outw(value, USBSTS(0)); -} - -void clear_uport_stat(unsigned short port) -{ - unsigned short value; - - value = inw(port); - outw(value, port); -} - -void uport_suspend( unsigned short port) -{ - unsigned short value; - - value = inw(port); - value |= 0x1000; - outw( value, port); - -} - -void uport_wakeup( unsigned short port) -{ - unsigned short value; - - value = inw(port); - value &= ~0x1000; - outw( value, port); - -} - -#if 0 -void uport_resume( unsigned short port) -{ - unsigned short value; - - value = inw(port); - value |= 0x40; - outw(value, port); - udelay(20000+usec_offset); - value &= ~0x40; - outw(value, port); - - do { - value = inw(port); - } while(value & 0x40); -} - -#endif -void uport_enable( unsigned short port) -{ - unsigned short value; - - value = inw(port); - value |= 0x04; - outw( value, port); - - do { - value = inw(port); - } while( !(value & 0x04) && (value & 0x01)); - -} - - -void uport_disable( unsigned short port) -{ - unsigned short value; - - value = inw(port); - value &= ~0x04; - outw( value, port); -} - -void uport_reset(unsigned short port) -{ - unsigned short value; - int i; - - value = inw(port); - value |= 0x200; - - outw( value, port); - - for(i=0;i<5;i++) - udelay(10000+usec_offset); - - value &= ~0x200; - outw( value, port); - -// DPRINTF("Port %04x reset\n", port); -} - -void uport_reset_long(unsigned short port) -{ - unsigned short value; - int i; - - value = inw(port); - value |= 0x200; - outw( value, port); - - for(i=0; i<20; i++) - udelay(10000); - - value &= ~0x200; - outw( value, port); - -// DPRINTF("Port %04x reset\n", port); -} - -void uhc_reset(uchar controller) -{ - DPRINTF("Resetting UHCI\n"); - outw(0x04, USBCMD(controller)); - udelay(20000); - outw(0, USBCMD(controller)); -} -#if 0 -int uhc_stop(uchar dev) -{ - unsigned short tmp; - - tmp = inw(USBCMD(dev)); - tmp &= ~USBCMDRUN; - outw( tmp, USBCMD(dev)); - - while(! (inw(USBSTS(dev)) & USBSTSHALTED) ); - outw( USBSTSHALTED, USBSTS(dev)); // clear the status - - return(0); -} - -#endif - -int uhc_start(uchar dev) { - unsigned short tmp; - - DPRINTF("Starting UHCI\n"); - - tmp = inw(USBCMD(dev)); - tmp |= USBCMDRUN; - -// tmp |= USBCMD_DEBUG; - outw( tmp, USBCMD(dev)); - - return(0); -} - -int uhc_init(struct pci_device *dev) -{ - int16_t word; - - - pci_read_config_word(dev, 0x20, &word); - hc_base[num_controllers] = word; - hc_base[num_controllers] &= ~1; - - DPRINTF("Found UHCI at %04x\n", hc_base[num_controllers]); - uhc_reset(num_controllers); - - // set master - pci_read_config_word(dev, 0x04, &word); - word |= 0x04; - pci_write_config_word(dev, 0x04, word); - -#if 0 - if( ((unsigned int) virt_to_bus(frame_list[num_controllers])) != ( ( (unsigned int)virt_to_bus(frame_list[num_controllers])) & ~0x7ff) ) { - DPRINTF("UHCI: grave error, misaligned framelist (%x)\n", frame_list[num_controllers]); - return(-1); - } -#endif - - DPRINTF("uhc_init setting framelist to: %08x\n", (unsigned int) virt_to_bus( (frame_list[num_controllers]) )); - outl( (unsigned int) virt_to_bus(frame_list[num_controllers]), FLBASE(num_controllers)); - outw( 0, FRNUM(num_controllers)); - outw( 0, USBINTR(num_controllers)); // no interrupts! - - outw(0x1000, PORTSC1(num_controllers)); - outw(0x1000, PORTSC2(num_controllers)); - - uhc_start(num_controllers); - - dump_uhci(hc_base[num_controllers]); - - num_controllers++; - return(0); -} - -queue_head_t *sched_queue[MAX_CONTROLLERS]; -queue_head_t *term_qh[MAX_CONTROLLERS]; -//td_t *dummy_td[MAX_CONTROLLERS]; -td_t *loop_td[MAX_CONTROLLERS]; - -void init_sched(uchar dev) -{ - int i; - -// dummy_td[dev] = new_td(); - loop_td[dev] = new_td(); - term_qh[dev] = new_queue_head(); - - sched_queue[dev] = new_queue_head(); - sched_queue[dev]->bredth.terminate=0; - sched_queue[dev]->bredth.queue=1; - sched_queue[dev]->bredth.link=LINK_ADDR(term_qh[dev]); - sched_queue[dev]->depth.terminate=1; - - term_qh[dev]->bredth.terminate=1; - term_qh[dev]->depth.link = LINK_ADDR(loop_td[dev]); - term_qh[dev]->depth.terminate=0; - -// dummy_td->link.link = LINK_ADDR(sched_queue); -// dummy_td->link.queue = 1; -// dummy_td->link.depth=1; -// dummy_td->link.terminate=0; -// dummy_td->packet_type = IN_TOKEN; -// dummy_td->max_transfer = 0x7; -// dummy_td->isochronous=1; -// dummy_td->active=1; -// dummy_td->device_addr = 0x7f; -// dummy_td->endpoint=0x01; -// dummy_td->buffer = virt_to_bus(&dummy_td->data[2]); -// dummy_td->retrys=3; - -//dump_hex( (uchar *) dummy_td, sizeof(td_t), "dummy_td "); - - loop_td[dev]->link.link = LINK_ADDR(loop_td[dev]); - loop_td[dev]->link.terminate=0; - loop_td[dev]->link.queue=0; - loop_td[dev]->packet_type = IN_TOKEN; - loop_td[dev]->max_transfer=7; - loop_td[dev]->retrys=0; - loop_td[dev]->device_addr=0x7f; - - for(i=0; i< 1024; i++) { - frame_list[dev][i].link = LINK_ADDR(sched_queue[dev]); - frame_list[dev][i].queue=1; - frame_list[dev][i].terminate=0; -// frame_list[dev][i].terminate=1; - } - - dump_link( frame_list[dev], "frame_list_link: "); -// DPRINTF("dummy_td = %x\n", dummy_td[dev]); - -// dump_frame_list("sched:"); - -} - -void uhci_init(void) -{ - int i; - - init_td(); - init_qh(); - init_transactions(); - - for(i=0;i<MAX_CONTROLLERS; i++) { - if(hc_type[i] == 0x00) { - init_framelist(i); - init_sched(i); - } - } - - // From now should not change num_controllers any more -} - -int poll_queue_head( queue_head_t *qh) -{ - td_t *td; - int strikes=3; - - if(qh->depth.terminate) - return(1); - - while(strikes--) { - if(qh->depth.terminate) - return(1); - - td = MEM_ADDR(qh->depth.link); - - if(td->active) - return(0); - - udelay(1000); - -// if(!td->active) -// return(1); - } - - return(1); -} - -int wait_queue_complete( queue_head_t *qh) -{ - int ret; - int spins=1000; - - while( --spins && !(ret = poll_queue_head(qh))) { - udelay(1500); -// if(!(spins%30)) -// DPRINTF("wait_queue_complete: spin\n"); - } -// DPRINTF("wait_queue_complete: returning %d\n", ret); - - if(!spins) - return(-1); - - return(ret); -} - -#define BULK_DEPTH 1 - -transaction_t *_bulk_transfer( uchar devnum, uchar ep, unsigned int len, uchar *data) -{ - uchar dt; - transaction_t *trans; - td_t *td, *cur, *last; - int remaining = len; - uchar *pos = data; - int max; - uchar type = OUT_TOKEN; - int packet_length; - - - if(ep & 0x80) - type = IN_TOKEN; - - ep &= 0x7f; - - td = cur = last = NULL; - dt = usb_device[devnum].toggle[ep]; - max = usb_device[devnum].max_packet[ep]; - - while(remaining) { - cur = new_td(); - cur->packet_type = type; - cur->data_toggle = dt; - cur->endpoint = ep&0x7f; - cur->device_addr = devnum; - cur->detect_short=1; - cur->active=1; - dt = dt^0x01; - - if(!td){ - td = cur; - } - - if(last) { - last->link.terminate=0; - last->link.link = LINK_ADDR(cur); - } - - cur->buffer = (void *) virt_to_bus(pos); - - if(remaining>max) { - packet_length = max; - } - else { - packet_length = remaining; - } - - cur->max_transfer=packet_length-1; - cur->link.depth = BULK_DEPTH; - - remaining -= packet_length; - pos+= packet_length; - last = cur; - } - -// if( packet_length == max) { // if final packet wasn't short, add a zero packet -// cur = new_td(); -// dt = dt^0x01; -// cur->packet_type = type; -// cur->max_transfer = 0x7ff; // zero length code -// last->link.terminate=0; -// last->link.link = LINK_ADDR(cur); -// -// } - - cur->link.terminate=1; - - trans = new_transaction(td); - usb_device[devnum].toggle[ep] = dt; - - return(trans); -} - -#define DEPTH 0 - -transaction_t *ctrl_msg(uchar devnum, uchar request_type, uchar request, unsigned short wValue, unsigned short wIndex, unsigned short wLength, uchar *data) -{ - td_t *td; - td_t *current_td; - td_t *last_td; - transaction_t *trans; - - ctrl_msg_t *message; - - unsigned char type; - int remaining = wLength; - uchar *pos = data; - uchar dt=1; - -// DPRINTF("ctrl_msg( %02x, %02x, %02x, %04x, %04x, %04x, %p)\n", devnum, request_type, request, wValue, wIndex, wLength, data); -// DPRINTF("%d bytes in payload\n", remaining); -// DPRINTF("lowspeed = %u\n", usb_device[devnum].lowspeed); - last_td = td = new_td(); - - td->packet_type = SETUP_TOKEN; - td->device_addr = devnum & 0x7f; - td->max_transfer = 7; // fixed for setup packets - td->retrys = CTRL_RETRIES; - td->active=1; - td->data_toggle=0; - td->link.depth=DEPTH; - td->detect_short=0; - td->interrupt=1; - td->lowspeed = usb_device[devnum].lowspeed; - -// steal 8 bytes from so-called software area to hole the control message itself - td->buffer = (void *) virt_to_bus(&(td->data[2])); - message = bus_to_virt( (unsigned int) td->buffer); - - message->bmRequestType = request_type; - message->bRequest = request; - message->wValue = wValue; - message->wIndex = wIndex; - message->wLength = wLength; -//dump_hex(td, sizeof(td_t), "ctrl_msg:"); - trans = new_transaction(td); - - if(!trans) { - DPRINTF("ctrl_msg: couldn't allocate a transaction!\n"); - return(NULL); - } - - if(request_type & CONTROL_DIR_MASK) - type = IN_TOKEN; - else - type = OUT_TOKEN; - - while(remaining >0) { - int length; - -// DPRINTF("ctrl_msg loop %d remaining, maxpacket = %u\n", remaining, usb_device[devnum].max_packet[0]); - current_td = new_td(); - - last_td->link.link = LINK_ADDR(current_td); - last_td->link.terminate=0; - last_td->link.queue=0; - last_td->link.depth=DEPTH; - - - current_td->device_addr = devnum & 0x7f; - current_td->retrys = CTRL_RETRIES; - current_td->active=1; - current_td->data_toggle=dt; - current_td->link.depth=DEPTH; - current_td->lowspeed = usb_device[devnum].lowspeed; - current_td->detect_short=1; - - dt = dt^0x01; - - current_td->packet_type = type; -// if(type == IN_TOKEN) -// current_td->detect_short=1; - - if(remaining >usb_device[devnum].max_packet[0]) - length = usb_device[devnum].max_packet[0]; - else - length = remaining; - - current_td->max_transfer = length-1; - current_td->buffer = (void *) virt_to_bus(pos); - remaining -= length; - pos += length; - - last_td = current_td; - } - - current_td = new_td(); - - current_td->device_addr = devnum & 0x7f; - current_td->retrys = CONTROL_STS_RETRIES; - current_td->active=1; - current_td->lowspeed = usb_device[devnum].lowspeed; - - if(type == IN_TOKEN) - current_td->packet_type = OUT_TOKEN; - else - current_td->packet_type = IN_TOKEN; - - current_td->max_transfer=0x7ff; - - current_td->link.terminate=1; - current_td->data_toggle=1; - current_td->link.depth=DEPTH; - - - last_td->link.link = LINK_ADDR(current_td); - last_td->link.terminate=0; - last_td->link.queue=0; - last_td->link.depth=DEPTH; - - return(trans); -} - - -int schedule_transaction( uchar dev, transaction_t *trans) -{ - unsigned short value; - - if(!sched_queue[dev]->depth.terminate) - return(-EBUSY); - - sched_queue[dev]->depth.link = LINK_ADDR(trans->qh); - sched_queue[dev]->depth.terminate = 0; - sched_queue[dev]->depth.queue=1; - - if(hc_type[dev]==0x00) { - value = inw(hc_base[dev]); - value |=1; - outw( value, hc_base[dev]); - } -#if 0 - else if (hc_type[dev]==0x10) { - uint32_t value; - ohci_regs_t *ohci_regs = (ohci_regs_t *) hc_base[dev]; - value = readl(&ohci_regs->control); - value |=OHCI_USB_OPER; - writel( value, &ohci_regs->control); - - } -#endif - - return(0); -} - -int wait_transaction( transaction_t *trans) -{ - queue_head_t *qh; - - qh = trans->qh; - - while(!qh->bredth.terminate) - qh = MEM_ADDR(qh->bredth.link); - - return( wait_queue_complete(qh)); -} - -void unlink_transaction( uchar dev, transaction_t *trans) -{ - sched_queue[dev]->depth.terminate=1; - sched_queue[dev]->depth.link = 0; // just in case -} - -int uhci_bulk_transfer( uchar devnum, uchar ep, unsigned int len, uchar *data) -{ - transaction_t *trans; - td_t *td; - int data_len; - int ret; - uchar *buffer; - DPRINTF("bulk_transfer: ep = %x len=%d\n", ep, len); -#if ALLOCATE==1 - buffer = allot2(2048, 0x7ff); - if(buffer==0){ - printf("bulk_transfer: can not allot\n"); - } - memset(buffer,0,2048); -// DPRINTF("bulk_transfer: buffer(virt) = %x buffer(phys) = %x len = %d\n", buffer, virt_to_phys(buffer), len); - - if( !(ep & 0x80)) - memcpy(buffer, data, len); -#else - buffer = data; -#endif - - - trans = _bulk_transfer(devnum, ep, len, buffer); -#if 0 -#ifdef DEBUG - dump_transaction(trans, "bulk_transfer:"); -#endif -#endif - schedule_transaction( usb_device[devnum].controller, trans); - ret = wait_transaction(trans); - - if(ret<0) { -#ifdef DEBUG - dump_uhci(hc_base[usb_device[devnum].controller] ); - dump_td(trans->td_list, "failed_bulk_transaction: "); -#endif - unlink_transaction( usb_device[devnum].controller, trans); - free_transaction(trans); -#if ALLOCATE==1 - forget2(buffer); -#endif - return(-1); - } - - unlink_transaction( usb_device[devnum].controller, trans); - - data_len=0; - td = trans->td_list; - do { - if(td->active) - break; - - if(td->max_transfer == 0x7ff) - break; - - data_len += td->actual +1; - - if(td->actual < td->max_transfer) // short packet also check for errors here - break; - - if(!td->link.terminate){ - td = MEM_ADDR(td->link.link); - } - else { - td=NULL; - } - } while(td); -#if 0 - -#ifdef DEBUG - dump_td(trans->td_list, "bulk_transfer_success:"); -#endif -#endif - - if(data_len < len) { - DPRINTF("bulk_transfer( dev= %d, ep = %d, len = %d, buffer = %x) = %d:short transaction:\n", devnum, ep, len, data, data_len); - dump_td(trans->td_list, "short_transaction:"); - } - - free_transaction(trans); - -#if ALLOCATE==1 - if( (ep & 0x80)) - memcpy(data, buffer, len); - forget2(buffer); -#endif - - - DPRINTF("bulk_transfer returning %d\n", data_len); - return(data_len); -} - -int uhci_control_msg( uchar devnum, uchar request_type, uchar request, unsigned short wValue, unsigned short wIndex, unsigned short wLength, void *data) -{ - transaction_t *trans; - td_t *td; - int data_len=0; - uchar *buffer; - int ret; - DPRINTF("uhci_control_msg: request_type = %x request = %x wLength=%d\n", request_type, request, wLength); -#if ALLOCATE==1 -// if( (wLength!=0) && (data!=NULL) ) { - buffer = allot2(2048+wLength,0x7ff); - if(buffer==0){ - printf("uhci_control_msg: can not allot\n"); - } - - memset(buffer,0,2048+wLength); - //DPRINTF("uhci_control_msg: buffer(virt) = %x buffer(phys) = %x wLength=%d\n", buffer, virt_to_phys(buffer), wLength); - if( !(request_type & 0x80)) - memcpy(buffer, data, wLength); -// } else { -// buffer=NULL; -// } - -#else - buffer = data; -#endif - - trans = ctrl_msg(devnum, request_type, request, wValue, wIndex, wLength, buffer); - if(!trans) { - DPRINTF("uhci_control_msg: ctrl_msg failed!\n"); -#if ALLOCATE==1 - forget2(buffer); -#endif - return(-1); - } - - schedule_transaction( usb_device[devnum].controller, trans); - ret = wait_transaction(trans); - - if(ret<0) { -#ifdef DEBUG - dump_uhci(hc_base[usb_device[devnum].controller] ); - dump_td(trans->td_list, "failed_transaction: "); -#endif - unlink_transaction( usb_device[devnum].controller, trans); - free_transaction(trans); -#if ALLOCATE==1 - forget2(buffer); -#endif - return(ret); - } - -//#ifdef DEBUG -// dump_td(trans->td_list, "success: "); -//#endif - - unlink_transaction( usb_device[devnum].controller, trans); - - // now, see what happened - - if(!trans->qh->depth.terminate) { -// handle setup error - - dump_uhci(hc_base); - dump_td(trans->td_list, "qh->depth failed_transaction: "); - - free_transaction(trans); -#if ALLOCATE==1 - forget2(buffer); -#endif - return(-1); - } - - td = trans->td_list; - - do { - if(td->packet_type != SETUP_TOKEN) - data_len += td->actual; - - if(td->actual < td->max_transfer) // short packet also check for errors here - break; - - if(!td->link.terminate) { - td = MEM_ADDR(td->link.link); - } - else { - td=NULL; - } - } while(td); - - free_transaction(trans); - -#if ALLOCATE==1 - if ( (wLength!=0) && (data!=NULL)){ - if( (request_type & 0x80)) - memcpy(data, buffer, wLength); - forget2(buffer); - } -#endif - - DPRINTF("usb_control_message returning %d\n", data_len); - - return(data_len); -} - - -int poll_u_root_hub(unsigned short port, uchar controller) -{ - ushort value; - int addr=0; - int i; - static int do_over=0; - - value = inw(port); - - debug("poll_u_root_hub1 v=%08x\t", value); - - if(value & 0x02 || do_over == port) { - debug("poll_u_root_hub2 v=%08x\t", value); - do_over=0; - if(value & 0x01 ) { // if port connected - debug("poll_u_root_hub21 v=%08x\t", value); - DPRINTF("Connection on port %04x\n", port); - - outw(value, port); - for(i=0; i<40; i++) { - udelay(10000+usec_offset); - value = inw(port); - if(value & 0x02) { - outw(value, port); - i=0; - DPRINTF("BOUNCE!\n"); - } - } - - uport_wakeup(port); -// DPRINTF("Wakup %04x\n", port); - - uport_reset(port); - udelay(10); - uport_enable(port); - - if(!value & 0x01) { - DPRINTF("Device went away!\n"); - return(-1); - } - - addr = configure_device( port, controller, value & 0x100); - - if(addr<0) { - uport_disable(port); - udelay(20000); -// uport_reset(port); - uport_reset_long(port); - uport_suspend(port); - do_over=port; - uhc_clear_stat(); -// dump_uhci(0x38c0); - } - } else { - uport_suspend(port); - uport_disable(port); - DPRINTF("Port %04x disconnected\n", port); - // wave hands, deconfigure devices on this port! - } - } - - - return(addr); -} - -#endif diff --git a/src/filo/usb/uhci.h b/src/filo/usb/uhci.h deleted file mode 100644 index 17370a13d..000000000 --- a/src/filo/usb/uhci.h +++ /dev/null @@ -1,175 +0,0 @@ -#ifndef _UHCI_H -#define _UHCI_H - -/* - * The link pointer is multi use. Some fields are valid only for some uses. - * In other cases, they must be 0 - * - */ - -#define MAX_POLLDEV 10 - -#define MAX_TRANSACTIONS 10 -#define MAX_QUEUEHEAD 255 -#define MAX_TD 1024 - - -typedef struct link_pointer { - unsigned long terminate:1; - unsigned long queue:1; - unsigned long depth:1; - unsigned long reserved:1; - unsigned long link:28; -} __attribute__((packed)) link_pointer_t; - -extern link_pointer_t *frame_list[]; - -void init_framelist(uchar dev); - - -#define SETUP_TOKEN 0x2d -#define IN_TOKEN 0x69 -#define OUT_TOKEN 0xe1 - -#define CTRL_RETRIES 3 -#define CONTROL_STS_RETRIES 0 - - -// some port features -#define PORT_CONNECTION 0 -#define PORT_ENABLE 1 -#define PORT_SUSPEND 2 -#define PORT_OVER_CURRENT 3 -#define PORT_RESET 4 -#define PORT_POWER 8 -#define PORT_LOW_SPEED 9 -#define C_PORT_CONNECTION 16 -#define C_PORT_ENABLE 17 -#define C_PORT_SUSPEND 18 -#define C_PORT_OVER_CURRENT 19 -#define C_PORT_RESET 20 - -// features -#define FEATURE_HALT 0 - -typedef struct td { - - link_pointer_t link; - - unsigned long actual:11; // actual length - unsigned long reserved2:5; - -// status/error flags - unsigned long res1:1; - unsigned long bitstuff:1; - unsigned long crc:1; - unsigned long nak:1; - unsigned long babble:1; - unsigned long buffer_error:1; - unsigned long stall:1; - unsigned long active:1; - - unsigned long interrupt:1; // interrupt on complete - unsigned long isochronous:1; - unsigned long lowspeed:1; - unsigned long retrys:2; - unsigned long detect_short:1; - unsigned long reserved3:2; - - unsigned long packet_type:8; // one of in (0x69), out (0xe1) or setup (0x2d) - unsigned long device_addr:7; - unsigned long endpoint:4; - unsigned long data_toggle:1; - unsigned long reserved:1; - unsigned long max_transfer:11; // misnamed. Desired length might be better - - void *buffer; - unsigned long data[4]; // free use by driver -} __attribute__((packed)) td_t; - -typedef struct queue_head { - link_pointer_t bredth; // depth must = 0 - link_pointer_t depth; // depth may vary randomly, ignore - unsigned long int udata[2]; -} __attribute__((packed)) queue_head_t; - -typedef struct transaction { - queue_head_t *qh; - td_t *td_list; - struct transaction *next; -} transaction_t; - -//##################################################### -int wait_head( queue_head_t *head, int count); - -extern queue_head_t *free_qh; -extern queue_head_t *queue_heads; - -queue_head_t *new_queue_head(void); -void free_queue_head( queue_head_t *qh); -void init_qh(void); - -extern td_t *free_td_list; -extern td_t *tds; - -void init_td(void); -td_t *new_td(void); -td_t *find_last_td(td_t *td); -void free_td( td_t *td); -link_pointer_t *queue_end( queue_head_t *queue); -void add_td( queue_head_t *head, td_t *td); - -extern transaction_t transactions[MAX_TRANSACTIONS]; -extern transaction_t *free_transactions; - -void init_transactions(void); -void free_transaction( transaction_t *trans ); -transaction_t *new_transaction(td_t *td); -transaction_t *add_transaction( transaction_t *trans, td_t *td); - - -#define USBCMD(x) hc_base[x] -#define USBSTS(x) (hc_base[x] + 0x02) -#define USBINTR(x) (hc_base[x] + 0x04) -#define FRNUM(x) ( hc_base[x] + 0x06) -#define FLBASE(x) ( hc_base[x] + 0x08) -#define SOFMOD(x) ( hc_base[x] + 0x0c) -#define PORTSC1(x) ( hc_base[x] + 0x10) -#define PORTSC2(x) ( hc_base[x] + 0x12) - -#define USBCMDRUN 0x01 -#define USBCMD_DEBUG 0x20 - -#define USBSTSHALTED 0x20 - - -void hc_reset(uchar dev); -int hc_stop(void); -int hc_start(uchar dev); - -extern queue_head_t *sched_queue[]; - -void init_sched(uchar dev); -int poll_queue_head( queue_head_t *qh); -int wait_queue_complete( queue_head_t *qh); - -extern int num_polls; -extern int (*devpoll[MAX_POLLDEV])(uchar); -extern uchar parm[MAX_POLLDEV]; - -transaction_t *_bulk_transfer( uchar devnum, uchar ep, unsigned int len, uchar *data); -transaction_t *ctrl_msg(uchar devnum, uchar request_type, uchar request, unsigned short wValue, unsigned short wIndex, unsigned short wLength, uchar *data); -int schedule_transaction( uchar dev, transaction_t *trans); -int wait_transaction( transaction_t *trans); -void unlink_transaction( uchar dev, transaction_t *trans); -int uhci_bulk_transfer( uchar devnum, uchar ep, unsigned int len, uchar *data); -int uhci_control_msg( uchar devnum, uchar request_type, uchar request, unsigned short wValue, unsigned short wIndex, unsigned short wLength, void *data); - - -// defined in uhci.c -int uhc_init(struct pci_device *dev); -void uhci_init(void); -void clear_uport_stat(unsigned short port); -int poll_u_root_hub(unsigned short port, uchar controller); - -#endif diff --git a/src/filo/usb/usb.c b/src/filo/usb/usb.c deleted file mode 100644 index 23afe9a71..000000000 --- a/src/filo/usb/usb.c +++ /dev/null @@ -1,803 +0,0 @@ -#ifdef USB_DISK - -/******************************************************************************* - * - * - * Copyright 2003 Steven James <pyro@linuxlabs.com> and - * LinuxLabs http://www.linuxlabs.com - * - * 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 <etherboot.h> -#include <pci.h> -#include <timer.h> -#include <lib.h> - -#define DEBUG_THIS DEBUG_USB -#include <debug.h> - -#define DPRINTF debug - - -#include "usb.h" -#include "uhci.h" -#include "ohci.h" -#include "debug_x.h" - - -#define ALLOCATE 1 - -int usec_offset=0; - -int num_controllers=0; - -uint32_t hc_base[MAX_CONTROLLERS]; -uint8_t hc_type[MAX_CONTROLLERS]; - - -void hci_init(void) -{ - int i; - struct pci_device *dev; - uint8_t prog_if; - - - for(i=0;i<MAX_CONTROLLERS; i++) { - hc_type[i] = 0xff; - } - - /* Find a PCI_SERIAL_USB class device */ - i=0; - num_controllers = 0; - while(num_controllers<MAX_CONTROLLERS) { - dev = pci_find_device(-1, -1, 0x0c03, -1, i); - if(!dev) break; - - prog_if = ((dev->class>>8) & 0xff); - if(prog_if == 0x00 ) { // UHCI - hc_type[num_controllers] = prog_if; - uhc_init(dev); - } - else if(prog_if == 0x10) { // OHCI - hc_type[num_controllers] = prog_if; - ohc_init(dev); - } -#if 0 - else if(prog_if == 0x20) { // EHCI - hc_type[num_controllers] = prog_if; - ehc_init(dev); - } -#endif - i++; - } - // From now should not change num_controllers any more - - uhci_init(); - ohci_init(); -} - - -int next_usb_dev; -usbdev_t usb_device[MAX_USB_DEV]; - -void init_devices(void) -{ - - memset(usb_device,0,sizeof(usb_device)); - usb_device[0].max_packet[0] = 8; - next_usb_dev=2; // 0 for all controller root hub, use MAX_CONTROLLERS instead??? - // do we need have one for every controller ?? or just use hc_base and hc_type instead - // For example 0 --> controller 1 root hub - // 1 --> controller 2 root hub - // 2 --> controller 3 root hub.... -} - - -inline int set_address( uchar address) -{ - int ret; - - ret = usb_control_msg(0, 0, SET_ADDRESS, address, 0, 0, NULL); - - return(ret); -} - -inline int clear_stall(uchar device, uchar endpoint) -{ - int ret; - - ret = usb_control_msg(device, CONTROL_ENDPOINT, CLEAR_FEATURE, FEATURE_HALT, endpoint, 0, NULL); - if(hc_type[device]==0x00) { - usb_device[device].toggle[endpoint]=0; - } - else if(hc_type[device]==0x10) { - usb_settoggle(&usb_device[device], endpoint & 0xf, ((endpoint & 0x80)>>7)^1, 0); - } - - return(ret); -} - -inline int device_reset(uchar device) { - return usb_control_msg(device, 0x21, 0xff, 0, 0, 0, NULL); -} - -/////////////////////////////////////////////////////////////////////////////////////// -// -// String Descriptors -// -////////////////////////////////////////////////////////////////////////////////////// - -#define STRING_DESCRIPTOR 0x0300 - -int get_string( uchar addr, uchar string, int len, uchar *buffer) -{ - int ret; - int i,j; - int real_len; - ushort lang; - - if(!string) { - strcpy(buffer, "unknown"); - return(0); - } - - ret = usb_control_msg(addr, 0x80, GET_DESCRIPTOR, STRING_DESCRIPTOR | string, 0, 4, buffer); - real_len = buffer[0]; - if(real_len>len) - real_len = len; - - lang = buffer[2] | buffer[3]<<8; - ret = usb_control_msg(addr, 0x80, GET_DESCRIPTOR, STRING_DESCRIPTOR | string, lang, real_len, buffer); - - // de-unicode it! - for(i=0, j=2; j<real_len; i++, j+=2) - buffer[i] = buffer[j]; - - buffer[i]=0; - real_len/=2; - - return(real_len); -} - -int get_string2( uchar addr, uchar string, ushort lang, int len, uchar *buffer) -{ - int ret; - int i,j; - int real_len; - - - ret = usb_control_msg(addr, 0x80, GET_DESCRIPTOR, STRING_DESCRIPTOR | string, lang, len, buffer); - - real_len = buffer[0]; - if(real_len>len) - real_len = len; - - if(real_len<=4) { - strcpy(buffer, "USB"); - real_len = 3; - buffer[real_len] = 0; - } else { - // de-unicode it! - for(i=0, j=2; j<real_len; i++, j+=2) - buffer[i] = buffer[j]; - - buffer[i]=0; - real_len/=2; - } - - return(real_len); -} -ushort get_lang( uchar addr, uchar string, int len, uchar *buffer) -{ - int ret; - int i,j; - int real_len; - ushort lang; - - ret = usb_control_msg(addr, 0x80, GET_DESCRIPTOR, STRING_DESCRIPTOR | string, 0, 4, buffer); - lang = buffer[2] | buffer[3]<<8; - - return lang; -} - -/////////////////////////////////////////////////////////////////////////////////////// -// -// HUB functions. This will be moved to it's own module soonishly -// -/////////////////////////////////////////////////////////////////////////////////////// - -typedef struct port_charge { - ushort c_port_connection:1; - ushort c_port_enable:1; - ushort c_port_suspend:1; - ushort c_port_over_current:1; - ushort c_port_reset:1; - ushort reserved:11; -} port_change_t; - -typedef struct port_status { - ushort port_connection:1; - ushort port_enable:1; - ushort port_suspend:1; - ushort port_over_current:1; - ushort port_reset:1; - ushort reserved:3; - ushort port_power:1; - ushort port_lowspeed:1; - ushort port_highspeed:1; - ushort port_test:1; - ushort port_indicator:1; -} __attribute__ ((packed)) portstatus_t; - - -typedef struct portstat { - portstatus_t stat; - port_change_t change; -} __attribute__ ((packed)) portstat_t; - -int hub_port_reset( uchar addr, uchar port) -{ - int ret; - int tries=100; - portstat_t status; - - ret = usb_control_msg(addr, 0x23, SET_FEATURE, PORT_RESET, port, 0, NULL); // reset port - - while(tries--) { - udelay(10000); - ret = usb_control_msg(addr, 0xa3, GET_STATUS, 0x0, port, 4, &status); - if(!status.change.c_port_reset) - continue; - - ret = usb_control_msg(addr, 0x23, CLEAR_FEATURE, C_PORT_RESET, port, 0, NULL); // clear status - return(0); - } - - DPRINTF("hub_port_reset(%x, %x) failed,\n", addr, port); - dump_hex((uint8_t *)&status, 4, "status="); - - return(-1); -} - -int hub_port_resume( uchar addr, uchar port) -{ - int ret; - int tries=100; - portstat_t status; - - ret = usb_control_msg(addr, 0x23, CLEAR_FEATURE, PORT_SUSPEND, port, 0, NULL); // reset port - - while(tries--) { - udelay(10000); - ret = usb_control_msg(addr, 0xa3, GET_STATUS, 0x0, port, 4, &status); - if(!status.change.c_port_suspend) - continue; - - ret = usb_control_msg(addr, 0x23, CLEAR_FEATURE, C_PORT_SUSPEND, port, 0, NULL); // clear status - return(0); - } - - return(-1); -} - -int poll_hub(uchar addr) -{ - int i; - int ret; - uchar devaddr=0; - hub_descriptor_t *desc; - portstat_t status; - - DPRINTF("Poll hub (%x)\n", addr); - desc = usb_device[addr].private; - - for(i=1; i<= desc->bNbrPorts; i++) { - ret = usb_control_msg(addr, 0xa3, GET_STATUS, 0x0, i, 4, &status); -// DPRINTF("Get status for port %u returns: %d\n", i, ret); -// dump_hex(&status, 4, "status="); - - if(status.change.c_port_connection) { - ret = usb_control_msg(addr, 0x23, CLEAR_FEATURE, C_PORT_CONNECTION, i, 0, NULL); // clear status - - if(status.stat.port_connection) { - udelay(desc->bPwrOn2PwrGood * 20000); - - hub_port_resume(addr, i); - - ret = hub_port_reset(addr,i); - udelay(10); - ret = usb_control_msg(addr, 0x23, SET_FEATURE, PORT_ENABLE, i, 0, NULL); // enable port - -// ret = usb_control_msg(addr, 0xa3, GET_STATUS, 0x0, i, 4, &status); -// DPRINTF("*****Get status again for port %u returns: %d\n", i, ret); -// dump_hex(&status, 4, "status="); - - devaddr = configure_device(i, usb_device[addr].controller, status.stat.port_lowspeed); - - // configure - } else { - ret = usb_control_msg(addr, 0x23, SET_FEATURE, PORT_SUSPEND, i, 0, NULL); // suspend port - ret = usb_control_msg(addr, 0x23, CLEAR_FEATURE, PORT_ENABLE, i, 0, NULL); // disable port - DPRINTF("Hub %d, Port %04x disconnected\n", addr, i); - // deconfigure - } - } - } - return(devaddr); - -} - -int usb_hub_init( uchar addr) -{ - int i; - int ret; - hub_descriptor_t *desc; - - desc = allot(sizeof(hub_descriptor_t)); - - memset(desc, 0 , sizeof(hub_descriptor_t)); - - DPRINTF("hub init (%d)\n", addr); - - ret = usb_control_msg(addr, 0xa0, GET_DESCRIPTOR, 0x2900, 0, 8, desc); - ret = usb_control_msg(addr, 0xa0, GET_DESCRIPTOR, 0x2900, 0, desc->bLength, desc); - - usb_device[addr].private = desc; - - for(i=1; i<=desc->bNbrPorts; i++) - ret = usb_control_msg(addr, 0x23, SET_FEATURE, PORT_POWER, i, 0, NULL); // power port - - - // register hub to be polled - - devpoll[num_polls] = poll_hub; - parm[num_polls++] = addr; - - return(0); -} - -extern void ohci_dump_x(uchar controller); - -// will set up whatever device is answering at address 0. -int configure_device(uint32_t port, uchar controller, unsigned int lowspeed) -{ - device_descriptor_t *desc; - config_descriptor_t *conf; - interface_descriptor_t *iface; - endpoint_descriptor_t *epd; - int ret; - int i; - int addr = next_usb_dev++; - uchar buffer[512]; - uchar string[255]; - ushort lang; - uchar x[2]; - - desc = (device_descriptor_t *) buffer; - - memset( &usb_device[addr], 0, sizeof(usbdev_t)); - - printf("New USB device, setting address %d\n", addr); - if(lowspeed) { - usb_device[addr].lowspeed = usb_device[0].lowspeed = 1; - DPRINTF("LOWSPEED\n"); - } else - usb_device[addr].lowspeed = usb_device[0].lowspeed = 0; - - usb_device[0].port = usb_device[addr].port = port; - usb_device[0].controller = usb_device[addr].controller = controller; - usb_device[addr].toggle2[0]=0; - usb_device[addr].toggle2[1]=0; - -// hc_clear_stat(); - - ret = set_address(addr); - if(ret<0) { - DPRINTF("configure_device: set_address failed!\n"); - next_usb_dev--; - return(-1); - } - - mdelay(10); /* Let the SET_ADDRESS settle */ - - usb_device[addr].max_packet[0] = 8; - - - DPRINTF("Fetching device descriptor length\n"); - ret = usb_control_msg(addr, 0x80, GET_DESCRIPTOR, 0x100, 0, 8, desc); - - usb_device[addr].max_packet[0] = desc->max_packet; - - DPRINTF("Fetching device descriptor\n"); - ret = usb_control_msg(addr, 0x80, GET_DESCRIPTOR, 0x100, 0, desc->bLength, desc); - if(ret < desc->bLength) - return(-1); - - DPRINTF("Fetching config descriptor length\n"); - conf = (config_descriptor_t *) (buffer + sizeof(device_descriptor_t)); - - ret = usb_control_msg(addr, 0x80, GET_DESCRIPTOR, 0x200, 0, 8, conf); - - DPRINTF("Fetching config descriptor\n"); - ret = usb_control_msg(addr, 0x80, GET_DESCRIPTOR, 0x200, 0, conf->wTotalLength, conf); - if(ret < conf->wTotalLength) - return(-1); - - iface = (interface_descriptor_t *) (buffer + sizeof(device_descriptor_t) + conf->bLength); - epd = (endpoint_descriptor_t *) (buffer + conf->bLength + iface->bLength + sizeof(device_descriptor_t)); - - DPRINTF("device:\n"); - dump_device_descriptor( desc, ""); - DPRINTF("config:\n"); - dump_config_descriptor( (uchar *)conf, ""); - - DPRINTF("Selecting Configuration number %x:\n", conf->bConfigurationValue); - ret = usb_control_msg(addr, 0, SET_CONFIGURATION, conf->bConfigurationValue, 0, 0, NULL); - -// mdelay(20); - -#if 0 - usb_control_msg(addr, 0x80, GET_CONFIGURATION, 0, 0, 1 , x); - DPRINTF("Configuration number = %x\n", x[0]); - - usb_control_msg(addr, 0x80, GET_STATUS, 0, addr, 2, x); - DPRINTF("status = %x %x\n", x[0], x[1]); - - usb_control_msg(addr, 0x81, GET_STATUS, 0, 0, 2, x); - DPRINTF("status = %x %x\n", x[0], x[1]); -#endif - - for(i=0; i<iface->bNumEndpoints;i++) { - if(!epd[i].bEndpointAddress) { - usb_device[addr].max_packet[ 1 ] = epd[i].wMaxPacketSize & 0x3ff; - } else { - usb_device[addr].max_packet[ epd[i].bEndpointAddress & 0x7f ] = epd[i].wMaxPacketSize & 0x3ff; - } - - if( (epd[i].bmAttributes & 0x03) == 0x01) // interrupt - usb_device[addr].interrupt = epd[i].bEndpointAddress; - - if( (epd[i].bmAttributes & 0x03) == 0x02) { // bulk -#if 0 - DPRINTF("clear stall on ep=%x\n", epd[i].bEndpointAddress); - clear_stall(addr, epd[i].bEndpointAddress); // to reset data toggle - udelay(10); -#endif - -#if 0 - usb_control_msg(addr, 0x82, GET_STATUS, 0, epd[i].bEndpointAddress, 2, x); - DPRINTF("status = %x %x\n", x[0], x[1]); -#endif - - if(epd[i].bEndpointAddress & 0x80){ //in - usb_device[addr].bulk_in = epd[i].bEndpointAddress; - } - else { //out - usb_device[addr].bulk_out = epd[i].bEndpointAddress; - } - } - - } - - // determine device class - if(desc->Class) { - usb_device[addr].class = desc->Class; - usb_device[addr].subclass = desc->SubClass; - usb_device[addr].protocol = desc->protocol; - } else { - usb_device[addr].class = iface->bInterfaceClass; - usb_device[addr].subclass = iface->bInterfaceSubClass; - usb_device[addr].protocol = iface->bInterfaceProtocol; - } - - printf("%02x:%02x:%02x\n", usb_device[addr].class, usb_device[addr].subclass, usb_device[addr].protocol); -#if 0 - get_string(addr, desc->iManufacturor, sizeof(string), string); - printf("Manufacturor: %s\n", string); - - get_string(addr, desc->iProduct, sizeof(string), string); - printf("Product: %s\n", string); - - get_string(addr, desc->iSerial, sizeof(string), string); - printf("Serial: %s\n", string); -#else - lang = get_lang(addr, 0, sizeof(string), string); - - get_string2(addr, desc->iManufacturor, lang, sizeof(string), string); - printf("Manufacturor: %s\n", string); - - get_string2(addr, desc->iProduct, lang,sizeof(string), string); - printf("Product: %s\n", string); - - get_string2(addr, desc->iSerial, lang, sizeof(string), string); - printf("Serial: %s\n", string); -#endif - - switch( usb_device[addr].class) { - case 0x09: // hub - usb_hub_init(addr); - break; - - default: - break; - - } - - DPRINTF("DEVICE CONFIGURED\n"); - - return(addr); -} - -int num_polls=0; -int (*devpoll[MAX_POLLDEV])(uchar); -uchar parm[MAX_POLLDEV]; - -int poll_usb() -{ - int addr; - int found=0; - int i; - int j; - - for(i=0; i<num_controllers; i++) { - debug("poll_usb1 i=%d\t", i); - // if addr >0, should probably see what was attached! - if(hc_type[i]==0x00) { - addr = poll_u_root_hub(PORTSC1(i), i); - if(addr && !found) - found=addr; - - addr = poll_u_root_hub(PORTSC2(i), i); - if(addr && !found) - found=addr; - } - - else if(hc_type[i]==0x10) { - int NDP; - NDP = readl(&ohci_regs->roothub.a) & 0xff; - ohci_regs = (ohci_regs_t *)hc_base[i]; - for(j=0;j<NDP;j++) { - addr = poll_o_root_hub((uint32_t)&ohci_regs->roothub.portstatus[j], i); - if(addr && !found) - found=addr; - } - - } - - } - - // now poll registered drivers (such as the hub driver - for(i=0;i<num_polls; i++) { - debug("poll_usb2 i=%d\t", i); - addr = devpoll[i](parm[i]); - if(addr && !found) - found=addr; - } - - return(found); -} - - -int usb_bulk_transfer( uchar devnum, uchar ep, unsigned int len, uchar *data) -{ - uint8_t hc_num = usb_device[devnum].controller; - if(ep&0x80) { - ep = usb_device[devnum].bulk_in; - } else { - ep = usb_device[devnum].bulk_out; - } - - if(hc_type[hc_num] == 0x00) { //UHCI - return uhci_bulk_transfer(devnum, ep, len, data); - } - else if( hc_type[hc_num] == 0x10 ) { //OHCI - return ohci_bulk_transfer(devnum, ep, len, data); - } -#if 0 - else if (hc_type[hc_num] == 0x20 ) { //EHCI - return ehci_bulk_transfer(devnum, ep, len, data); - } -#endif - return 0; -} -int usb_control_msg( uchar devnum, uchar request_type, uchar request, unsigned short wValue, unsigned short wIndex, - unsigned short wLength, void *data) -{ - - uint8_t hc_num = usb_device[devnum].controller; - - if(hc_type[hc_num] == 0x00) { //UHCI - return uhci_control_msg(devnum, request_type, request, wValue, wIndex, wLength, data); - } - else if( hc_type[hc_num] == 0x10 ) { //OHCI - return ohci_control_msg(devnum, request_type, request, wValue, wIndex, wLength, data); - } -#if 0 - else if (hc_type[hc_num] == 0x20 ) { //EHCI - return ehci_control_msg(devnum, request_type, request, wValue, wIndex, wLength, data); - } -#endif - return 0; -} - - -struct urb *usb_alloc_urb(int controller) -{ - struct urb *urb; - ohci_t *ohci = NULL; -#if URB_PRE_ALLOCATE!=1 - urb = (struct urb *)allot2(sizeof(struct urb),0xff); - if (!urb) { - printf("usb_alloc_urb: allot2 failed"); - return NULL; - } -#else - if(hc_type[controller] == 0x10) { //OHCI - ohci = &_ohci_x[controller]; - urb = ohci->urb; - } else { - urb = NULL; - } -#endif - - memset(urb, 0, sizeof(*urb)); - - return urb; -} -/** - * usb_free_urb - frees the memory used by a urb - * @urb: pointer to the urb to free - * - * If an urb is created with a call to usb_create_urb() it should be - * cleaned up with a call to usb_free_urb() when the driver is finished - * with it. - */ -void usb_free_urb(struct urb* urb) -{ -#if URB_PRE_ALLOCATE!=1 - if (urb) - forget2(urb); -#endif -} - -void usb_wait_urb_done(struct urb* urb, int timeout) -{ - usbdev_t *usb_dev = urb->dev; - if(hc_type[usb_dev->controller]==0x10) { - ohci_wait_urb_done(urb, timeout); - } - -} - - -int usb_submit_urb(struct urb *urb) -{ - if (urb && urb->dev) { -#if 0 - if(hc_type[urb->dev->controller] == 0x00) { - return uhci_submit_urb(urb); - } else -#endif - if(hc_type[urb->dev->controller] == 0x10) { - return ohci_submit_urb(urb); - } -#if 0 - else if(hc_type[urb->dev->controller] == 0x20) { - return ohci_submit_urb(urb); - } -#endif - return 0; - } - else - return -ENODEV; -} - -// Starts urb and waits for completion or timeout -static int usb_start_wait_urb(struct urb *urb, int timeout, int* actual_length) -{ - int status; - status = usb_submit_urb(urb); - -//for OHCI We will check the BLF and CLF, because HC after processing all td list, it will clear the BLF and CLF - usb_wait_urb_done(urb, timeout); -//Add by LYH to call complete function - if(urb->complete!=0) urb->complete(urb); - - if (actual_length) - *actual_length = urb->actual_length; - - usb_free_urb(urb); - return status; -} -// returns status (negative) or length (positive) -int usb_internal_control_msg(struct usbdev *usb_dev, unsigned int pipe, - struct usb_ctrlrequest *cmd, void *data, int len, int timeout, usb_complete_t complete) -{ - struct urb *urb; - int retv; - int length; - - urb = usb_alloc_urb(usb_dev->controller); - if (!urb) - return -ENOMEM; - - FILL_CONTROL_URB(urb, usb_dev, pipe, (unsigned char*)cmd, data, len, - complete,0); - - retv = usb_start_wait_urb(urb, timeout, &length); - if (retv < 0) - return retv; - else - return length; -} -int usb_control_msg_x(struct usbdev *dev, unsigned int pipe, u8 request, u8 requesttype, - u16 value, u16 index, void *data, u16 size, int timeout, usb_complete_t complete) -{ - struct usb_ctrlrequest *dr; - int ret; - int controller = dev->controller; - ohci_t *ohci; - -#if URB_PRE_ALLOCATE!=1 - dr = allot2(sizeof(struct usb_ctrlrequest), 0xf); - if (!dr) { - printf("usb_control_msg_x: dr allocate no MEM\n"); - return -ENOMEM; - } -#else - if(hc_type[controller] == 0x10) { //OHCI - ohci = &_ohci_x[controller]; - dr = ohci->dr; - } else { - dr = NULL; - } - -#endif - - dr->bRequestType = requesttype; - dr->bRequest = request; - dr->wValue = cpu_to_le16p(&value); - dr->wIndex = cpu_to_le16p(&index); - dr->wLength = cpu_to_le16p(&size); - - ret = usb_internal_control_msg(dev, pipe, dr, data, size, timeout, complete); - -#if URB_PRE_ALLOCATE!=1 - forget2(dr); -#endif - - return ret; -} -int usb_bulk_msg_x(struct usbdev *usb_dev, unsigned int pipe, - void *data, int len, int *actual_length, int timeout, usb_complete_t complete) -{ - struct urb *urb; - - if (len < 0) - return -EINVAL; - - urb=usb_alloc_urb(usb_dev->controller); - if (!urb) - return -ENOMEM; - - FILL_BULK_URB(urb, usb_dev, pipe, data, len, - complete, 0); - - return usb_start_wait_urb(urb,timeout,actual_length); -} - -#endif diff --git a/src/filo/usb/usb.h b/src/filo/usb/usb.h deleted file mode 100644 index 58fd57347..000000000 --- a/src/filo/usb/usb.h +++ /dev/null @@ -1,435 +0,0 @@ -#ifndef _USB_H -#define _USB_H - -#define URB_PRE_ALLOCATE 1 - -#define u32 uint32_t -#define u16 uint16_t -#define u8 uint8_t - -#define uchar uint8_t -#define ushort uint16_t -#define EBUSY 1 -#define ENOMEM 12 -#define ENODEV 19 -#define EINVAL 22 -#define EINPROGRESS 115 - -#define LINK_ADDR(x) ( virt_to_bus(x) >> 4) -#define MEM_ADDR(x) (void *) ( bus_to_virt( ((unsigned int) (x)) <<4) ) - -#define MAX_CONTROLLERS 4 - -extern int num_controllers; - -extern uint32_t hc_base[]; -extern uint8_t hc_type[]; - -// Some control message bmRequestType defines -#define CTRL_DEVICE 0 -#define CONTROL_INTERFACE 1 -#define CONTROL_ENDPOINT 2 -#define CONTROL_OTHER 3 -#define CONTROL_RECIPIENT_MASK 0x1f - -#define CONTROL_TYPE_STD 0 -#define CONTROL_TYPE_CLASS 0x20 -#define CONTROL_CLASS_VENDOR 0x40 -#define CONTROL_CLASS_MASK 0x60 - -#define CONTROL_OUT 0 -#define CONTROL_IN 0x80 -#define CONTROL_DIR_MASK 0x80 - -// bRequest values -#define GET_STATUS 0 -#define CLEAR_FEATURE 1 -#define SET_FEATURE 3 -#define SET_ADDRESS 5 - -#define GET_DESCRIPTOR 6 -#define SET_DESCRIPTOR 7 - -#define GET_CONFIGURATION 8 -#define SET_CONFIGURATION 9 - -#define GET_INTERFACE 10 -#define SET_INTERFACE 11 - -#define SYNC_FRAME 12 - -// descriptor types -#define DEVICE_DESC 1 -#define CONFIGURATION_DESC 2 -#define STRING_DESC 3 -#define INTERFACE_DESC 4 -#define ENDPOINT_DESC 5 -#define OTHERSPEED_DESC 7 -#define POWER_DESC 8 - - -typedef struct device_descriptor { - uchar bLength; - uchar type; - - uchar bcdVersion[2]; - uchar Class; - uchar SubClass; - uchar protocol; - uchar max_packet; - - unsigned short idVendor; - unsigned short idProduct; - - uchar bcdDevice[2]; - uchar iManufacturor; - uchar iProduct; - uchar iSerial; - uchar bNumConfig; -} __attribute__((packed)) device_descriptor_t; - -#define GET_DESCRIPTOR 6 - -typedef struct config_descriptor { - uchar bLength; - uchar type; - - unsigned short wTotalLength; - uchar bNumInterfaces; - uchar bConfigurationValue; - uchar iConfiguration; - - uchar bmAttributes; - uchar bMaxPower; -} __attribute__((packed)) config_descriptor_t; - -typedef struct interface_descriptor { - uchar bLength; - uchar type; - - uchar bInterfaceNumber; - uchar bAlternateSetting; - - uchar bNumEndpoints; - uchar bInterfaceClass; - uchar bInterfaceSubClass; - uchar bInterfaceProtocol; - uchar iInterface; -} __attribute__((packed)) interface_descriptor_t; - -typedef struct endpoint_descriptor { - uchar bLength; - uchar type; - - uchar bEndpointAddress; - uchar bmAttributes; - unsigned short wMaxPacketSize; - uchar bInterval; -} __attribute__((packed)) endpoint_descriptor_t; - -typedef struct ctrl_msg { - uchar bmRequestType; - uchar bRequest; - unsigned short wValue; - unsigned short wIndex; - unsigned short wLength; -} __attribute__((packed)) ctrl_msg_t; - -// Some descriptors for hubs, will be moved later -typedef struct hub_descriptor { - uchar bLength; - uchar type; - - uchar bNbrPorts; - ushort wHubCharacteristics; - uchar bPwrOn2PwrGood; - uchar bHubCntrCurrent; - - uchar DeviceRemovable; // assume bNbrPorts <=8 - uchar PortPwrCntrMask; -} __attribute__((packed)) hub_descriptor_t; - -#define MAX_USB_DEV 127 -#define MAX_EP 8 - -typedef struct usbdev { - uint32_t port; - uchar address; - uchar controller; - uchar class; - uchar subclass; - uchar protocol; - uchar bulk_in; - uchar bulk_out; - uchar interrupt; - uchar lowspeed; - uint32_t toggle2[2]; //For OHCI - uint32_t halted[2]; - uchar toggle[MAX_EP]; //for UHCI - unsigned short max_packet[MAX_EP]; - void *private; -} usbdev_t; - -// I will use urb as transaction for OHCI to remember the td and ed - -struct urb; -typedef void (*usb_complete_t)(struct urb *); - -struct urb -{ -#if 0 - spinlock_t lock; // lock for the URB -#endif - void *hcpriv; // private data for host controller -#if 0 - struct list_head urb_list; // list pointer to all active urbs - struct urb *next; // pointer to next URB -#endif - struct usbdev *dev; // pointer to associated USB device - unsigned int pipe; // pipe information - int status; // returned status - unsigned int transfer_flags; // USB_DISABLE_SPD | USB_ISO_ASAP | etc. - void *transfer_buffer; // associated data buffer - void *transfer_dma; // dma addr for transfer_buffer - int transfer_buffer_length; // data buffer length - int actual_length; // actual data buffer length - int bandwidth; // bandwidth for this transfer request (INT or ISO) - unsigned char *setup_packet; // setup packet (control only) - void * setup_dma; // dma addr for setup_packet - // - int start_frame; // start frame (iso/irq only) - int number_of_packets; // number of packets in this request (iso) - int interval; // polling interval (irq only) - int error_count; // number of errors in this transfer (iso only) - int timeout; // timeout (in jiffies) - // - void *context; // context for completion routine - usb_complete_t complete; // pointer to completion routine - // -#if 0 - struct iso_packet_descriptor iso_frame_desc[0]; -#endif -}; - -typedef struct urb urb_t; - -/* - * urb->transfer_flags: - */ -#define USB_DISABLE_SPD 0x0001 -#define URB_SHORT_NOT_OK USB_DISABLE_SPD -#define USB_ISO_ASAP 0x0002 -#define USB_ASYNC_UNLINK 0x0008 -#define USB_QUEUE_BULK 0x0010 -#define USB_NO_FSBR 0x0020 -#define USB_ZERO_PACKET 0x0040 // Finish bulk OUTs always with zero length packet -#define URB_NO_INTERRUPT 0x0080 /* HINT: no non-error interrupt needed */ - /* ... less overhead for QUEUE_BULK */ -#define USB_TIMEOUT_KILLED 0x1000 // only set by HCD! - - -struct usb_ctrlrequest { - u8 bRequestType; - u8 bRequest; - u16 wValue; - u16 wIndex; - u16 wLength; -} __attribute__ ((packed)); - -/* - * USB-status codes: - * USB_ST* maps to -E* and should go away in the future - */ - -#define USB_ST_NOERROR 0 -#define USB_ST_CRC (-EILSEQ) -#define USB_ST_BITSTUFF (-EPROTO) -#define USB_ST_NORESPONSE (-ETIMEDOUT) /* device not responding/handshaking */ -#define USB_ST_DATAOVERRUN (-EOVERFLOW) -#define USB_ST_DATAUNDERRUN (-EREMOTEIO) -#define USB_ST_BUFFEROVERRUN (-ECOMM) -#define USB_ST_BUFFERUNDERRUN (-ENOSR) -#define USB_ST_INTERNALERROR (-EPROTO) /* unknown error */ -#define USB_ST_SHORT_PACKET (-EREMOTEIO) -#define USB_ST_PARTIAL_ERROR (-EXDEV) /* ISO transfer only partially completed */ -#define USB_ST_URB_KILLED (-ENOENT) /* URB canceled by user */ -#define USB_ST_URB_PENDING (-EINPROGRESS) -#define USB_ST_REMOVED (-ENODEV) /* device not existing or removed */ -#define USB_ST_TIMEOUT (-ETIMEDOUT) /* communication timed out, also in urb->status**/ -#define USB_ST_NOTSUPPORTED (-ENOSYS) -#define USB_ST_BANDWIDTH_ERROR (-ENOSPC) /* too much bandwidth used */ -#define USB_ST_URB_INVALID_ERROR (-EINVAL) /* invalid value/transfer type */ -#define USB_ST_URB_REQUEST_ERROR (-ENXIO) /* invalid endpoint */ -#define USB_ST_STALL (-EPIPE) /* pipe stalled, also in urb->status*/ - -/** - * FILL_CONTROL_URB - macro to help initialize a control urb - * @URB: pointer to the urb to initialize. - * @DEV: pointer to the struct usb_device for this urb. - * @PIPE: the endpoint pipe - * @SETUP_PACKET: pointer to the setup_packet buffer - * @TRANSFER_BUFFER: pointer to the transfer buffer - * @BUFFER_LENGTH: length of the transfer buffer - * @COMPLETE: pointer to the usb_complete_t function - * @CONTEXT: what to set the urb context to. - * - * Initializes a control urb with the proper information needed to submit - * it to a device. This macro is depreciated, the usb_fill_control_urb() - * function should be used instead. - */ -#define FILL_CONTROL_URB(URB,DEV,PIPE,SETUP_PACKET,TRANSFER_BUFFER,BUFFER_LENGTH,COMPLETE,CONTEXT) \ - do {\ - (URB)->dev=DEV;\ - (URB)->pipe=PIPE;\ - (URB)->setup_packet=SETUP_PACKET;\ - (URB)->transfer_buffer=TRANSFER_BUFFER;\ - (URB)->transfer_buffer_length=BUFFER_LENGTH;\ - (URB)->complete=COMPLETE;\ - (URB)->context=CONTEXT;\ - } while (0) - - -/** - * FILL_BULK_URB - macro to help initialize a bulk urb - * @URB: pointer to the urb to initialize. - * @DEV: pointer to the struct usb_device for this urb. - * @PIPE: the endpoint pipe - * @TRANSFER_BUFFER: pointer to the transfer buffer - * @BUFFER_LENGTH: length of the transfer buffer - * @COMPLETE: pointer to the usb_complete_t function - * @CONTEXT: what to set the urb context to. - * - * Initializes a bulk urb with the proper information needed to submit it - * to a device. This macro is depreciated, the usb_fill_bulk_urb() - * function should be used instead. - */ -#define FILL_BULK_URB(URB,DEV,PIPE,TRANSFER_BUFFER,BUFFER_LENGTH,COMPLETE,CONTEXT) \ - do {\ - (URB)->dev=DEV;\ - (URB)->pipe=PIPE;\ - (URB)->transfer_buffer=TRANSFER_BUFFER;\ - (URB)->transfer_buffer_length=BUFFER_LENGTH;\ - (URB)->complete=COMPLETE;\ - (URB)->context=CONTEXT;\ - } while (0) - - -/* - * USB directions - */ -#define USB_DIR_OUT 0 /* to device */ -#define USB_DIR_IN 0x80 /* to host */ - -/* - * USB Packet IDs (PIDs) - */ -#define USB_PID_UNDEF_0 0xf0 -#define USB_PID_OUT 0xe1 -#define USB_PID_ACK 0xd2 -#define USB_PID_DATA0 0xc3 -#define USB_PID_PING 0xb4 /* USB 2.0 */ -#define USB_PID_SOF 0xa5 -#define USB_PID_NYET 0x96 /* USB 2.0 */ -#define USB_PID_DATA2 0x87 /* USB 2.0 */ -#define USB_PID_SPLIT 0x78 /* USB 2.0 */ -#define USB_PID_IN 0x69 -#define USB_PID_NAK 0x5a -#define USB_PID_DATA1 0x4b -#define USB_PID_PREAMBLE 0x3c /* Token mode */ -#define USB_PID_ERR 0x3c /* USB 2.0: handshake mode */ -#define USB_PID_SETUP 0x2d -#define USB_PID_STALL 0x1e -#define USB_PID_MDATA 0x0f /* USB 2.0 */ - -#define PIPE_ISOCHRONOUS 0 -#define PIPE_INTERRUPT 1 -#define PIPE_CONTROL 2 -#define PIPE_BULK 3 - -#define usb_maxpacket(dev, pipe, out) ((dev)->max_packet[usb_pipeendpoint(pipe)]) -#define usb_packetid(pipe) (((pipe) & USB_DIR_IN) ? USB_PID_IN : USB_PID_OUT) - -#define usb_pipeout(pipe) ((((pipe) >> 7) & 1) ^ 1) -#define usb_pipein(pipe) (((pipe) >> 7) & 1) -#define usb_pipedevice(pipe) (((pipe) >> 8) & 0x7f) -#define usb_pipe_endpdev(pipe) (((pipe) >> 8) & 0x7ff) -#define usb_pipeendpoint(pipe) (((pipe) >> 15) & 0xf) -#define usb_pipedata(pipe) (((pipe) >> 19) & 1) -#define usb_pipeslow(pipe) (((pipe) >> 26) & 1) -#define usb_pipetype(pipe) (((pipe) >> 30) & 3) -#define usb_pipeisoc(pipe) (usb_pipetype((pipe)) == PIPE_ISOCHRONOUS) -#define usb_pipeint(pipe) (usb_pipetype((pipe)) == PIPE_INTERRUPT) -#define usb_pipecontrol(pipe) (usb_pipetype((pipe)) == PIPE_CONTROL) -#define usb_pipebulk(pipe) (usb_pipetype((pipe)) == PIPE_BULK) - -#define PIPE_DEVEP_MASK 0x0007ff00 - - -/* The D0/D1 toggle bits */ -#define usb_gettoggle(dev, ep, out) (((dev)->toggle2[out] >> (ep)) & 1) -#define usb_dotoggle(dev, ep, out) ((dev)->toggle2[out] ^= (1 << (ep))) -static inline void usb_settoggle(struct usbdev *dev, - unsigned int ep, - unsigned int out, - int bit) -{ - dev->toggle2[out] &= ~(1 << ep); - dev->toggle2[out] |= bit << ep; -} - - -/* Endpoint halt control/status */ -#define usb_endpoint_out(ep_dir) (((ep_dir >> 7) & 1) ^ 1) -#define usb_endpoint_halt(dev, ep, out) ((dev)->halted[out] |= (1 << (ep))) -#define usb_endpoint_running(dev, ep, out) ((dev)->halted[out] &= ~(1 << (ep))) -#define usb_endpoint_halted(dev, ep, out) ((dev)->halted[out] & (1 << (ep))) - - -static inline unsigned int __create_pipe(usbdev_t *dev, unsigned int endpoint) -{ - return (dev->address << 8) | (endpoint << 15) | - ((dev->lowspeed == 1) << 26); -} - -static inline unsigned int __default_pipe(struct usbdev *dev) -{ - return ((dev->lowspeed == 1) << 26); -} - -/* Create various pipes... */ -#define usb_sndctrlpipe(dev,endpoint) ((PIPE_CONTROL << 30) | __create_pipe(dev,endpoint)) -#define usb_rcvctrlpipe(dev,endpoint) ((PIPE_CONTROL << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN) -#if 0 -#define usb_sndisocpipe(dev,endpoint) ((PIPE_ISOCHRONOUS << 30) | __create_pipe(dev,endpoint)) -#define usb_rcvisocpipe(dev,endpoint) ((PIPE_ISOCHRONOUS << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN) -#endif -#define usb_sndbulkpipe(dev,endpoint) ((PIPE_BULK << 30) | __create_pipe(dev,endpoint)) -#define usb_rcvbulkpipe(dev,endpoint) ((PIPE_BULK << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN) -#if 0 -#define usb_sndintpipe(dev,endpoint) ((PIPE_INTERRUPT << 30) | __create_pipe(dev,endpoint)) -#define usb_rcvintpipe(dev,endpoint) ((PIPE_INTERRUPT << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN) -#endif -#define usb_snddefctrl(dev) ((PIPE_CONTROL << 30) | __default_pipe(dev)) -#define usb_rcvdefctrl(dev) ((PIPE_CONTROL << 30) | __default_pipe(dev) | USB_DIR_IN) - - -extern int next_usb_dev; -usbdev_t usb_device[MAX_USB_DEV]; - -void init_devices(void); -void hci_init(void); -int hc_init(struct pci_device *dev); -inline int set_address(uchar address); -inline int clear_stall(uchar device, uchar endpoint); -int poll_usb(); -int configure_device(uint32_t port, uchar controller, unsigned int lowspeed); -int usb_bulk_transfer( uchar devnum, uchar ep, unsigned int len, uchar *data); -int usb_control_msg( uchar devnum, uchar request_type, uchar request, unsigned short wValue, unsigned short wIndex, - unsigned short wLength, void *data); - -int usb_control_msg_x(struct usbdev *dev, unsigned int pipe, u8 request, u8 requesttype, - u16 value, u16 index, void *data, u16 size, int timeout, usb_complete_t complete); -int usb_bulk_msg_x(struct usbdev *usb_dev, unsigned int pipe, - void *data, int len, int *actual_length, int timeout, usb_complete_t complete); - -#endif diff --git a/src/filo/usb/usb_scsi_low.c b/src/filo/usb/usb_scsi_low.c deleted file mode 100644 index 20afecae5..000000000 --- a/src/filo/usb/usb_scsi_low.c +++ /dev/null @@ -1,172 +0,0 @@ -#ifdef USB_DISK -/******************************************************************************* - * - * - * Copyright 2003 Steven James <pyro@linuxlabs.com> and - * LinuxLabs http://www.linuxlabs.com - * - * 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 <etherboot.h> -#include <pci.h> -#include <timer.h> -#include <lib.h> - -#define DEBUG_THIS DEBUG_USB -#include <debug.h> - -#define DPRINTF debug - -#define uchar uint8_t - -//#include "debug_x.h" -#include "usb_scsi_low.h" - -int usb_bulk_transfer( uchar devnum, uchar ep, unsigned int len, uchar *data); - -#define SG_DXFER_FROM_DEV -3 -#define SG_DXFER_TO_DEV -2 - -#define REQUEST_SENSE 0x03 - -#define CBW_SIG 0x43425355 - -typedef struct usb_cbw { - unsigned int signature; - unsigned int tag; - unsigned int transfer_len; // this is exclusive of cbw and csw - - uchar res1:7; - uchar direction:1; // 1 = device to host (read) - - uchar lun:4; - uchar res:4; - - uchar cbw_len:5; // the length of the SCSI command - uchar res3:3; - - uchar scsi_cmd[16]; -} __attribute__ ((packed)) usb_cbw_t; - -#define CSW_SIG 0x53425355 - -typedef struct usb_csw { - unsigned int signature; - unsigned int tag; - unsigned int residue; - uchar status; -} __attribute__ ((packed)) usb_csw_t; - - -int scsi_command( uchar device, unsigned char *cmd, int cmd_len, int direction, unsigned char *data, int data_len, char *sense_data, int sense_len) -{ - usb_cbw_t cbw; - usb_csw_t csw; - int ret; - - memset(&cbw,0,sizeof(usb_cbw_t)); - memset(&csw,0,sizeof(usb_csw_t)); - - cbw.signature = CBW_SIG; - cbw.tag = 777; - - memcpy(cbw.scsi_cmd, cmd, cmd_len); - cbw.cbw_len = cmd_len; - - if(direction == SG_DXFER_FROM_DEV) - cbw.direction=1; - - cbw.transfer_len = data_len; - - ret = usb_bulk_transfer(device, 2, sizeof(cbw), (uchar *) &cbw); - if(ret<0){ - DPRINTF("ERROR:Bulk write:\n"); - } - - if(data_len) { - if(cbw.direction) { - DPRINTF("scsi_command reading %d bytes\n", data_len); - ret = usb_bulk_transfer(device, 0x81, data_len, data); - DPRINTF("scsi_command read %d bytes\n", ret); - if(ret<0 || ret <data_len) { - DPRINTF("ERROR:Bulk read data ret = %d\n", ret); - } - } else { -// DPRINTF("scsi_command writing %u bytes\n", data_len); - ret = usb_bulk_transfer(device, 0x2, data_len, data); -// DPRINTF("scsi_command wrote %u bytes\n", ret); - if(ret<0) { - DPRINTF("ERROR:Bulk write data\n"); - } - } - } - -// DPRINTF("scsi_command fetching csw\n"); - ret = usb_bulk_transfer(device, 0x81, sizeof(csw), (uchar *) &csw); -// DPRINTF("scsi_command csw is %d bytes\n", ret); - if(ret<0 || ret < sizeof(csw)) { - DPRINTF("ERROR: Bulk read CSW ret = %d\n", ret); - return(-1); - } - - if(csw.status) { - DPRINTF("CSW: residue = %08x, status = %02x\n", csw.residue, csw.status); - DPRINTF("Getting sense data\n"); - request_sense( device, sense_data, sense_len); - return(-csw.status); - } - - return(data_len - csw.residue); -} - -int request_sense( uchar device, char *sense_data, int len) -{ - usb_cbw_t cbw; - usb_csw_t csw; - int ret; - - memset(&cbw,0,sizeof(usb_cbw_t)); - memset(&csw,0,sizeof(usb_csw_t)); - - cbw.signature = CBW_SIG; - cbw.tag = 666; - - cbw.scsi_cmd[0] = REQUEST_SENSE; - cbw.scsi_cmd[4] = len; - cbw.cbw_len = 6; - cbw.direction=1; - cbw.transfer_len = len; - - ret = usb_bulk_transfer(device, 2, sizeof(usb_cbw_t), (uchar *) &cbw); - if(ret<0 || ret < sizeof(usb_cbw_t)) { - DPRINTF("ERROR: sense Bulk write ret = %d\n", ret); - } - - ret = usb_bulk_transfer(device, 0x81, len, sense_data); - if(ret<0 || ret < len) { - DPRINTF("ERROR: sense Bulk read data ret = %d\n", ret); - } - - ret = usb_bulk_transfer(device, 0x81, sizeof(usb_csw_t), (uchar *) &csw); - if(ret<0 || ret < sizeof(usb_csw_t)) { - DPRINTF("ERROR: sense Bulk read CSW ret = %d\n", ret); - } - - return(-csw.status); -} - -#endif diff --git a/src/filo/usb/usb_scsi_low.h b/src/filo/usb/usb_scsi_low.h deleted file mode 100644 index 773614e43..000000000 --- a/src/filo/usb/usb_scsi_low.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _USB_SCSI_LOW_H -#define _USB_SCSI_LOW_H - -#define SG_DXFER_FROM_DEV -3 -#define SG_DXFER_TO_DEV -2 - -int scsi_command( unsigned char device, unsigned char *cmd, int cmd_len, int direction, unsigned char *data, int data_len, char *sense_data, int sense_len); -int request_sense( unsigned char device, char *sense_data, int len); - -#endif diff --git a/src/filo/usb/usb_x.c b/src/filo/usb/usb_x.c deleted file mode 100644 index 3da02d81f..000000000 --- a/src/filo/usb/usb_x.c +++ /dev/null @@ -1,163 +0,0 @@ -#ifdef USB_DISK -/******************************************************************************* - * - * - * Copyright 2003 Steven James <pyro@linuxlabs.com> and - * LinuxLabs http://www.linuxlabs.com - * - * 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 <etherboot.h> -#include <pci.h> -#include <timer.h> -#include <lib.h> - -#define DEBUG_THIS DEBUG_USB -#include <debug.h> - -#define DPRINTF debug - -#include "usb.h" -#include "scsi_cmds.h" - -struct usbdisk_info_t { - struct controller *ctrl; - uint16_t heads; - uint16_t cylinders; - uint16_t sectors_per_track; - uint8_t model_number[41]; - uint8_t slave; - sector_t sectors; - int address_mode; -#define ADDRESS_MODE_CHS 0 -#define ADDRESS_MODE_LBA 1 -#define ADDRESS_MODE_LBA48 2 -#define ADDRESS_MODE_PACKET 3 - uint32_t hw_sector_size; - unsigned drive_exists : 1; - unsigned slave_absent : 1; - unsigned removable : 1; - - unsigned char usb_device_address; -}; - -struct usbdisk_info_t usbdisk_info; - -#define TEST 0 - -#if TEST==1 -#include "usb_scsi_low.h" -typedef struct partition_entry { - uchar boot_flag; - - uchar chs[7]; - - unsigned int lba_start; - unsigned int lba_len; -} __attribute__ ((packed)) partition_entry_t; - -typedef struct partition { - char loader[446]; - partition_entry_t entry[4]; - char sig[2]; -} __attribute__ ((packed)) partition_t; -#endif - -int usb_probe(int drive) -{ - struct usbdisk_info_t *info = &usbdisk_info; -#if TEST==1 - partition_t part; - unsigned char sense_data[32]; -#endif - int i,res; - int error_count=100; - - printf("LinuxLabs USB bootloader\n"); - -// outb( 0x30, 0x70); // reset primary boot -// outb( 0xff, 0x71); - init_devices(); - hci_init(); - - info->usb_device_address = 0; - // find first usb device - - while(error_count && (res = poll_usb())) // keep polling usb until no more devices are enumerated - if(res<0) - if(!--error_count) - printf("There is a USB device, but it won't init! This is a bad thing.\n"); - - for(i=0; i< next_usb_dev ; i++) { - if(usb_device[i].class == 0x08 && usb_device[i].subclass == 0x06 && usb_device[i].protocol == 0x50) { - printf("Found USB block device %d\n", i); - if(drive==0) { - info->usb_device_address = i; - break; - } - drive--; - } - } - - if(info->usb_device_address == 0) return -1; - - UnitReady(info->usb_device_address); - -#if TEST==1 -//Test - printf("Requesting initial sense data\n"); - request_sense( info->usb_device_address, sense_data, 32); - PrintSense(sense_data, 32); - - res = ll_read_block(info->usb_device_address, (uint8_t *)&part, 0, 1); - - printf("ll_read_block returns %d\n", res); - - res=-1; - - debug("part address (phy) = %x, (virt) = %x\n", (uint32_t) virt_to_phys(&part), (uint32_t)&part); - - for(i=0; i<4; i++) { - printf("%d: boot=%02x, start=%08x length=%08x\n",i, part.entry[i].boot_flag, part.entry[i].lba_start, part.entry[i] -.lba_len); - } - - -#endif - - return 0; -} -int usb_read(int drive, sector_t sector, void *buffer) -{ - struct usbdisk_info_t *info = &usbdisk_info; - int result; - int blocknum = sector; - int i; -// printf("sector= %d\t", blocknum); - result = ll_read_block(info->usb_device_address, buffer,blocknum, 1); -#if 0 - for(i=0;i<128;i++) { - if((i%4)==0) printf("\n %08x:",i*4); - printf(" %08x ",(uint32_t)*((uint32_t *)buffer+i)); - } -#endif - - if(result!=512) return -1; - - return 0; -} -#endif |
