implemented pci_hook_interrupt()
formatted USB sources
This commit is contained in:
@@ -270,3 +270,4 @@ tos/Makefile
|
|||||||
usb/usb_hub.c
|
usb/usb_hub.c
|
||||||
include/usb_hub.h
|
include/usb_hub.h
|
||||||
tos/Makefile
|
tos/Makefile
|
||||||
|
usb/usb_kbd.c
|
||||||
|
|||||||
1
Makefile
1
Makefile
@@ -97,6 +97,7 @@ CSRCS= \
|
|||||||
ehci-hcd.c \
|
ehci-hcd.c \
|
||||||
usb_hub.c \
|
usb_hub.c \
|
||||||
usb_mouse.c \
|
usb_mouse.c \
|
||||||
|
usb_kbd.c \
|
||||||
ikbd.c \
|
ikbd.c \
|
||||||
\
|
\
|
||||||
nbuf.c \
|
nbuf.c \
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ SECTIONS
|
|||||||
OBJDIR/driver_mem.o(.text)
|
OBJDIR/driver_mem.o(.text)
|
||||||
OBJDIR/usb_hub.o(.text)
|
OBJDIR/usb_hub.o(.text)
|
||||||
OBJDIR/usb_mouse.o(.text)
|
OBJDIR/usb_mouse.o(.text)
|
||||||
|
OBJDIR/usb_kbd.o(.text)
|
||||||
OBJDIR/ohci-hcd.o(.text)
|
OBJDIR/ohci-hcd.o(.text)
|
||||||
OBJDIR/ehci-hcd.o(.text)
|
OBJDIR/ehci-hcd.o(.text)
|
||||||
OBJDIR/wait.o(.text)
|
OBJDIR/wait.o(.text)
|
||||||
|
|||||||
@@ -3,10 +3,14 @@
|
|||||||
|
|
||||||
#define PCI_ANY_ID (~0)
|
#define PCI_ANY_ID (~0)
|
||||||
|
|
||||||
struct pci_device_id {
|
struct pci_device_id
|
||||||
unsigned long vendor, device; /* Vendor and device ID or PCI_ANY_ID*/
|
{
|
||||||
unsigned long subvendor, subdevice; /* Subsystem ID's or PCI_ANY_ID */
|
unsigned long vendor; /* Vendor and device ID or PCI_ANY_ID*/
|
||||||
unsigned long class, class_mask; /* (class,subclass,prog-if) triplet */
|
unsigned long device;
|
||||||
|
unsigned long subvendor; /* Subsystem ID's or PCI_ANY_ID */
|
||||||
|
unsigned long subdevice;
|
||||||
|
unsigned long class; /* (class,subclass,prog-if) triplet */
|
||||||
|
unsigned long class_mask;
|
||||||
unsigned long driver_data; /* Data private to the driver */
|
unsigned long driver_data; /* Data private to the driver */
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -15,7 +19,8 @@ struct pci_device_id {
|
|||||||
#define IEEE1394_MATCH_SPECIFIER_ID 0x0004
|
#define IEEE1394_MATCH_SPECIFIER_ID 0x0004
|
||||||
#define IEEE1394_MATCH_VERSION 0x0008
|
#define IEEE1394_MATCH_VERSION 0x0008
|
||||||
|
|
||||||
struct ieee1394_device_id {
|
struct ieee1394_device_id
|
||||||
|
{
|
||||||
unsigned long match_flags;
|
unsigned long match_flags;
|
||||||
unsigned long vendor_id;
|
unsigned long vendor_id;
|
||||||
unsigned long model_id;
|
unsigned long model_id;
|
||||||
@@ -81,7 +86,8 @@ struct ieee1394_device_id {
|
|||||||
* matches towards the beginning of your table, so that driver_info can
|
* matches towards the beginning of your table, so that driver_info can
|
||||||
* record quirks of specific products.
|
* record quirks of specific products.
|
||||||
*/
|
*/
|
||||||
struct usb_device_id {
|
struct usb_device_id
|
||||||
|
{
|
||||||
/* which fields to match against? */
|
/* which fields to match against? */
|
||||||
unsigned short match_flags;
|
unsigned short match_flags;
|
||||||
|
|
||||||
@@ -118,7 +124,8 @@ struct usb_device_id {
|
|||||||
#define USB_DEVICE_ID_MATCH_INT_PROTOCOL 0x0200
|
#define USB_DEVICE_ID_MATCH_INT_PROTOCOL 0x0200
|
||||||
|
|
||||||
/* s390 CCW devices */
|
/* s390 CCW devices */
|
||||||
struct ccw_device_id {
|
struct ccw_device_id
|
||||||
|
{
|
||||||
unsigned short match_flags; /* which fields to match against */
|
unsigned short match_flags; /* which fields to match against */
|
||||||
|
|
||||||
unsigned short cu_type; /* control unit type */
|
unsigned short cu_type; /* control unit type */
|
||||||
@@ -138,15 +145,18 @@ struct ccw_device_id {
|
|||||||
#define PNP_ID_LEN 8
|
#define PNP_ID_LEN 8
|
||||||
#define PNP_MAX_DEVICES 8
|
#define PNP_MAX_DEVICES 8
|
||||||
|
|
||||||
struct pnp_device_id {
|
struct pnp_device_id
|
||||||
|
{
|
||||||
unsigned char id[PNP_ID_LEN];
|
unsigned char id[PNP_ID_LEN];
|
||||||
unsigned long driver_data;
|
unsigned long driver_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pnp_card_device_id {
|
struct pnp_card_device_id
|
||||||
|
{
|
||||||
unsigned char id[PNP_ID_LEN];
|
unsigned char id[PNP_ID_LEN];
|
||||||
unsigned long driver_data;
|
unsigned long driver_data;
|
||||||
struct {
|
struct
|
||||||
|
{
|
||||||
unsigned char id[PNP_ID_LEN];
|
unsigned char id[PNP_ID_LEN];
|
||||||
} devs[PNP_MAX_DEVICES];
|
} devs[PNP_MAX_DEVICES];
|
||||||
};
|
};
|
||||||
@@ -154,7 +164,8 @@ struct pnp_card_device_id {
|
|||||||
|
|
||||||
#define SERIO_ANY 0xff
|
#define SERIO_ANY 0xff
|
||||||
|
|
||||||
struct serio_device_id {
|
struct serio_device_id
|
||||||
|
{
|
||||||
unsigned char type;
|
unsigned char type;
|
||||||
unsigned char extra;
|
unsigned char extra;
|
||||||
unsigned char id;
|
unsigned char id;
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ static int cc_to_error[16] =
|
|||||||
/* Not Access */ -1
|
/* Not Access */ -1
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef DEBUG_OHCI
|
|
||||||
static const char *cc_to_string[16] =
|
static const char *cc_to_string[16] =
|
||||||
{
|
{
|
||||||
"No Error",
|
"No Error",
|
||||||
@@ -64,7 +63,6 @@ static const char *cc_to_string[16] =
|
|||||||
"NOT ACCESSED:\r\nThis code is set by software before the TD is placed\r\n" \
|
"NOT ACCESSED:\r\nThis code is set by software before the TD is placed\r\n" \
|
||||||
"on a list to be processed by the HC.(2)",
|
"on a list to be processed by the HC.(2)",
|
||||||
};
|
};
|
||||||
#endif /* DEBUG_OHCI */
|
|
||||||
|
|
||||||
/* ED States */
|
/* ED States */
|
||||||
|
|
||||||
|
|||||||
@@ -91,9 +91,12 @@
|
|||||||
#define PCICSR_STEPPING (1 << 7) /* if set: stepping enabled */
|
#define PCICSR_STEPPING (1 << 7) /* if set: stepping enabled */
|
||||||
#define PCICSR_SERR (1 << 8) /* if set: SERR pin enabled */
|
#define PCICSR_SERR (1 << 8) /* if set: SERR pin enabled */
|
||||||
#define PCICSR_FAST_BTOB_E (1 << 9) /* if set: fast back-to-back enabled */
|
#define PCICSR_FAST_BTOB_E (1 << 9) /* if set: fast back-to-back enabled */
|
||||||
|
#define PCICSR_INT_DISABLE (1 << 10) /* if set: disable interrupts from this device */
|
||||||
/*
|
/*
|
||||||
* bit definitions for PCICSR upper half (Status Register)
|
* bit definitions for PCICSR upper half (Status Register)
|
||||||
*/
|
*/
|
||||||
|
#define PCICSR_INTERRUPT (1 << 3) /* device requested interrupt */
|
||||||
|
#define PCICSR_CAPABILITIES (1 << 4) /* if set, capabilities pointer is valid */
|
||||||
#define PCICSR_66MHZ (1 << 5) /* 66 MHz capable */
|
#define PCICSR_66MHZ (1 << 5) /* 66 MHz capable */
|
||||||
#define PCICSR_UDF (1 << 6) /* UDF supported */
|
#define PCICSR_UDF (1 << 6) /* UDF supported */
|
||||||
#define PCICSR_FAST_BTOB (1 << 7) /* Fast back-to-back enabled */
|
#define PCICSR_FAST_BTOB (1 << 7) /* Fast back-to-back enabled */
|
||||||
@@ -243,7 +246,9 @@ extern int32_t pci_write_config_longword(int32_t handle, int offset, uint32_t va
|
|||||||
extern int32_t pci_write_config_word(int32_t handle, int offset, uint16_t value);
|
extern int32_t pci_write_config_word(int32_t handle, int offset, uint16_t value);
|
||||||
extern int32_t pci_write_config_byte(int32_t handle, int offset, uint8_t value);
|
extern int32_t pci_write_config_byte(int32_t handle, int offset, uint8_t value);
|
||||||
|
|
||||||
extern int32_t pci_hook_interrupt(int32_t handle, void *interrupt_handler, void *parameter);
|
typedef int (*pci_interrupt_handler)(int param);
|
||||||
|
|
||||||
|
extern int32_t pci_hook_interrupt(int32_t handle, pci_interrupt_handler handler, void *parameter);
|
||||||
extern int32_t pci_unhook_interrupt(int32_t handle);
|
extern int32_t pci_unhook_interrupt(int32_t handle);
|
||||||
|
|
||||||
extern struct pci_rd *pci_get_resource(int32_t handle);
|
extern struct pci_rd *pci_get_resource(int32_t handle);
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ extern int sprintD(char *s, const char *fmt, ...);
|
|||||||
#define USB_MAXCHILDREN 8 /* This is arbitrary */
|
#define USB_MAXCHILDREN 8 /* This is arbitrary */
|
||||||
#define USB_MAX_HUB 16
|
#define USB_MAX_HUB 16
|
||||||
|
|
||||||
#define USB_CNTL_TIMEOUT 100 /* 100ms timeout */
|
#define USB_CNTL_TIMEOUT 100 /* 100 ms timeout */
|
||||||
|
|
||||||
#define USB_BUFSIZ 512
|
#define USB_BUFSIZ 512
|
||||||
|
|
||||||
@@ -180,8 +180,10 @@ struct usb_device
|
|||||||
|
|
||||||
/* Maximum packet size; one of: PACKET_SIZE_* */
|
/* Maximum packet size; one of: PACKET_SIZE_* */
|
||||||
int maxpacketsize;
|
int maxpacketsize;
|
||||||
|
|
||||||
/* one bit for each endpoint ([0] = IN, [1] = OUT) */
|
/* one bit for each endpoint ([0] = IN, [1] = OUT) */
|
||||||
unsigned int toggle[2];
|
unsigned int toggle[2];
|
||||||
|
|
||||||
/* endpoint halts; one bit per endpoint # & direction;
|
/* endpoint halts; one bit per endpoint # & direction;
|
||||||
* [0] = IN, [1] = OUT
|
* [0] = IN, [1] = OUT
|
||||||
*/
|
*/
|
||||||
@@ -199,6 +201,7 @@ struct usb_device
|
|||||||
uint32_t irq_status;
|
uint32_t irq_status;
|
||||||
int irq_act_len; /* transfered bytes */
|
int irq_act_len; /* transfered bytes */
|
||||||
void *privptr;
|
void *privptr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Child devices - if this is a hub device
|
* Child devices - if this is a hub device
|
||||||
* Each instance needs its own set of data structures.
|
* Each instance needs its own set of data structures.
|
||||||
@@ -227,7 +230,7 @@ typedef struct
|
|||||||
} v;
|
} v;
|
||||||
} USB_COOKIE;
|
} USB_COOKIE;
|
||||||
|
|
||||||
/**********************************************************************
|
/*
|
||||||
* this is how the lowlevel part communicate with the outer world
|
* this is how the lowlevel part communicate with the outer world
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -322,8 +325,9 @@ extern int usb_set_interface(struct usb_device *dev, int interface, int alternat
|
|||||||
* specification, so that much of the uhci driver can just mask the bits
|
* specification, so that much of the uhci driver can just mask the bits
|
||||||
* appropriately.
|
* appropriately.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Create various pipes... */
|
/* Create various pipes... */
|
||||||
#define create_pipe(dev,endpoint) \
|
#define create_pipe(dev, endpoint) \
|
||||||
(((dev)->devnum << 8) | (endpoint << 15) | \
|
(((dev)->devnum << 8) | (endpoint << 15) | \
|
||||||
((dev)->speed << 26) | (dev)->maxpacketsize)
|
((dev)->speed << 26) | (dev)->maxpacketsize)
|
||||||
#define default_pipe(dev) ((dev)->speed << 26)
|
#define default_pipe(dev) ((dev)->speed << 26)
|
||||||
|
|||||||
213
pci/ohci-hcd.c
213
pci/ohci-hcd.c
@@ -48,12 +48,9 @@
|
|||||||
#include "bas_string.h" /* for memset() */
|
#include "bas_string.h" /* for memset() */
|
||||||
#include "pci.h"
|
#include "pci.h"
|
||||||
|
|
||||||
//extern xQueueHandle queue_poll_hub;
|
|
||||||
|
|
||||||
#undef OHCI_USE_NPS /* force NoPowerSwitching mode */
|
#undef OHCI_USE_NPS /* force NoPowerSwitching mode */
|
||||||
|
|
||||||
#undef OHCI_VERBOSE_DEBUG /* not always helpful */
|
#undef OHCI_VERBOSE_DEBUG /* not always helpful */
|
||||||
#undef SHOW_INFO
|
|
||||||
#undef OHCI_FILL_TRACE
|
#undef OHCI_FILL_TRACE
|
||||||
|
|
||||||
//#define DEBUG_OHCI
|
//#define DEBUG_OHCI
|
||||||
@@ -62,6 +59,7 @@
|
|||||||
#else
|
#else
|
||||||
#define dbg(format, arg...) do { ; } while (0)
|
#define dbg(format, arg...) do { ; } while (0)
|
||||||
#endif /* DEBUG_OHCI */
|
#endif /* DEBUG_OHCI */
|
||||||
|
#define err(format, arg...) do { xprintf("DEBUG: %s(): " format, __FUNCTION__, ##arg); } while (0)
|
||||||
|
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
#include "ohci.h"
|
#include "ohci.h"
|
||||||
@@ -149,9 +147,6 @@ struct pci_device_id ohci_usb_pci_table[] =
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#define err(format, arg...) do { dbg("ERROR: " format "\r\n", ## arg); } while (0)
|
|
||||||
#define info(format, arg...) dbg("INFO: " format "\r\n", ## arg)
|
|
||||||
|
|
||||||
/* global ohci_t */
|
/* global ohci_t */
|
||||||
static ohci_t gohci[2];
|
static ohci_t gohci[2];
|
||||||
int ohci_inited;
|
int ohci_inited;
|
||||||
@@ -1080,8 +1075,10 @@ static void check_status(ohci_t *ohci, td_t *td_list)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* replies to the request have to be on a FIFO basis so
|
/*
|
||||||
* we reverse the reversed done-list */
|
* replies to the request have to be on a FIFO basis so
|
||||||
|
* we reverse the reversed done-list
|
||||||
|
*/
|
||||||
static td_t *dl_reverse_done_list(ohci_t *ohci)
|
static td_t *dl_reverse_done_list(ohci_t *ohci)
|
||||||
{
|
{
|
||||||
uint32_t td_list_hc;
|
uint32_t td_list_hc;
|
||||||
@@ -1089,19 +1086,25 @@ static td_t *dl_reverse_done_list(ohci_t *ohci)
|
|||||||
td_t *td_list = NULL;
|
td_t *td_list = NULL;
|
||||||
|
|
||||||
td_list_hc = swpl(ohci->hcca->done_head) & ~0xf;
|
td_list_hc = swpl(ohci->hcca->done_head) & ~0xf;
|
||||||
|
|
||||||
if (td_list_hc)
|
if (td_list_hc)
|
||||||
|
{
|
||||||
td_list_hc += ohci->dma_offset;
|
td_list_hc += ohci->dma_offset;
|
||||||
|
}
|
||||||
|
|
||||||
ohci->hcca->done_head = 0;
|
ohci->hcca->done_head = 0;
|
||||||
while (td_list_hc)
|
while (td_list_hc)
|
||||||
{
|
{
|
||||||
td_list = (td_t *)td_list_hc;
|
td_list = (td_t *) td_list_hc;
|
||||||
check_status(ohci, td_list);
|
check_status(ohci, td_list);
|
||||||
td_list->next_dl_td = td_rev;
|
td_list->next_dl_td = td_rev;
|
||||||
td_rev = td_list;
|
td_rev = td_list;
|
||||||
td_list_hc = swpl(td_list->hwNextTD) & ~0xf;
|
td_list_hc = swpl(td_list->hwNextTD) & ~0xf;
|
||||||
if (td_list_hc)
|
if (td_list_hc)
|
||||||
|
{
|
||||||
td_list_hc += ohci->dma_offset;
|
td_list_hc += ohci->dma_offset;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return td_list;
|
return td_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1110,9 +1113,13 @@ static td_t *dl_reverse_done_list(ohci_t *ohci)
|
|||||||
static void finish_urb(ohci_t *ohci, urb_priv_t *urb, int status)
|
static void finish_urb(ohci_t *ohci, urb_priv_t *urb, int status)
|
||||||
{
|
{
|
||||||
if ((status & (ED_OPER | ED_UNLINK)) && (urb->state != URB_DEL))
|
if ((status & (ED_OPER | ED_UNLINK)) && (urb->state != URB_DEL))
|
||||||
|
{
|
||||||
urb->finished = sohci_return_job(ohci, urb);
|
urb->finished = sohci_return_job(ohci, urb);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
dbg("finish_urb: strange.., ED state %x, \r\n", status);
|
dbg("finish_urb: strange.., ED state %x, \r\n", status);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1126,16 +1133,21 @@ static int takeback_td(ohci_t *ohci, td_t *td_list)
|
|||||||
ed_t *ed;
|
ed_t *ed;
|
||||||
int cc;
|
int cc;
|
||||||
int stat = 0;
|
int stat = 0;
|
||||||
/* urb_t *urb; */
|
|
||||||
urb_priv_t *lurb_priv;
|
urb_priv_t *lurb_priv;
|
||||||
uint32_t tdINFO, edHeadP, edTailP;
|
uint32_t tdINFO;
|
||||||
|
uint32_t edHeadP;
|
||||||
|
uint32_t edTailP;
|
||||||
|
|
||||||
tdINFO = swpl(td_list->hwINFO);
|
tdINFO = swpl(td_list->hwINFO);
|
||||||
|
|
||||||
ed = td_list->ed;
|
ed = td_list->ed;
|
||||||
if (ed == NULL)
|
if (ed == NULL)
|
||||||
{
|
{
|
||||||
err("OHCI usb-%s-%c cannot get error code ED is null", ohci->slot_name, (char)ohci->controller + '0');
|
err("OHCI usb-%s-%c cannot get error code ED is null\r\n", ohci->slot_name, (char) ohci->controller + '0');
|
||||||
|
|
||||||
return stat;
|
return stat;
|
||||||
}
|
}
|
||||||
|
|
||||||
lurb_priv = ed->purb;
|
lurb_priv = ed->purb;
|
||||||
dl_transfer_length(ohci, td_list);
|
dl_transfer_length(ohci, td_list);
|
||||||
lurb_priv->td_cnt++;
|
lurb_priv->td_cnt++;
|
||||||
@@ -1144,26 +1156,40 @@ static int takeback_td(ohci_t *ohci, td_t *td_list)
|
|||||||
cc = TD_CC_GET(tdINFO);
|
cc = TD_CC_GET(tdINFO);
|
||||||
if (cc)
|
if (cc)
|
||||||
{
|
{
|
||||||
//err("OHCI usb-%s-%c error: %s (%x)", ohci->slot_name, (char)ohci->controller + '0', cc_to_string[cc], cc);
|
err("OHCI usb-%s-%c error: %s (%x)\r\n", ohci->slot_name, (char) ohci->controller + '0', cc_to_string[cc], cc);
|
||||||
stat = cc_to_error[cc];
|
stat = cc_to_error[cc];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* see if this done list makes for all TD's of current URB,
|
/*
|
||||||
* and mark the URB finished if so */
|
* see if this done list makes for all TD's of current URB,
|
||||||
|
* and mark the URB finished if so
|
||||||
|
*/
|
||||||
if (lurb_priv->td_cnt == lurb_priv->length)
|
if (lurb_priv->td_cnt == lurb_priv->length)
|
||||||
|
{
|
||||||
finish_urb(ohci, lurb_priv, ed->state);
|
finish_urb(ohci, lurb_priv, ed->state);
|
||||||
|
}
|
||||||
|
|
||||||
if (ohci->irq)
|
if (ohci->irq)
|
||||||
dbg("dl_done_list: processing TD %x, len %x", lurb_priv->td_cnt, lurb_priv->length);
|
{
|
||||||
|
dbg("dl_done_list: processing TD %x, len %x\r\n", lurb_priv->td_cnt, lurb_priv->length);
|
||||||
|
}
|
||||||
|
|
||||||
if (ed->state != ED_NEW && (!usb_pipeint(lurb_priv->pipe)))
|
if (ed->state != ED_NEW && (!usb_pipeint(lurb_priv->pipe)))
|
||||||
{
|
{
|
||||||
edHeadP = swpl(ed->hwHeadP) & ~0xf;
|
edHeadP = swpl(ed->hwHeadP) & ~0xf;
|
||||||
edTailP = swpl(ed->hwTailP);
|
edTailP = swpl(ed->hwTailP);
|
||||||
|
|
||||||
/* unlink eds if they are not busy */
|
/* unlink eds if they are not busy */
|
||||||
if ((edHeadP == edTailP) && (ed->state == ED_OPER))
|
if ((edHeadP == edTailP) && (ed->state == ED_OPER))
|
||||||
|
{
|
||||||
ep_unlink(ohci, ed);
|
ep_unlink(ohci, ed);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (cc && (ed->type == PIPE_INTERRUPT)) /* added, but it's not the better method */
|
if (cc && (ed->type == PIPE_INTERRUPT)) /* added, but it's not the better method */
|
||||||
|
{
|
||||||
ep_unlink(ohci, ed);
|
ep_unlink(ohci, ed);
|
||||||
|
}
|
||||||
return stat;
|
return stat;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1171,9 +1197,11 @@ static int dl_done_list(ohci_t *ohci)
|
|||||||
{
|
{
|
||||||
int stat = 0;
|
int stat = 0;
|
||||||
td_t *td_list = dl_reverse_done_list(ohci);
|
td_t *td_list = dl_reverse_done_list(ohci);
|
||||||
|
|
||||||
while (td_list)
|
while (td_list)
|
||||||
{
|
{
|
||||||
td_t *td_next = td_list->next_dl_td;
|
td_t *td_next = td_list->next_dl_td;
|
||||||
|
|
||||||
stat = takeback_td(ohci, td_list);
|
stat = takeback_td(ohci, td_list);
|
||||||
td_list = td_next;
|
td_list = td_next;
|
||||||
}
|
}
|
||||||
@@ -1289,10 +1317,10 @@ static unsigned char root_hub_str_index1[] =
|
|||||||
#define OK(x) len = (x); break
|
#define OK(x) len = (x); break
|
||||||
#ifdef DEBUG_OHCI
|
#ifdef DEBUG_OHCI
|
||||||
#define WR_RH_STAT(x) { info("WR:status %#8x", (x)); writel((x), &ohci->regs->roothub.status); }
|
#define WR_RH_STAT(x) { info("WR:status %#8x", (x)); writel((x), &ohci->regs->roothub.status); }
|
||||||
#define WR_RH_PORTSTAT(x) { info("WR:portstatus[%d] %#8x", wIndex-1, (x)); writel((x), &ohci->regs->roothub.portstatus[wIndex-1]); }
|
#define WR_RH_PORTSTAT(x) { info("WR:portstatus[%d] %#8x", wIndex - 1, (x)); writel((x), &ohci->regs->roothub.portstatus[wIndex - 1]); }
|
||||||
#else
|
#else
|
||||||
#define WR_RH_STAT(x) { writel((x), &ohci->regs->roothub.status); }
|
#define WR_RH_STAT(x) { writel((x), &ohci->regs->roothub.status); }
|
||||||
#define WR_RH_PORTSTAT(x) { writel((x), &ohci->regs->roothub.portstatus[wIndex-1]); }
|
#define WR_RH_PORTSTAT(x) { writel((x), &ohci->regs->roothub.portstatus[wIndex - 1]); }
|
||||||
#endif
|
#endif
|
||||||
#define RD_RH_STAT roothub_status(ohci)
|
#define RD_RH_STAT roothub_status(ohci)
|
||||||
#define RD_RH_PORTSTAT roothub_portstatus(ohci, wIndex-1)
|
#define RD_RH_PORTSTAT roothub_portstatus(ohci, wIndex-1)
|
||||||
@@ -1309,12 +1337,14 @@ int rh_check_port_status(ohci_t *controller)
|
|||||||
for (i = 0; i < ndp; i++)
|
for (i = 0; i < ndp; i++)
|
||||||
{
|
{
|
||||||
temp = roothub_portstatus(controller, i);
|
temp = roothub_portstatus(controller, i);
|
||||||
|
|
||||||
/* check for a device disconnect */
|
/* check for a device disconnect */
|
||||||
if (((temp & (RH_PS_PESC | RH_PS_CSC)) == (RH_PS_PESC | RH_PS_CSC)) && ((temp & RH_PS_CCS) == 0))
|
if (((temp & (RH_PS_PESC | RH_PS_CSC)) == (RH_PS_PESC | RH_PS_CSC)) && ((temp & RH_PS_CCS) == 0))
|
||||||
{
|
{
|
||||||
res = i;
|
res = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check for a device connect */
|
/* check for a device connect */
|
||||||
if ((temp & RH_PS_CSC) && (temp & RH_PS_CCS))
|
if ((temp & RH_PS_CSC) && (temp & RH_PS_CCS))
|
||||||
{
|
{
|
||||||
@@ -1343,49 +1373,60 @@ static int ohci_submit_rh_msg(ohci_t *ohci, struct usb_device *dev, uint32_t pip
|
|||||||
pkt_print(ohci, NULL, dev, pipe, buffer, transfer_len, cmd, "SUB(rh)", usb_pipein(pipe));
|
pkt_print(ohci, NULL, dev, pipe, buffer, transfer_len, cmd, "SUB(rh)", usb_pipein(pipe));
|
||||||
#else
|
#else
|
||||||
if (ohci->irq)
|
if (ohci->irq)
|
||||||
|
{
|
||||||
wait(1 * 1000);
|
wait(1 * 1000);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (usb_pipeint(pipe))
|
if (usb_pipeint(pipe))
|
||||||
{
|
{
|
||||||
info("Root-Hub submit IRQ: NOT implemented");
|
err("Root-Hub submit IRQ: NOT implemented");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bmRType_bReq = cmd->requesttype | (cmd->request << 8);
|
bmRType_bReq = cmd->requesttype | (cmd->request << 8);
|
||||||
wValue = swpw(cmd->value);
|
wValue = swpw(cmd->value);
|
||||||
wIndex = swpw(cmd->index);
|
wIndex = swpw(cmd->index);
|
||||||
wLength = swpw(cmd->length);
|
wLength = swpw(cmd->length);
|
||||||
info("Root-Hub: adr: %2x cmd(%1x): %08x %04x %04x %04x", dev->devnum, 8, bmRType_bReq, wValue, wIndex, wLength);
|
dbg("Root-Hub: adr: %2x cmd(%1x): %08x %04x %04x %04x\r\n", dev->devnum, 8, bmRType_bReq, wValue, wIndex, wLength);
|
||||||
|
|
||||||
switch (bmRType_bReq)
|
switch (bmRType_bReq)
|
||||||
{
|
{
|
||||||
/* Request Destination:
|
/*
|
||||||
without flags: Device,
|
* Request Destination:
|
||||||
RH_INTERFACE: interface,
|
* without flags: Device,
|
||||||
RH_ENDPOINT: endpoint,
|
* RH_INTERFACE: interface,
|
||||||
RH_CLASS means HUB here,
|
* RH_ENDPOINT: endpoint,
|
||||||
RH_OTHER | RH_CLASS almost ever means HUB_PORT here
|
* RH_CLASS means HUB here,
|
||||||
|
* RH_OTHER | RH_CLASS almost ever means HUB_PORT here
|
||||||
*/
|
*/
|
||||||
case RH_GET_STATUS:
|
case RH_GET_STATUS:
|
||||||
*(uint16_t *)data_buf = swpw(1);
|
*(uint16_t *) data_buf = swpw(1);
|
||||||
OK(2);
|
OK(2);
|
||||||
|
|
||||||
case RH_GET_STATUS | RH_INTERFACE:
|
case RH_GET_STATUS | RH_INTERFACE:
|
||||||
*(uint16_t *)data_buf = swpw(0);
|
*(uint16_t *)data_buf = swpw(0);
|
||||||
OK(2);
|
OK(2);
|
||||||
|
|
||||||
case RH_GET_STATUS | RH_ENDPOINT:
|
case RH_GET_STATUS | RH_ENDPOINT:
|
||||||
*(uint16_t *)data_buf = swpw(0);
|
*(uint16_t *)data_buf = swpw(0);
|
||||||
OK(2);
|
OK(2);
|
||||||
|
|
||||||
case RH_GET_STATUS | RH_CLASS:
|
case RH_GET_STATUS | RH_CLASS:
|
||||||
*(uint32_t *)data_buf = swpl(RD_RH_STAT & ~(RH_HS_CRWE | RH_HS_DRWE));
|
*(uint32_t *)data_buf = swpl(RD_RH_STAT & ~(RH_HS_CRWE | RH_HS_DRWE));
|
||||||
OK(4);
|
OK(4);
|
||||||
|
|
||||||
case RH_GET_STATUS | RH_OTHER | RH_CLASS:
|
case RH_GET_STATUS | RH_OTHER | RH_CLASS:
|
||||||
*(uint32_t *)data_buf = swpl(RD_RH_PORTSTAT);
|
*(uint32_t *)data_buf = swpl(RD_RH_PORTSTAT);
|
||||||
OK(4);
|
OK(4);
|
||||||
|
|
||||||
case RH_CLEAR_FEATURE | RH_ENDPOINT:
|
case RH_CLEAR_FEATURE | RH_ENDPOINT:
|
||||||
switch (wValue)
|
switch (wValue)
|
||||||
{
|
{
|
||||||
case (RH_ENDPOINT_STALL): OK(0);
|
case (RH_ENDPOINT_STALL): OK(0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RH_CLEAR_FEATURE | RH_CLASS:
|
case RH_CLEAR_FEATURE | RH_CLASS:
|
||||||
switch (wValue)
|
switch (wValue)
|
||||||
{
|
{
|
||||||
@@ -1393,6 +1434,7 @@ static int ohci_submit_rh_msg(ohci_t *ohci, struct usb_device *dev, uint32_t pip
|
|||||||
case (RH_C_HUB_OVER_CURRENT): WR_RH_STAT(RH_HS_OCIC); OK(0);
|
case (RH_C_HUB_OVER_CURRENT): WR_RH_STAT(RH_HS_OCIC); OK(0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
|
case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
|
||||||
switch (wValue)
|
switch (wValue)
|
||||||
{
|
{
|
||||||
@@ -1406,6 +1448,7 @@ static int ohci_submit_rh_msg(ohci_t *ohci, struct usb_device *dev, uint32_t pip
|
|||||||
case (RH_C_PORT_RESET): WR_RH_PORTSTAT(RH_PS_PRSC); OK(0);
|
case (RH_C_PORT_RESET): WR_RH_PORTSTAT(RH_PS_PRSC); OK(0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
|
case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
|
||||||
switch (wValue)
|
switch (wValue)
|
||||||
{
|
{
|
||||||
@@ -1426,9 +1469,11 @@ static int ohci_submit_rh_msg(ohci_t *ohci, struct usb_device *dev, uint32_t pip
|
|||||||
OK(0);
|
OK(0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RH_SET_ADDRESS:
|
case RH_SET_ADDRESS:
|
||||||
ohci->rh.devnum = wValue;
|
ohci->rh.devnum = wValue;
|
||||||
OK(0);
|
OK(0);
|
||||||
|
|
||||||
case RH_GET_DESCRIPTOR:
|
case RH_GET_DESCRIPTOR:
|
||||||
switch ((wValue & 0xff00) >> 8)
|
switch ((wValue & 0xff00) >> 8)
|
||||||
{
|
{
|
||||||
@@ -1436,10 +1481,12 @@ static int ohci_submit_rh_msg(ohci_t *ohci, struct usb_device *dev, uint32_t pip
|
|||||||
len = min_t(unsigned int, leni, min_t(unsigned int, sizeof(root_hub_dev_des), wLength));
|
len = min_t(unsigned int, leni, min_t(unsigned int, sizeof(root_hub_dev_des), wLength));
|
||||||
data_buf = root_hub_dev_des;
|
data_buf = root_hub_dev_des;
|
||||||
OK(len);
|
OK(len);
|
||||||
|
|
||||||
case(0x02): /* configuration descriptor */
|
case(0x02): /* configuration descriptor */
|
||||||
len = min_t(unsigned int, leni, min_t(unsigned int, sizeof(root_hub_config_des), wLength));
|
len = min_t(unsigned int, leni, min_t(unsigned int, sizeof(root_hub_config_des), wLength));
|
||||||
data_buf = root_hub_config_des;
|
data_buf = root_hub_config_des;
|
||||||
OK(len);
|
OK(len);
|
||||||
|
|
||||||
case(0x03): /* string descriptors */
|
case(0x03): /* string descriptors */
|
||||||
if (wValue == 0x0300)
|
if (wValue == 0x0300)
|
||||||
{
|
{
|
||||||
@@ -1453,10 +1500,12 @@ static int ohci_submit_rh_msg(ohci_t *ohci, struct usb_device *dev, uint32_t pip
|
|||||||
data_buf = root_hub_str_index1;
|
data_buf = root_hub_str_index1;
|
||||||
OK(len);
|
OK(len);
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
stat = USB_ST_STALLED;
|
stat = USB_ST_STALLED;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RH_GET_DESCRIPTOR | RH_CLASS:
|
case RH_GET_DESCRIPTOR | RH_CLASS:
|
||||||
{
|
{
|
||||||
uint32_t temp = roothub_a(ohci);
|
uint32_t temp = roothub_a(ohci);
|
||||||
@@ -1465,30 +1514,44 @@ static int ohci_submit_rh_msg(ohci_t *ohci, struct usb_device *dev, uint32_t pip
|
|||||||
// data_buf[2] = temp & RH_A_NDP;
|
// data_buf[2] = temp & RH_A_NDP;
|
||||||
data_buf[2] = (uint8_t)ohci->ndp;
|
data_buf[2] = (uint8_t)ohci->ndp;
|
||||||
data_buf[3] = 0;
|
data_buf[3] = 0;
|
||||||
|
|
||||||
if (temp & RH_A_PSM) /* per-port power switching? */
|
if (temp & RH_A_PSM) /* per-port power switching? */
|
||||||
|
{
|
||||||
data_buf[3] |= 0x1;
|
data_buf[3] |= 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
if (temp & RH_A_NOCP) /* no overcurrent reporting? */
|
if (temp & RH_A_NOCP) /* no overcurrent reporting? */
|
||||||
|
{
|
||||||
data_buf[3] |= 0x10;
|
data_buf[3] |= 0x10;
|
||||||
|
}
|
||||||
else if (temp & RH_A_OCPM) /* per-port overcurrent reporting? */
|
else if (temp & RH_A_OCPM) /* per-port overcurrent reporting? */
|
||||||
|
{
|
||||||
data_buf[3] |= 0x8;
|
data_buf[3] |= 0x8;
|
||||||
|
}
|
||||||
|
|
||||||
/* corresponds to data_buf[4-7] */
|
/* corresponds to data_buf[4-7] */
|
||||||
datab[1] = 0;
|
datab[1] = 0;
|
||||||
data_buf[5] = (temp & RH_A_POTPGT) >> 24;
|
data_buf[5] = (temp & RH_A_POTPGT) >> 24;
|
||||||
temp = roothub_b(ohci);
|
temp = roothub_b(ohci);
|
||||||
data_buf[7] = temp & RH_B_DR;
|
data_buf[7] = temp & RH_B_DR;
|
||||||
if (data_buf[2] < 7)
|
if (data_buf[2] < 7)
|
||||||
|
{
|
||||||
data_buf[8] = 0xff;
|
data_buf[8] = 0xff;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
data_buf[0] += 2;
|
data_buf[0] += 2;
|
||||||
data_buf[8] = (temp & RH_B_DR) >> 8;
|
data_buf[8] = (temp & RH_B_DR) >> 8;
|
||||||
data_buf[10] = data_buf[9] = 0xff;
|
data_buf[10] = data_buf[9] = 0xff;
|
||||||
}
|
}
|
||||||
len = min_t(unsigned int, leni, min_t(unsigned int, data_buf [0], wLength));
|
len = min_t(unsigned int, leni, min_t(unsigned int, data_buf[0], wLength));
|
||||||
OK(len);
|
OK(len);
|
||||||
}
|
}
|
||||||
|
|
||||||
case RH_GET_CONFIGURATION: *(uint8_t *) data_buf = 0x01; OK(1);
|
case RH_GET_CONFIGURATION: *(uint8_t *) data_buf = 0x01; OK(1);
|
||||||
|
|
||||||
case RH_SET_CONFIGURATION: WR_RH_STAT(0x10000); OK(0);
|
case RH_SET_CONFIGURATION: WR_RH_STAT(0x10000); OK(0);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
dbg("unsupported root hub command");
|
dbg("unsupported root hub command");
|
||||||
stat = USB_ST_STALLED;
|
stat = USB_ST_STALLED;
|
||||||
@@ -1497,25 +1560,38 @@ static int ohci_submit_rh_msg(ohci_t *ohci, struct usb_device *dev, uint32_t pip
|
|||||||
ohci_dump_roothub(ohci, 1);
|
ohci_dump_roothub(ohci, 1);
|
||||||
#else
|
#else
|
||||||
if (ohci->irq)
|
if (ohci->irq)
|
||||||
|
{
|
||||||
wait(1 * 1000);
|
wait(1 * 1000);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
len = min_t(int, len, leni);
|
len = min_t(int, len, leni);
|
||||||
|
|
||||||
if (data != data_buf)
|
if (data != data_buf)
|
||||||
|
{
|
||||||
memcpy(data, data_buf, len);
|
memcpy(data, data_buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
dev->act_len = len;
|
dev->act_len = len;
|
||||||
dev->status = stat;
|
dev->status = stat;
|
||||||
|
|
||||||
#ifdef DEBUG_OHCI
|
#ifdef DEBUG_OHCI
|
||||||
pkt_print(ohci, NULL, dev, pipe, buffer, transfer_len, cmd, "RET(rh)", 0/*usb_pipein(pipe)*/);
|
pkt_print(ohci, NULL, dev, pipe, buffer, transfer_len, cmd, "RET(rh)", 0/*usb_pipein(pipe)*/);
|
||||||
#else
|
#else
|
||||||
|
|
||||||
if (ohci->irq)
|
if (ohci->irq)
|
||||||
|
{
|
||||||
wait(1 * 1000);
|
wait(1 * 1000);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return stat;
|
return stat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* common code for handling submit messages - used for all but root hub accesses. */
|
/*
|
||||||
|
* common code for handling submit messages - used for all but root hub accesses.
|
||||||
|
*/
|
||||||
|
|
||||||
static int submit_common_msg(ohci_t *ohci, struct usb_device *dev, uint32_t pipe, void *buffer,
|
static int submit_common_msg(ohci_t *ohci, struct usb_device *dev, uint32_t pipe, void *buffer,
|
||||||
int transfer_len, struct devrequest *setup, int interval)
|
int transfer_len, struct devrequest *setup, int interval)
|
||||||
@@ -1523,14 +1599,16 @@ static int submit_common_msg(ohci_t *ohci, struct usb_device *dev, uint32_t pipe
|
|||||||
int stat = 0;
|
int stat = 0;
|
||||||
int maxsize = usb_maxpacket(dev, pipe);
|
int maxsize = usb_maxpacket(dev, pipe);
|
||||||
int timeout;
|
int timeout;
|
||||||
urb_priv_t *urb = (urb_priv_t *) driver_mem_alloc(sizeof(urb_priv_t));
|
urb_priv_t *urb = driver_mem_alloc(sizeof(urb_priv_t));
|
||||||
|
|
||||||
if (urb == NULL)
|
if (urb == NULL)
|
||||||
{
|
{
|
||||||
err("submit_common_msg malloc failed");
|
err("submit_common_msg driver_mem_alloc() failed\r\n");
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
memset(urb, 0, sizeof(urb_priv_t));
|
memset(urb, 0, sizeof(urb_priv_t));
|
||||||
|
|
||||||
urb->dev = dev;
|
urb->dev = dev;
|
||||||
urb->pipe = pipe;
|
urb->pipe = pipe;
|
||||||
urb->transfer_buffer = buffer;
|
urb->transfer_buffer = buffer;
|
||||||
@@ -1541,6 +1619,7 @@ static int submit_common_msg(ohci_t *ohci, struct usb_device *dev, uint32_t pipe
|
|||||||
if (ohci->devgone == dev)
|
if (ohci->devgone == dev)
|
||||||
{
|
{
|
||||||
dev->status = USB_ST_CRC_ERR;
|
dev->status = USB_ST_CRC_ERR;
|
||||||
|
dbg("device is gone...\r\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_OHCI
|
#ifdef DEBUG_OHCI
|
||||||
@@ -1548,18 +1627,20 @@ static int submit_common_msg(ohci_t *ohci, struct usb_device *dev, uint32_t pipe
|
|||||||
pkt_print(ohci, urb, dev, pipe, buffer, transfer_len, setup, "SUB", usb_pipein(pipe));
|
pkt_print(ohci, urb, dev, pipe, buffer, transfer_len, setup, "SUB", usb_pipein(pipe));
|
||||||
#else
|
#else
|
||||||
if (ohci->irq)
|
if (ohci->irq)
|
||||||
|
{
|
||||||
wait(1 * 1000);
|
wait(1 * 1000);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!maxsize)
|
if (!maxsize)
|
||||||
{
|
{
|
||||||
err("submit_common_message: pipesize for pipe %lx is zero", pipe);
|
err("submit_common_message: pipesize for pipe %lx is zero\r\n", pipe);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sohci_submit_job(ohci, urb, setup) < 0)
|
if (sohci_submit_job(ohci, urb, setup) < 0)
|
||||||
{
|
{
|
||||||
err("sohci_submit_job failed");
|
err("sohci_submit_job failed\r\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1567,22 +1648,31 @@ static int submit_common_msg(ohci_t *ohci, struct usb_device *dev, uint32_t pipe
|
|||||||
wait(10 * 1000);
|
wait(10 * 1000);
|
||||||
/* ohci_dump_status(ohci); */
|
/* ohci_dump_status(ohci); */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* allow more time for a BULK device to react - some are slow */
|
/* allow more time for a BULK device to react - some are slow */
|
||||||
|
|
||||||
#define BULK_TO 5000 /* timeout in milliseconds */
|
#define BULK_TO 5000 /* timeout in milliseconds */
|
||||||
|
|
||||||
if (usb_pipebulk(pipe))
|
if (usb_pipebulk(pipe))
|
||||||
|
{
|
||||||
timeout = BULK_TO;
|
timeout = BULK_TO;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
timeout = 1000;
|
timeout = 1000;
|
||||||
|
}
|
||||||
|
|
||||||
/* wait for it to complete */
|
/* wait for it to complete */
|
||||||
while (ohci->irq)
|
while (ohci->irq)
|
||||||
{
|
{
|
||||||
/* check whether the controller is done */
|
/* check whether the controller is done */
|
||||||
flush_data_cache(ohci);
|
flush_data_cache(ohci);
|
||||||
|
|
||||||
#ifndef CONFIG_USB_INTERRUPT_POLLING
|
#ifndef CONFIG_USB_INTERRUPT_POLLING
|
||||||
if (ohci->irq_enabled)
|
if (ohci->irq_enabled)
|
||||||
|
{
|
||||||
stat = ohci->stat_irq;
|
stat = ohci->stat_irq;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
stat = hc_interrupt(ohci);
|
stat = hc_interrupt(ohci);
|
||||||
@@ -1638,7 +1728,7 @@ static int submit_common_msg(ohci_t *ohci, struct usb_device *dev, uint32_t pipe
|
|||||||
/* submit routines called from usb.c */
|
/* submit routines called from usb.c */
|
||||||
int ohci_submit_bulk_msg(struct usb_device *dev, uint32_t pipe, void *buffer, int transfer_len)
|
int ohci_submit_bulk_msg(struct usb_device *dev, uint32_t pipe, void *buffer, int transfer_len)
|
||||||
{
|
{
|
||||||
info("submit_bulk_msg dev 0x%p ohci 0x%p buffer 0x%p len %d", dev, dev->priv_hcd, buffer, transfer_len);
|
err("submit_bulk_msg dev 0x%p ohci 0x%p buffer 0x%p len %d", dev, dev->priv_hcd, buffer, transfer_len);
|
||||||
return submit_common_msg((ohci_t *)dev->priv_hcd, dev, pipe, buffer, transfer_len, NULL, 0);
|
return submit_common_msg((ohci_t *)dev->priv_hcd, dev, pipe, buffer, transfer_len, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1646,12 +1736,16 @@ int ohci_submit_control_msg(struct usb_device *dev, uint32_t pipe, void *buffer,
|
|||||||
{
|
{
|
||||||
ohci_t *ohci = (ohci_t *)dev->priv_hcd;
|
ohci_t *ohci = (ohci_t *)dev->priv_hcd;
|
||||||
int maxsize = usb_maxpacket(dev, pipe);
|
int maxsize = usb_maxpacket(dev, pipe);
|
||||||
info("submit_control_msg dev 0x%p ohci 0x%p", dev, ohci);
|
|
||||||
|
dbg("submit_control_msg dev 0x%p ohci 0x%p\r\n", dev, ohci);
|
||||||
|
|
||||||
#ifdef DEBUG_OHCI
|
#ifdef DEBUG_OHCI
|
||||||
pkt_print(ohci, NULL, dev, pipe, buffer, transfer_len, setup, "SUB", usb_pipein(pipe));
|
pkt_print(ohci, NULL, dev, pipe, buffer, transfer_len, setup, "SUB", usb_pipein(pipe));
|
||||||
#else
|
#else
|
||||||
if (ohci->irq)
|
if (ohci->irq)
|
||||||
|
{
|
||||||
wait(1 * 1000);
|
wait(1 * 1000);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!maxsize)
|
if (!maxsize)
|
||||||
@@ -1663,6 +1757,7 @@ int ohci_submit_control_msg(struct usb_device *dev, uint32_t pipe, void *buffer,
|
|||||||
if (((pipe >> 8) & 0x7f) == ohci->rh.devnum)
|
if (((pipe >> 8) & 0x7f) == ohci->rh.devnum)
|
||||||
{
|
{
|
||||||
ohci->rh.dev = dev;
|
ohci->rh.dev = dev;
|
||||||
|
|
||||||
/* root hub - redirect */
|
/* root hub - redirect */
|
||||||
return ohci_submit_rh_msg(ohci, dev, pipe, buffer, transfer_len, setup);
|
return ohci_submit_rh_msg(ohci, dev, pipe, buffer, transfer_len, setup);
|
||||||
}
|
}
|
||||||
@@ -1671,7 +1766,7 @@ int ohci_submit_control_msg(struct usb_device *dev, uint32_t pipe, void *buffer,
|
|||||||
|
|
||||||
int ohci_submit_int_msg(struct usb_device *dev, uint32_t pipe, void *buffer, int transfer_len, int interval)
|
int ohci_submit_int_msg(struct usb_device *dev, uint32_t pipe, void *buffer, int transfer_len, int interval)
|
||||||
{
|
{
|
||||||
info("submit_int_msg dev 0x%p ohci 0x%p buffer 0x%p len %d", dev, dev->priv_hcd, buffer, transfer_len);
|
err("submit_int_msg dev 0x%p ohci 0x%p buffer 0x%p len %d", dev, dev->priv_hcd, buffer, transfer_len);
|
||||||
return submit_common_msg((ohci_t *)dev->priv_hcd, dev, pipe, buffer, transfer_len, NULL, interval);
|
return submit_common_msg((ohci_t *)dev->priv_hcd, dev, pipe, buffer, transfer_len, NULL, interval);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1769,7 +1864,7 @@ static int hc_reset(ohci_t *ohci)
|
|||||||
{
|
{
|
||||||
/* SMM owns the HC */
|
/* SMM owns the HC */
|
||||||
writel(OHCI_OCR, &ohci->regs->cmdstatus);/* request ownership */
|
writel(OHCI_OCR, &ohci->regs->cmdstatus);/* request ownership */
|
||||||
info("USB HC TakeOver from SMM");
|
err("USB HC TakeOver from SMM");
|
||||||
while (readl(&ohci->regs->control) & OHCI_CTRL_IR)
|
while (readl(&ohci->regs->control) & OHCI_CTRL_IR)
|
||||||
{
|
{
|
||||||
wait(10);
|
wait(10);
|
||||||
@@ -1895,21 +1990,26 @@ void ohci_usb_event_poll(int interrupt)
|
|||||||
|
|
||||||
#endif /* CONFIG_USB_INTERRUPT_POLLING */
|
#endif /* CONFIG_USB_INTERRUPT_POLLING */
|
||||||
|
|
||||||
/* an interrupt happens */
|
/*
|
||||||
|
* an interrupt happens
|
||||||
|
*/
|
||||||
static int hc_interrupt(ohci_t *ohci)
|
static int hc_interrupt(ohci_t *ohci)
|
||||||
{
|
{
|
||||||
struct ohci_regs *regs = ohci->regs;
|
struct ohci_regs *regs = ohci->regs;
|
||||||
int ints, stat = -1;
|
int ints;
|
||||||
|
int stat = -1;
|
||||||
|
|
||||||
if ((ohci->hcca->done_head != 0) && !(swpl(ohci->hcca->done_head) & 0x01))
|
if ((ohci->hcca->done_head != 0) && !(swpl(ohci->hcca->done_head) & 0x01))
|
||||||
|
{
|
||||||
ints = OHCI_INTR_WDH;
|
ints = OHCI_INTR_WDH;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ints = readl(®s->intrstatus);
|
ints = readl(®s->intrstatus);
|
||||||
if (ints == ~(uint32_t) 0)
|
if (ints == ~ 0UL)
|
||||||
{
|
{
|
||||||
ohci->disabled++;
|
ohci->disabled++;
|
||||||
err("OHCI usb-%s-%c device removed!", ohci->slot_name, (char)ohci->controller + '0');
|
err("OHCI usb-%s-%c device removed!\r\n", ohci->slot_name, (char) ohci->controller + '0');
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1917,14 +2017,17 @@ static int hc_interrupt(ohci_t *ohci)
|
|||||||
ints &= readl(®s->intrenable);
|
ints &= readl(®s->intrenable);
|
||||||
if (ints == 0)
|
if (ints == 0)
|
||||||
{
|
{
|
||||||
// dbg("hc_interrupt: returning..\r\n");
|
dbg("no interrupt...\r\n");
|
||||||
|
|
||||||
return 0xff;
|
return 0xff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ohci->irq)
|
if (ohci->irq)
|
||||||
dbg("Interrupt: 0x%x frame: 0x%x bus: %d", ints, swpw(ohci->hcca->frame_no), ohci->controller);
|
{
|
||||||
|
dbg("Interrupt: 0x%x frame: 0x%x bus: %d\r\n", ints, swpw(ohci->hcca->frame_no), ohci->controller);
|
||||||
|
}
|
||||||
|
|
||||||
if (ints & OHCI_INTR_RHSC) /* root hub status change */
|
if (ints & OHCI_INTR_RHSC) /* root hub status change */
|
||||||
{
|
{
|
||||||
@@ -1950,7 +2053,7 @@ static int hc_interrupt(ohci_t *ohci)
|
|||||||
(void) status;
|
(void) status;
|
||||||
|
|
||||||
err("OHCI Unrecoverable Error, controller usb-%s-%c disabled\r\n(SR:0x%04X%s%s%s%s%s%s)",
|
err("OHCI Unrecoverable Error, controller usb-%s-%c disabled\r\n(SR:0x%04X%s%s%s%s%s%s)",
|
||||||
ohci->slot_name, (char)ohci->controller + '0', status & 0xFFFF,
|
ohci->slot_name, (char) ohci->controller + '0', status & 0xFFFF,
|
||||||
status & 0x8000 ? ", Parity error" : "",
|
status & 0x8000 ? ", Parity error" : "",
|
||||||
status & 0x4000 ? ", Signaled system error" : "",
|
status & 0x4000 ? ", Signaled system error" : "",
|
||||||
status & 0x2000 ? ", Received master abort" : "",
|
status & 0x2000 ? ", Received master abort" : "",
|
||||||
@@ -1962,18 +2065,24 @@ static int hc_interrupt(ohci_t *ohci)
|
|||||||
ohci_dump(ohci, 1);
|
ohci_dump(ohci, 1);
|
||||||
#else
|
#else
|
||||||
if (ohci->irq)
|
if (ohci->irq)
|
||||||
|
{
|
||||||
wait(1);
|
wait(1);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
/* HC Reset */
|
/* HC Reset */
|
||||||
ohci->hc_control = 0;
|
ohci->hc_control = 0;
|
||||||
writel(ohci->hc_control, &ohci->regs->control);
|
writel(ohci->hc_control, &ohci->regs->control);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ints & OHCI_INTR_WDH)
|
if (ints & OHCI_INTR_WDH)
|
||||||
{
|
{
|
||||||
if (ohci->irq)
|
if (ohci->irq)
|
||||||
|
{
|
||||||
wait(1);
|
wait(1);
|
||||||
|
}
|
||||||
|
|
||||||
writel(OHCI_INTR_WDH, ®s->intrdisable);
|
writel(OHCI_INTR_WDH, ®s->intrdisable);
|
||||||
(void) readl(®s->intrdisable); /* flush */
|
(void) readl(®s->intrdisable); /* flush */
|
||||||
stat = dl_done_list(ohci);
|
stat = dl_done_list(ohci);
|
||||||
@@ -2086,13 +2195,13 @@ int ohci_usb_lowlevel_init(int32_t handle, const struct pci_device_id *ent, void
|
|||||||
else if (!ohci->handle) /* for restart USB cmd */
|
else if (!ohci->handle) /* for restart USB cmd */
|
||||||
return(-1);
|
return(-1);
|
||||||
|
|
||||||
info("ohci %p", ohci);
|
err("ohci %p", ohci);
|
||||||
|
|
||||||
ohci->controller = PCI_FUNCTION_FROM_HANDLE(ohci->handle);
|
ohci->controller = PCI_FUNCTION_FROM_HANDLE(ohci->handle);
|
||||||
// ohci->controller = (ohci->handle >> 16) & 3; /* PCI function */
|
// ohci->controller = (ohci->handle >> 16) & 3; /* PCI function */
|
||||||
|
|
||||||
/* this must be aligned to a 256 byte boundary */
|
/* this must be aligned to a 256 byte boundary */
|
||||||
ohci->hcca_unaligned = (struct ohci_hcca *) driver_mem_alloc(sizeof(struct ohci_hcca) + 256);
|
ohci->hcca_unaligned = driver_mem_alloc(sizeof(struct ohci_hcca) + 256);
|
||||||
if (ohci->hcca_unaligned == NULL)
|
if (ohci->hcca_unaligned == NULL)
|
||||||
{
|
{
|
||||||
err("HCCA malloc failed");
|
err("HCCA malloc failed");
|
||||||
@@ -2102,8 +2211,8 @@ int ohci_usb_lowlevel_init(int32_t handle, const struct pci_device_id *ent, void
|
|||||||
/* align the storage */
|
/* align the storage */
|
||||||
ohci->hcca = (struct ohci_hcca *) (((uint32_t) ohci->hcca_unaligned + 255) & ~255);
|
ohci->hcca = (struct ohci_hcca *) (((uint32_t) ohci->hcca_unaligned + 255) & ~255);
|
||||||
memset(ohci->hcca, 0, sizeof(struct ohci_hcca));
|
memset(ohci->hcca, 0, sizeof(struct ohci_hcca));
|
||||||
info("aligned ghcca %p", ohci->hcca);
|
err("aligned ghcca %p", ohci->hcca);
|
||||||
ohci->ohci_dev_unaligned = (struct ohci_device *) driver_mem_alloc(sizeof(struct ohci_device) + 8);
|
ohci->ohci_dev_unaligned = driver_mem_alloc(sizeof(struct ohci_device) + 8);
|
||||||
if (ohci->ohci_dev_unaligned == NULL)
|
if (ohci->ohci_dev_unaligned == NULL)
|
||||||
{
|
{
|
||||||
err("EDs malloc failed");
|
err("EDs malloc failed");
|
||||||
@@ -2112,9 +2221,9 @@ int ohci_usb_lowlevel_init(int32_t handle, const struct pci_device_id *ent, void
|
|||||||
}
|
}
|
||||||
ohci->ohci_dev = (struct ohci_device *) (((uint32_t) ohci->ohci_dev_unaligned + 7) & ~7);
|
ohci->ohci_dev = (struct ohci_device *) (((uint32_t) ohci->ohci_dev_unaligned + 7) & ~7);
|
||||||
memset(ohci->ohci_dev, 0, sizeof(struct ohci_device));
|
memset(ohci->ohci_dev, 0, sizeof(struct ohci_device));
|
||||||
info("aligned EDs %p", ohci->ohci_dev);
|
err("aligned EDs %p", ohci->ohci_dev);
|
||||||
|
|
||||||
ohci->td_unaligned = (struct td *) driver_mem_alloc(sizeof(struct td) * (NUM_TD + 1));
|
ohci->td_unaligned = driver_mem_alloc(sizeof(struct td) * (NUM_TD + 1));
|
||||||
if (ohci->td_unaligned == NULL)
|
if (ohci->td_unaligned == NULL)
|
||||||
{
|
{
|
||||||
err("TDs malloc failed");
|
err("TDs malloc failed");
|
||||||
@@ -2126,7 +2235,7 @@ int ohci_usb_lowlevel_init(int32_t handle, const struct pci_device_id *ent, void
|
|||||||
|
|
||||||
dbg("memset from %p to %p\r\n", ptd, ptd + sizeof(td_t) * NUM_TD);
|
dbg("memset from %p to %p\r\n", ptd, ptd + sizeof(td_t) * NUM_TD);
|
||||||
memset(ptd, 0, sizeof(td_t) * NUM_TD);
|
memset(ptd, 0, sizeof(td_t) * NUM_TD);
|
||||||
info("aligned TDs %p", ptd);
|
err("aligned TDs %p", ptd);
|
||||||
|
|
||||||
ohci->disabled = 1;
|
ohci->disabled = 1;
|
||||||
ohci->sleeping = 0;
|
ohci->sleeping = 0;
|
||||||
|
|||||||
86
pci/pci.c
86
pci/pci.c
@@ -78,19 +78,26 @@ static int num_pci_classes = sizeof(pci_classes) / sizeof(struct pci_class);
|
|||||||
/* holds the handle of a card at position = array index */
|
/* holds the handle of a card at position = array index */
|
||||||
static int32_t handles[NUM_CARDS];
|
static int32_t handles[NUM_CARDS];
|
||||||
|
|
||||||
/* holds the interrupt handler addresses (see pci_hook_interrupt() and pci_unhook_interrupt()) of the PCI cards */
|
|
||||||
struct pci_interrupt
|
|
||||||
{
|
|
||||||
void (*handler)(void);
|
|
||||||
int32_t parameter;
|
|
||||||
struct pci_interrupt *next;
|
|
||||||
};
|
|
||||||
#define MAX_INTERRUPTS (NUM_CARDS * 3)
|
|
||||||
static struct pci_interrupt interrupts[MAX_INTERRUPTS];
|
|
||||||
|
|
||||||
/* holds the card's resource descriptors; filled in pci_device_config() */
|
/* holds the card's resource descriptors; filled in pci_device_config() */
|
||||||
static struct pci_rd resource_descriptors[NUM_CARDS][NUM_RESOURCES];
|
static struct pci_rd resource_descriptors[NUM_CARDS][NUM_RESOURCES];
|
||||||
|
|
||||||
|
typedef int (*pci_interrupt_handler)(int param);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* holds the interrupt handler addresses (see pci_hook_interrupt()
|
||||||
|
* and pci_unhook_interrupt()) of the PCI cards
|
||||||
|
*/
|
||||||
|
struct pci_interrupt
|
||||||
|
{
|
||||||
|
int32_t handle;
|
||||||
|
int irq;
|
||||||
|
pci_interrupt_handler handler;
|
||||||
|
int32_t parameter;
|
||||||
|
struct pci_interrupt *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MAX_INTERRUPTS (NUM_CARDS * 3)
|
||||||
|
static struct pci_interrupt interrupts[MAX_INTERRUPTS];
|
||||||
|
|
||||||
__attribute__((aligned(16))) void chip_errata_135(void)
|
__attribute__((aligned(16))) void chip_errata_135(void)
|
||||||
{
|
{
|
||||||
@@ -154,15 +161,23 @@ __attribute__((interrupt)) void pci_interrupt(void)
|
|||||||
*/
|
*/
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||||
|
|
||||||
static int32_t pci_get_interrupt_cause(int32_t *handles)
|
static int32_t pci_get_interrupt_cause(int32_t *handles)
|
||||||
{
|
{
|
||||||
int32_t handle;
|
int32_t handle;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* loop through all PCI devices...
|
||||||
|
*/
|
||||||
while ((handle = *handles++) != -1)
|
while ((handle = *handles++) != -1)
|
||||||
{
|
{
|
||||||
uint32_t csr = swpl(pci_read_config_longword(handle, PCICSR));
|
uint16_t command_register = swpw(pci_read_config_word(handle, PCICR));
|
||||||
|
uint16_t status_register = swpw(pci_read_config_word(handle, PCISR));
|
||||||
|
|
||||||
if ((csr & (1 << 3)) && (csr & !(csr & (1 << 10))))
|
/*
|
||||||
|
* ...to see which device caused the interrupt
|
||||||
|
*/
|
||||||
|
if ((status_register & PCICSR_INTERRUPT) && !(command_register & PCICSR_INT_DISABLE))
|
||||||
{
|
{
|
||||||
/* device has interrupts enabled and has an active interrupt, so its probably ours */
|
/* device has interrupts enabled and has an active interrupt, so its probably ours */
|
||||||
|
|
||||||
@@ -175,11 +190,21 @@ static int32_t pci_get_interrupt_cause(int32_t *handles)
|
|||||||
|
|
||||||
static int32_t pci_call_interrupt_chain(int32_t handle, int32_t data)
|
static int32_t pci_call_interrupt_chain(int32_t handle, int32_t data)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_INTERRUPTS; i++)
|
||||||
|
{
|
||||||
|
if (interrupts[i].handle == handle)
|
||||||
|
{
|
||||||
|
interrupts[i].handler(data);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
return data; /* unmodified - means: not handled */
|
return data; /* unmodified - means: not handled */
|
||||||
}
|
}
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
#ifdef MACHINE_M5484LITE
|
|
||||||
/*
|
/*
|
||||||
* This gets called from irq5 in exceptions.S
|
* This gets called from irq5 in exceptions.S
|
||||||
* Once we arrive here, the SR has been set to disable interrupts and the gcc scratch registers have been saved
|
* Once we arrive here, the SR has been set to disable interrupts and the gcc scratch registers have been saved
|
||||||
@@ -191,7 +216,9 @@ void irq5_handler(void)
|
|||||||
int32_t newvalue;
|
int32_t newvalue;
|
||||||
|
|
||||||
MCF_EPORT_EPFR |= (1 << 5); /* clear interrupt from edge port */
|
MCF_EPORT_EPFR |= (1 << 5); /* clear interrupt from edge port */
|
||||||
|
|
||||||
xprintf("IRQ5!\r\n");
|
xprintf("IRQ5!\r\n");
|
||||||
|
|
||||||
if ((handle = pci_get_interrupt_cause(handles)) > 0)
|
if ((handle = pci_get_interrupt_cause(handles)) > 0)
|
||||||
{
|
{
|
||||||
newvalue = pci_call_interrupt_chain(handle, value);
|
newvalue = pci_call_interrupt_chain(handle, value);
|
||||||
@@ -202,6 +229,7 @@ void irq5_handler(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MACHINE_M5484LITE
|
||||||
/*
|
/*
|
||||||
* This gets called from irq7 in exceptions.S
|
* This gets called from irq7 in exceptions.S
|
||||||
* Once we arrive here, the SR has been set to disable interrupts and the gcc scratch registers have been saved
|
* Once we arrive here, the SR has been set to disable interrupts and the gcc scratch registers have been saved
|
||||||
@@ -580,19 +608,41 @@ int32_t pci_find_classcode(uint32_t classcode, int index)
|
|||||||
return PCI_DEVICE_NOT_FOUND;
|
return PCI_DEVICE_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t pci_hook_interrupt(int32_t handle, void *handler, void *parameter)
|
int32_t pci_hook_interrupt(int32_t handle, pci_interrupt_handler handler, void *parameter)
|
||||||
{
|
{
|
||||||
/* FIXME: implement */
|
int i;
|
||||||
dbg("pci_hook_interrupt() still not implemented\r\n");
|
|
||||||
|
/*
|
||||||
|
* find empty slot
|
||||||
|
*/
|
||||||
|
for (i = 0; i < MAX_INTERRUPTS; i++)
|
||||||
|
{
|
||||||
|
if (interrupts[i].handle == 0)
|
||||||
|
{
|
||||||
|
interrupts[i].handle = handle;
|
||||||
|
interrupts[i].handler = handler;
|
||||||
|
interrupts[i].parameter = (int32_t) parameter;
|
||||||
|
|
||||||
return PCI_SUCCESSFUL;
|
return PCI_SUCCESSFUL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PCI_BUFFER_TOO_SMALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t pci_unhook_interrupt(int32_t handle)
|
int32_t pci_unhook_interrupt(int32_t handle)
|
||||||
{
|
{
|
||||||
/* FIXME: implement */
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_INTERRUPTS; i++)
|
||||||
|
{
|
||||||
|
if (interrupts[i].handle == handle)
|
||||||
|
{
|
||||||
|
memset(&interrupts[i], 0, sizeof(struct pci_interrupt));
|
||||||
|
|
||||||
dbg("pci_unhook_interrupt() still not implemented\r\n");
|
|
||||||
return PCI_SUCCESSFUL;
|
return PCI_SUCCESSFUL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PCI_DEVICE_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -429,7 +429,7 @@ irq7text:
|
|||||||
.text
|
.text
|
||||||
|
|
||||||
#elif MACHINE_FIREBEE /* these handlers are only meaningful for the Firebee */
|
#elif MACHINE_FIREBEE /* these handlers are only meaningful for the Firebee */
|
||||||
irq5: // irq5 is tied to PCI INTC# and PCI INTD# on the M5484LITE
|
irq5:
|
||||||
irq 0x74,5,0x20
|
irq 0x74,5,0x20
|
||||||
|
|
||||||
irq6: // MFP interrupt from FPGA
|
irq6: // MFP interrupt from FPGA
|
||||||
@@ -466,6 +466,22 @@ irq6_1:
|
|||||||
bne irq6_2
|
bne irq6_2
|
||||||
lea MCF_GPIO_PODR_FEC1L,a5
|
lea MCF_GPIO_PODR_FEC1L,a5
|
||||||
bset.b #4,(a5) // led off
|
bset.b #4,(a5) // led off
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Firebee inthandler. 0xf0020000 delivers the interrupt vector
|
||||||
|
*
|
||||||
|
* 0: PIC_INT
|
||||||
|
* 1: E0_INT
|
||||||
|
* 2: DVI_INT
|
||||||
|
* 3: PCI_INT#A
|
||||||
|
* 4: PCI_INT#B
|
||||||
|
* 5: PCI_INT#C
|
||||||
|
* 6: PCI_INT#D
|
||||||
|
* 7: DSP_INT
|
||||||
|
* 8: VSYNC
|
||||||
|
* 9: HSYNC
|
||||||
|
*/
|
||||||
|
|
||||||
irq6_2:
|
irq6_2:
|
||||||
move.l 0xF0020000,a5 // vector holen
|
move.l 0xF0020000,a5 // vector holen
|
||||||
add.l _rt_vbr,a5 // basis
|
add.l _rt_vbr,a5 // basis
|
||||||
|
|||||||
46
usb/usb.c
46
usb/usb.c
@@ -54,9 +54,6 @@
|
|||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
#include "usb_hub.h"
|
#include "usb_hub.h"
|
||||||
|
|
||||||
extern int usb_stor_curr_dev;
|
|
||||||
extern uint32_t usb_1st_disk_drive;
|
|
||||||
|
|
||||||
//#define DEBUG_USB
|
//#define DEBUG_USB
|
||||||
#ifdef DEBUG_USB
|
#ifdef DEBUG_USB
|
||||||
#define dbg(format, arg...) do { xprintf("DEBUG: %s(): " format, __FUNCTION__, ##arg); } while (0)
|
#define dbg(format, arg...) do { xprintf("DEBUG: %s(): " format, __FUNCTION__, ##arg); } while (0)
|
||||||
@@ -97,7 +94,10 @@ int usb_init(int32_t handle, const struct pci_device_id *ent)
|
|||||||
struct hci *priv;
|
struct hci *priv;
|
||||||
int res = 0;
|
int res = 0;
|
||||||
if (bus_index >= USB_MAX_BUS)
|
if (bus_index >= USB_MAX_BUS)
|
||||||
|
{
|
||||||
|
dbg("bus_index >= USB_MAX_BUS");
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
dev_index[bus_index] = 0;
|
dev_index[bus_index] = 0;
|
||||||
asynch_allowed = 1;
|
asynch_allowed = 1;
|
||||||
@@ -107,21 +107,29 @@ int usb_init(int32_t handle, const struct pci_device_id *ent)
|
|||||||
if (driver_mem_init())
|
if (driver_mem_init())
|
||||||
{
|
{
|
||||||
usb_started = 0;
|
usb_started = 0;
|
||||||
|
dbg("driver_mem_init failed\r\n");
|
||||||
|
|
||||||
return -1; /* out of memory */
|
return -1; /* out of memory */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (usb_dev == NULL)
|
if (usb_dev == NULL)
|
||||||
|
{
|
||||||
usb_dev = (struct usb_device *) driver_mem_alloc(sizeof(struct usb_device) * USB_MAX_BUS * USB_MAX_DEVICE);
|
usb_dev = (struct usb_device *) driver_mem_alloc(sizeof(struct usb_device) * USB_MAX_BUS * USB_MAX_DEVICE);
|
||||||
|
}
|
||||||
|
|
||||||
if (usb_dev == NULL)
|
if (usb_dev == NULL)
|
||||||
{
|
{
|
||||||
usb_started = 0;
|
usb_started = 0;
|
||||||
|
|
||||||
|
dbg("could not allocate memory\r\n");
|
||||||
|
|
||||||
return -1; /* out of memory */
|
return -1; /* out of memory */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else /* restart */
|
else /* restart */
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
res = 0;
|
res = 0;
|
||||||
for (i = 0; i < USB_MAX_BUS; i++)
|
for (i = 0; i < USB_MAX_BUS; i++)
|
||||||
{
|
{
|
||||||
@@ -131,7 +139,7 @@ int usb_init(int32_t handle, const struct pci_device_id *ent)
|
|||||||
|
|
||||||
if (handle)
|
if (handle)
|
||||||
{
|
{
|
||||||
res |= usb_init(handle, NULL); /* FIXME: recursive call! */
|
res |= usb_init(handle, NULL); /* FIXME: recursive call!? */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -176,6 +184,9 @@ int usb_init(int32_t handle, const struct pci_device_id *ent)
|
|||||||
if (setup_packet == NULL)
|
if (setup_packet == NULL)
|
||||||
{
|
{
|
||||||
usb_started = 0;
|
usb_started = 0;
|
||||||
|
|
||||||
|
dbg("could not allocate memory\r\n");
|
||||||
|
|
||||||
return -1; /* no memory, no USB */
|
return -1; /* no memory, no USB */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -306,11 +317,13 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe,
|
|||||||
unsigned short value, unsigned short index,
|
unsigned short value, unsigned short index,
|
||||||
void *data, unsigned short size, int timeout)
|
void *data, unsigned short size, int timeout)
|
||||||
{
|
{
|
||||||
struct hci *priv = (struct hci *)dev->priv_hcd;
|
struct hci *priv = (struct hci *) dev->priv_hcd;
|
||||||
|
|
||||||
if ((timeout == 0) && (!asynch_allowed))
|
if ((timeout == 0) && (!asynch_allowed))
|
||||||
{
|
{
|
||||||
/* request for a asynch control pipe is not allowed */
|
/* request for a asynch control pipe is not allowed */
|
||||||
|
|
||||||
|
dbg("request for an async control pipe is not allowed\r\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1064,7 +1077,9 @@ struct usb_device *usb_alloc_new_device(int bus_index, void *priv)
|
|||||||
*/
|
*/
|
||||||
int usb_new_device(struct usb_device *dev)
|
int usb_new_device(struct usb_device *dev)
|
||||||
{
|
{
|
||||||
int addr, err, tmp;
|
int addr;
|
||||||
|
int err;
|
||||||
|
int tmp;
|
||||||
unsigned char *tmpbuf;
|
unsigned char *tmpbuf;
|
||||||
|
|
||||||
#ifndef CONFIG_LEGACY_USB_INIT_SEQ
|
#ifndef CONFIG_LEGACY_USB_INIT_SEQ
|
||||||
@@ -1075,7 +1090,10 @@ int usb_new_device(struct usb_device *dev)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (dev == NULL)
|
if (dev == NULL)
|
||||||
|
{
|
||||||
|
dbg("called with NULL device\r\n");
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* We still haven't set the Address yet */
|
/* We still haven't set the Address yet */
|
||||||
addr = dev->devnum;
|
addr = dev->devnum;
|
||||||
@@ -1084,7 +1102,7 @@ int usb_new_device(struct usb_device *dev)
|
|||||||
tmpbuf = (unsigned char *) driver_mem_alloc(USB_BUFSIZ);
|
tmpbuf = (unsigned char *) driver_mem_alloc(USB_BUFSIZ);
|
||||||
if (tmpbuf == NULL)
|
if (tmpbuf == NULL)
|
||||||
{
|
{
|
||||||
dbg("usb_new_device: malloc failure\r\n");
|
dbg("malloc failure\r\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1125,6 +1143,7 @@ int usb_new_device(struct usb_device *dev)
|
|||||||
*/
|
*/
|
||||||
desc = (struct usb_device_descriptor *) tmpbuf;
|
desc = (struct usb_device_descriptor *) tmpbuf;
|
||||||
dev->descriptor.bMaxPacketSize0 = 64; /* Start off at 64 bytes */
|
dev->descriptor.bMaxPacketSize0 = 64; /* Start off at 64 bytes */
|
||||||
|
|
||||||
/* Default to 64 byte max packet size */
|
/* Default to 64 byte max packet size */
|
||||||
dev->maxpacketsize = PACKET_SIZE_64;
|
dev->maxpacketsize = PACKET_SIZE_64;
|
||||||
dev->epmaxpacketin[0] = 64;
|
dev->epmaxpacketin[0] = 64;
|
||||||
@@ -1260,7 +1279,9 @@ int usb_new_device(struct usb_device *dev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* build device Tree */
|
/*
|
||||||
|
* build device Tree
|
||||||
|
*/
|
||||||
void usb_scan_devices(void *priv)
|
void usb_scan_devices(void *priv)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -1274,7 +1295,9 @@ void usb_scan_devices(void *priv)
|
|||||||
}
|
}
|
||||||
dev_index[bus_index] = 0;
|
dev_index[bus_index] = 0;
|
||||||
|
|
||||||
/* device 0 is always present (root hub, so let it analyze) */
|
/*
|
||||||
|
* device 0 is always present (root hub, so let it analyze)
|
||||||
|
*/
|
||||||
dev = usb_alloc_new_device(bus_index, priv);
|
dev = usb_alloc_new_device(bus_index, priv);
|
||||||
if (usb_new_device(dev))
|
if (usb_new_device(dev))
|
||||||
{
|
{
|
||||||
@@ -1289,9 +1312,6 @@ void usb_scan_devices(void *priv)
|
|||||||
xprintf("%d USB Device(s) found\r\n", dev_index[bus_index]);
|
xprintf("%d USB Device(s) found\r\n", dev_index[bus_index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
#ifdef _NOT_USED_ /* not implemented yet */
|
|
||||||
/* insert "driver" if possible */
|
/* insert "driver" if possible */
|
||||||
if (drv_usb_kbd_init() < 0)
|
if (drv_usb_kbd_init() < 0)
|
||||||
{
|
{
|
||||||
@@ -1301,7 +1321,6 @@ void usb_scan_devices(void *priv)
|
|||||||
{
|
{
|
||||||
xprintf("USB HID keyboard driver installed\r\n");
|
xprintf("USB HID keyboard driver installed\r\n");
|
||||||
}
|
}
|
||||||
#endif /* _NOT_USED */
|
|
||||||
|
|
||||||
if (drv_usb_mouse_init() < 0)
|
if (drv_usb_mouse_init() < 0)
|
||||||
{
|
{
|
||||||
@@ -1311,7 +1330,6 @@ void usb_scan_devices(void *priv)
|
|||||||
{
|
{
|
||||||
xprintf("USB HID mouse driver installed\r\n");
|
xprintf("USB HID mouse driver installed\r\n");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
xprintf("Scan end\r\n");
|
xprintf("Scan end\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
1389
usb/usb_kbd.c
Normal file
1389
usb/usb_kbd.c
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user