mirror of
https://github.com/apache/nuttx.git
synced 2026-06-06 08:36:24 +08:00
More HID keyboard support
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3255 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
@@ -85,10 +85,11 @@
|
||||
/* OHCI Setup ******************************************************************/
|
||||
/* Frame Interval / Periodic Start */
|
||||
|
||||
#define FI (12000-1) /* 12000 bits per frame (-1) */
|
||||
#define FSMPS ((6 * (FI - 210)) / 7)
|
||||
#define DEFAULT_FMINTERVAL ((FSMPS << OHCI_FMINT_FSMPS_SHIFT) | FI)
|
||||
#define DEFAULT_PERSTART ((9 * FI) / 10)
|
||||
#define BITS_PER_FRAME 12000
|
||||
#define FI (BITS_PER_FRAME-1)
|
||||
#define FSMPS ((6 * (FI - 210)) / 7)
|
||||
#define DEFAULT_FMINTERVAL ((FSMPS << OHCI_FMINT_FSMPS_SHIFT) | FI)
|
||||
#define DEFAULT_PERSTART (((9 * BITS_PER_FRAME) / 10) - 1)
|
||||
|
||||
/* CLKCTRL enable bits */
|
||||
|
||||
@@ -152,11 +153,15 @@ struct lpc17_usbhost_s
|
||||
|
||||
/* Driver status */
|
||||
|
||||
volatile bool connected; /* Connected to device */
|
||||
volatile bool lowspeed; /* Low speed device attached. */
|
||||
volatile bool rhswait; /* TRUE: Thread is waiting for Root Hub Status change */
|
||||
sem_t exclsem; /* Support mutually exclusive access */
|
||||
sem_t rhssem; /* Semaphore to wait Writeback Done Head event */
|
||||
volatile bool connected; /* Connected to device */
|
||||
volatile bool lowspeed; /* Low speed device attached. */
|
||||
volatile bool rhswait; /* TRUE: Thread is waiting for Root Hub Status change */
|
||||
#ifndef CONFIG_USBHOST_INT_DISABLE
|
||||
uint8_t ininterval; /* Minimum periodic IN EP polling interval: 2, 4, 6, 16, or 32 */
|
||||
uint8_t outinterval; /* Minimum periodic IN EP polling interval: 2, 4, 6, 16, or 32 */
|
||||
#endif
|
||||
sem_t exclsem; /* Support mutually exclusive access */
|
||||
sem_t rhssem; /* Semaphore to wait Writeback Done Head event */
|
||||
};
|
||||
|
||||
/* The OCHI expects the size of an endpoint descriptor to be 16 bytes.
|
||||
@@ -174,7 +179,7 @@ struct lpc17_ed_s
|
||||
/* Software specific fields */
|
||||
|
||||
uint8_t xfrtype; /* Transfer type. See SB_EP_ATTR_XFER_* in usb.h */
|
||||
uint8_t period; /* Periodic EP polling frequency 1, 2, 4, 6, 16, or 32 */
|
||||
uint8_t interval; /* Periodic EP polling interval: 2, 4, 6, 16, or 32 */
|
||||
volatile uint8_t tdstatus; /* TD control status bits from last Writeback Done Head event */
|
||||
volatile bool wdhwait; /* TRUE: Thread is waiting for WDH interrupt */
|
||||
sem_t wdhsem; /* Semaphore used to wait for Writeback Done Head event */
|
||||
@@ -251,11 +256,20 @@ static inline int lpc17_addbulked(struct lpc17_usbhost_s *priv,
|
||||
struct lpc17_ed_s *ed);
|
||||
static inline int lpc17_rembulked(struct lpc17_usbhost_s *priv,
|
||||
struct lpc17_ed_s *ed);
|
||||
|
||||
#if !defined(CONFIG_USBHOST_INT_DISABLE) || !defined(CONFIG_USBHOST_ISOC_DISABLE)
|
||||
static unsigned int lpc17_getinterval(uint8_t interval);
|
||||
static void lpc17_setinttab(uint32_t value, unsigned int interval, unsigned int offset);
|
||||
#endif
|
||||
|
||||
static inline int lpc17_addinted(struct lpc17_usbhost_s *priv,
|
||||
const FAR struct usbhost_epdesc_s *epdesc,
|
||||
struct lpc17_ed_s *ed);
|
||||
static inline int lpc17_reminted(struct lpc17_usbhost_s *priv,
|
||||
struct lpc17_ed_s *ed);
|
||||
|
||||
static inline int lpc17_addisoced(struct lpc17_usbhost_s *priv,
|
||||
const FAR struct usbhost_epdesc_s *epdesc,
|
||||
struct lpc17_ed_s *ed);
|
||||
static inline int lpc17_remisoced(struct lpc17_usbhost_s *priv,
|
||||
struct lpc17_ed_s *ed);
|
||||
@@ -722,9 +736,9 @@ static inline int lpc17_rembulked(struct lpc17_usbhost_s *priv,
|
||||
struct lpc17_ed_s *ed)
|
||||
{
|
||||
#ifndef CONFIG_USBHOST_BULK_DISABLE
|
||||
struct lpc17_ed_s *curr = NULL;
|
||||
struct lpc17_ed_s *prev = NULL;
|
||||
uint32_t regval;
|
||||
struct lpc17_ed_s *curr;
|
||||
struct lpc17_ed_s *prev;
|
||||
uint32_t regval;
|
||||
|
||||
/* Find the ED in the bulk list. NOTE: We really should never be mucking
|
||||
* with the bulk list while BLE is set.
|
||||
@@ -773,44 +787,315 @@ static inline int lpc17_rembulked(struct lpc17_usbhost_s *priv,
|
||||
#endif
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Name: lpc17_getinterval
|
||||
*
|
||||
* Description:
|
||||
* Convert the endpoint polling interval into a HCCA table increment
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
#if !defined(CONFIG_USBHOST_INT_DISABLE) || !defined(CONFIG_USBHOST_ISOC_DISABLE)
|
||||
static unsigned int lpc17_getinterval(uint8_t interval)
|
||||
{
|
||||
/* The bInterval field of the endpoint descriptor contains the polling interval
|
||||
* for interrupt and isochronous endpoints. For other types of endpoint, this
|
||||
* value should be ignored. bInterval is provided in units of 1MS frames.
|
||||
*/
|
||||
|
||||
if (interval < 3)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
else if (interval < 7)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
else if (interval < 15)
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
else if (interval < 31)
|
||||
{
|
||||
return 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 32;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* Name: lpc17_setinttab
|
||||
*
|
||||
* Description:
|
||||
* Set the interrupt table to the selected value using the provided interval
|
||||
* and offset.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
#if !defined(CONFIG_USBHOST_INT_DISABLE) || !defined(CONFIG_USBHOST_ISOC_DISABLE)
|
||||
static void lpc17_setinttab(uint32_t value, unsigned int interval, unsigned int offset)
|
||||
{
|
||||
unsigned int i;
|
||||
for (i = offset; i < HCCA_INTTBL_WSIZE; i += interval)
|
||||
{
|
||||
HCCA->inttbl[i] = value;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* Name: lpc17_addinted
|
||||
*
|
||||
* Description:
|
||||
* Helper function to add an ED to the HCCA interrupt table.
|
||||
*
|
||||
* To avoid reshuffling the table so much and to keep life simple in general,
|
||||
* the following rules are applied:
|
||||
*
|
||||
* 1. IN EDs get the even entries, OUT EDs get the odd entries.
|
||||
* 2. Add IN/OUT EDs are scheduled together at the minimum interval of all
|
||||
* IN/OUT EDs.
|
||||
*
|
||||
* This has the following consequences:
|
||||
*
|
||||
* 1. The minimum support polling rate is 2MS, and
|
||||
* 2. Some devices may get polled at a much higher rate than they request.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
static inline int lpc17_addinted(struct lpc17_usbhost_s *priv,
|
||||
const FAR struct usbhost_epdesc_s *epdesc,
|
||||
struct lpc17_ed_s *ed)
|
||||
{
|
||||
#ifndef CONFIG_USBHOST_INT_DISABLE
|
||||
# warning "Interrupt endpoints not yet supported"
|
||||
unsigned int interval;
|
||||
unsigned int offset;
|
||||
uint32_t head;
|
||||
uint32_t regval;
|
||||
|
||||
/* Disable periodic list processing. Does this take effect immediately? Or
|
||||
* at the next SOF... need to check.
|
||||
*/
|
||||
|
||||
regval = lpc17_getreg(LPC17_USBHOST_CTRL);
|
||||
regval &= ~OHCI_CTRL_PLE;
|
||||
lpc17_putreg(regval, LPC17_USBHOST_CTRL);
|
||||
|
||||
/* Get the quanitized interval value associated with this ED and save it
|
||||
* in the ED.
|
||||
*/
|
||||
|
||||
interval = lpc17_getinterval(epdesc->interval);
|
||||
ed->interval = interval;
|
||||
uvdbg("interval: %d->%d\n", epdesc->interval, interval);
|
||||
|
||||
/* Get the offset associated with the ED direction. IN EDs get the even
|
||||
* entries, OUT EDs get the odd entries.
|
||||
*
|
||||
* Get the new, minimum interval. Add IN/OUT EDs are scheduled together
|
||||
* at the minimum interval of all IN/OUT EDs.
|
||||
*/
|
||||
|
||||
if (epdesc->in)
|
||||
{
|
||||
offset = 0;
|
||||
if (priv->ininterval > interval)
|
||||
{
|
||||
priv->ininterval = interval;
|
||||
}
|
||||
else
|
||||
{
|
||||
interval = priv->ininterval;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
offset = 1;
|
||||
if (priv->outinterval > interval)
|
||||
{
|
||||
priv->outinterval = interval;
|
||||
}
|
||||
else
|
||||
{
|
||||
interval = priv->outinterval;
|
||||
}
|
||||
}
|
||||
uvdbg("min interval: %d offset: %d\n", interval, offset);
|
||||
|
||||
/* Get the head of the first of the duplicated entries. The first offset
|
||||
* entry is always guaranteed to contain the common ED list head.
|
||||
*/
|
||||
|
||||
head = HCCA->inttbl[offset];
|
||||
|
||||
/* Clear all current entries in the interrupt table for this direction */
|
||||
|
||||
lpc17_setinttab(0, 2, offset);
|
||||
|
||||
/* Add the new ED before the old head of the periodic ED list and set the
|
||||
* new ED as the head ED in all of the appropriate entries of the HCCA
|
||||
* interrupt table.
|
||||
*/
|
||||
|
||||
ed->hw.nexted = head;
|
||||
lpc17_setinttab((uint32_t)ed, interval, offset);
|
||||
uvdbg("head: %08x next: %08x\n", ed, head);
|
||||
|
||||
/* Re-enabled periodic list processing */
|
||||
|
||||
regval = lpc17_getreg(LPC17_USBHOST_CTRL);
|
||||
regval &= ~OHCI_CTRL_PLE;
|
||||
lpc17_putreg(regval, LPC17_USBHOST_CTRL);
|
||||
return OK;
|
||||
#else
|
||||
return -ENOSYS;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Name: lpc17_addbulked
|
||||
* Name: lpc17_reminted
|
||||
*
|
||||
* Description:
|
||||
* Helper function to remove an ED from the HCCA interrupt table.
|
||||
*
|
||||
* To avoid reshuffling the table so much and to keep life simple in general,
|
||||
* the following rules are applied:
|
||||
*
|
||||
* 1. IN EDs get the even entries, OUT EDs get the odd entries.
|
||||
* 2. Add IN/OUT EDs are scheduled together at the minimum interval of all
|
||||
* IN/OUT EDs.
|
||||
*
|
||||
* This has the following consequences:
|
||||
*
|
||||
* 1. The minimum support polling rate is 2MS, and
|
||||
* 2. Some devices may get polled at a much higher rate than they request.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
static inline int lpc17_reminted(struct lpc17_usbhost_s *priv,
|
||||
struct lpc17_ed_s *ed)
|
||||
{
|
||||
#ifndef CONFIG_USBHOST_INT_DISABLE
|
||||
# warning "Interrupt endpoints not yet supported"
|
||||
struct lpc17_ed_s *head;
|
||||
struct lpc17_ed_s *curr;
|
||||
struct lpc17_ed_s *prev;
|
||||
unsigned int interval;
|
||||
unsigned int offset;
|
||||
uint32_t regval;
|
||||
|
||||
/* Disable periodic list processing. Does this take effect immediately? Or
|
||||
* at the next SOF... need to check.
|
||||
*/
|
||||
|
||||
regval = lpc17_getreg(LPC17_USBHOST_CTRL);
|
||||
regval &= ~OHCI_CTRL_PLE;
|
||||
lpc17_putreg(regval, LPC17_USBHOST_CTRL);
|
||||
|
||||
/* Get the offset associated with the ED direction. IN EDs get the even
|
||||
* entries, OUT EDs get the odd entries.
|
||||
*/
|
||||
|
||||
if ((ed->hw.ctrl && ED_CONTROL_D_MASK) == ED_CONTROL_D_IN)
|
||||
{
|
||||
offset = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
offset = 1;
|
||||
}
|
||||
|
||||
/* Get the head of the first of the duplicated entries. The first offset
|
||||
* entry is always guaranteed to contain the common ED list head.
|
||||
*/
|
||||
|
||||
head = (struct lpc17_ed_s *)HCCA->inttbl[offset];
|
||||
uvdbg("ed: %08x head: %08x next: %08x offset: %d\n",
|
||||
ed, head, head ? head->hw.nexted : 0, offset);
|
||||
|
||||
/* Find the ED to be removed in the ED list */
|
||||
|
||||
for (curr = head, prev = NULL;
|
||||
curr && curr != ed;
|
||||
prev = curr, curr = (struct lpc17_ed_s *)curr->hw.nexted);
|
||||
|
||||
/* Hmmm.. It would be a bug if we do not find the ED in the bulk list. */
|
||||
|
||||
DEBUGASSERT(curr != NULL);
|
||||
if (curr != NULL)
|
||||
{
|
||||
/* Clear all current entries in the interrupt table for this direction */
|
||||
|
||||
lpc17_setinttab(0, 2, offset);
|
||||
|
||||
/* Remove the ED from the list.. Is this ED the first on in the list? */
|
||||
|
||||
if (prev == NULL)
|
||||
{
|
||||
/* Yes... set the head of the bulk list to skip over this ED */
|
||||
|
||||
head = (struct lpc17_ed_s *)ed->hw.nexted;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No.. set the forward link of the previous ED in the list
|
||||
* skip over this ED.
|
||||
*/
|
||||
|
||||
prev->hw.nexted = ed->hw.nexted;
|
||||
}
|
||||
uvdbg("ed: %08x head: %08x next: %08x\n",
|
||||
ed, head, head ? head->hw.nexted : 0);
|
||||
|
||||
/* Calculate the new minimum interval for this list */
|
||||
|
||||
interval = 32;
|
||||
for (curr = head; curr; curr = (struct lpc17_ed_s *)curr->hw.nexted)
|
||||
{
|
||||
if (curr->interval < interval)
|
||||
{
|
||||
interval = curr->interval;
|
||||
}
|
||||
}
|
||||
uvdbg("min interval: %d offset: %d\n", interval, offset);
|
||||
|
||||
/* Save the new minimum interval */
|
||||
|
||||
if ((ed->hw.ctrl && ED_CONTROL_D_MASK) == ED_CONTROL_D_IN)
|
||||
{
|
||||
priv->ininterval = interval;
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->outinterval = interval;
|
||||
}
|
||||
|
||||
/* Set the head ED in all of the appropriate entries of the HCCA interrupt
|
||||
* table (head might be NULL).
|
||||
*/
|
||||
|
||||
lpc17_setinttab((uint32_t)head, interval, offset);
|
||||
}
|
||||
|
||||
/* Re-enabled periodic list processing */
|
||||
|
||||
if (head != NULL)
|
||||
{
|
||||
regval = lpc17_getreg(LPC17_USBHOST_CTRL);
|
||||
regval &= ~OHCI_CTRL_PLE;
|
||||
lpc17_putreg(regval, LPC17_USBHOST_CTRL);
|
||||
}
|
||||
|
||||
return OK;
|
||||
#else
|
||||
return -ENOSYS;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Name: lpc17_addbulked
|
||||
* Name: lpc17_addisoced
|
||||
*
|
||||
* Description:
|
||||
* Helper functions to add an ED to the periodic table.
|
||||
@@ -818,6 +1103,7 @@ static inline int lpc17_reminted(struct lpc17_usbhost_s *priv,
|
||||
*******************************************************************************/
|
||||
|
||||
static inline int lpc17_addisoced(struct lpc17_usbhost_s *priv,
|
||||
const FAR struct usbhost_epdesc_s *epdesc,
|
||||
struct lpc17_ed_s *ed)
|
||||
{
|
||||
#ifndef CONFIG_USBHOST_ISOC_DISABLE
|
||||
@@ -828,7 +1114,7 @@ static inline int lpc17_addisoced(struct lpc17_usbhost_s *priv,
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Name: lpc17_addbulked
|
||||
* Name: lpc17_remisoced
|
||||
*
|
||||
* Description:
|
||||
* Helper functions to remove an ED from the periodic table.
|
||||
@@ -1441,7 +1727,7 @@ static int lpc17_epalloc(FAR struct usbhost_driver_s *drvr,
|
||||
|
||||
/* Get the direction of the endpoint */
|
||||
|
||||
if (epdesc->in != 0)
|
||||
if (epdesc->in)
|
||||
{
|
||||
ed->hw.ctrl |= ED_CONTROL_D_IN;
|
||||
}
|
||||
@@ -1491,11 +1777,11 @@ static int lpc17_epalloc(FAR struct usbhost_driver_s *drvr,
|
||||
break;
|
||||
|
||||
case USB_EP_ATTR_XFER_INT:
|
||||
ret = lpc17_addinted(priv, ed);
|
||||
ret = lpc17_addinted(priv, epdesc, ed);
|
||||
break;
|
||||
|
||||
case USB_EP_ATTR_XFER_ISOC:
|
||||
ret = lpc17_addisoced(priv, ed);
|
||||
ret = lpc17_addisoced(priv, epdesc, ed);
|
||||
break;
|
||||
|
||||
case USB_EP_ATTR_XFER_CONTROL:
|
||||
|
||||
+477
-215
File diff suppressed because it is too large
Load Diff
@@ -65,12 +65,12 @@
|
||||
#endif
|
||||
|
||||
/* Driver support ***********************************************************/
|
||||
/* This format is used to construct the /dev/sd[n] device driver path. It
|
||||
/* This format is used to construct the /dev/skel[n] device driver path. It
|
||||
* defined here so that it will be used consistently in all places.
|
||||
*/
|
||||
|
||||
#define DEV_FORMAT "/dev/sd%c"
|
||||
#define DEV_NAMELEN 10
|
||||
#define DEV_FORMAT "/dev/skel%c"
|
||||
#define DEV_NAMELEN 12
|
||||
|
||||
/* Used in usbhost_cfgdesc() */
|
||||
|
||||
@@ -85,8 +85,8 @@
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/* This structure contains the internal, private state of the USB host mass
|
||||
* storage class.
|
||||
/* This structure contains the internal, private state of the USB host class
|
||||
* driver.
|
||||
*/
|
||||
|
||||
struct usbhost_state_s
|
||||
@@ -99,15 +99,15 @@ struct usbhost_state_s
|
||||
|
||||
struct usbhost_driver_s *drvr;
|
||||
|
||||
/* The remainder of the fields are provide o the mass storage class */
|
||||
/* The remainder of the fields are provide to the class driver */
|
||||
|
||||
char sdchar; /* Character identifying the /dev/sd[n] device */
|
||||
char devchar; /* Character identifying the /dev/skel[n] device */
|
||||
volatile bool disconnected; /* TRUE: Device has been disconnected */
|
||||
int16_t crefs; /* Reference count on the driver instance */
|
||||
sem_t exclsem; /* Used to maintain mutual exclusive access */
|
||||
struct work_s work; /* For interacting with the worker thread */
|
||||
FAR uint8_t *tdbuffer; /* The allocated transfer descriptor buffer */
|
||||
size_t tdbuflen; /* Size of the allocated transfer buffer */
|
||||
FAR uint8_t *tbuffer; /* The allocated transfer buffer */
|
||||
size_t tbuflen; /* Size of the allocated transfer buffer */
|
||||
usbhost_ep_t epin; /* IN endpoint */
|
||||
usbhost_ep_t epout; /* OUT endpoint */
|
||||
};
|
||||
@@ -152,8 +152,8 @@ static void usbhost_putle32(uint8_t *dest, uint32_t val);
|
||||
|
||||
/* Transfer descriptor memory management */
|
||||
|
||||
static inline int usbhost_tdalloc(FAR struct usbhost_state_s *priv);
|
||||
static inline int usbhost_tdfree(FAR struct usbhost_state_s *priv);
|
||||
static inline int usbhost_talloc(FAR struct usbhost_state_s *priv);
|
||||
static inline int usbhost_tfree(FAR struct usbhost_state_s *priv);
|
||||
|
||||
/* struct usbhost_registry_s methods */
|
||||
|
||||
@@ -174,8 +174,7 @@ static int usbhost_disconnected(FAR struct usbhost_class_s *class);
|
||||
****************************************************************************/
|
||||
|
||||
/* This structure provides the registry entry ID informatino that will be
|
||||
* used to associate the USB host mass storage class to a connected USB
|
||||
* device.
|
||||
* used to associate the USB class driver to a connected USB device.
|
||||
*/
|
||||
|
||||
static const const struct usbhost_id_s g_id =
|
||||
@@ -197,7 +196,7 @@ static struct usbhost_registry_s g_skeleton =
|
||||
&g_id /* id[] */
|
||||
};
|
||||
|
||||
/* This is a bitmap that is used to allocate device names /dev/sda-z. */
|
||||
/* This is a bitmap that is used to allocate device names /dev/skela-z. */
|
||||
|
||||
static uint32_t g_devinuse;
|
||||
|
||||
@@ -303,7 +302,7 @@ static int usbhost_allocdevno(FAR struct usbhost_state_s *priv)
|
||||
if ((g_devinuse & bitno) == 0)
|
||||
{
|
||||
g_devinuse |= bitno;
|
||||
priv->sdchar = 'a' + devno;
|
||||
priv->devchar = 'a' + devno;
|
||||
irqrestore(flags);
|
||||
return OK;
|
||||
}
|
||||
@@ -315,7 +314,7 @@ static int usbhost_allocdevno(FAR struct usbhost_state_s *priv)
|
||||
|
||||
static void usbhost_freedevno(FAR struct usbhost_state_s *priv)
|
||||
{
|
||||
int devno = 'a' - priv->sdchar;
|
||||
int devno = 'a' - priv->devchar;
|
||||
|
||||
if (devno >= 0 && devno < 26)
|
||||
{
|
||||
@@ -327,7 +326,7 @@ static void usbhost_freedevno(FAR struct usbhost_state_s *priv)
|
||||
|
||||
static inline void usbhost_mkdevname(FAR struct usbhost_state_s *priv, char *devname)
|
||||
{
|
||||
(void)snprintf(devname, DEV_NAMELEN, DEV_FORMAT, priv->sdchar);
|
||||
(void)snprintf(devname, DEV_NAMELEN, DEV_FORMAT, priv->devchar);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -761,10 +760,10 @@ static void usbhost_putle32(uint8_t *dest, uint32_t val)
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: usbhost_tdalloc
|
||||
* Name: usbhost_talloc
|
||||
*
|
||||
* Description:
|
||||
* Allocate transfer descriptor memory.
|
||||
* Allocate transfer buffer memory.
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - A reference to the class instance.
|
||||
@@ -775,17 +774,17 @@ static void usbhost_putle32(uint8_t *dest, uint32_t val)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline int usbhost_tdalloc(FAR struct usbhost_state_s *priv)
|
||||
static inline int usbhost_talloc(FAR struct usbhost_state_s *priv)
|
||||
{
|
||||
DEBUGASSERT(priv && priv->tdbuffer == NULL);
|
||||
return DRVR_ALLOC(priv->drvr, &priv->tdbuffer, &priv->tdbuflen);
|
||||
DEBUGASSERT(priv && priv->tbuffer == NULL);
|
||||
return DRVR_ALLOC(priv->drvr, &priv->tbuffer, &priv->tbuflen);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: usbhost_tdfree
|
||||
* Name: usbhost_tfree
|
||||
*
|
||||
* Description:
|
||||
* Free transfer descriptor memory.
|
||||
* Free transfer buffer memory.
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - A reference to the class instance.
|
||||
@@ -796,17 +795,17 @@ static inline int usbhost_tdalloc(FAR struct usbhost_state_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline int usbhost_tdfree(FAR struct usbhost_state_s *priv)
|
||||
static inline int usbhost_tfree(FAR struct usbhost_state_s *priv)
|
||||
{
|
||||
int result = OK;
|
||||
DEBUGASSERT(priv);
|
||||
|
||||
if (priv->tdbuffer)
|
||||
if (priv->tbuffer)
|
||||
{
|
||||
DEBUGASSERT(priv->drvr);
|
||||
result = DRVR_FREE(priv->drvr, priv->tdbuffer);
|
||||
priv->tdbuffer = NULL;
|
||||
priv->tdbuflen = 0;
|
||||
result = DRVR_FREE(priv->drvr, priv->tbuffer);
|
||||
priv->tbuffer = NULL;
|
||||
priv->tbuflen = 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -877,9 +876,7 @@ static FAR struct usbhost_class_s *usbhost_create(FAR struct usbhost_driver_s *d
|
||||
|
||||
priv->drvr = drvr;
|
||||
|
||||
/* NOTE: We do not yet know the geometry of the USB mass storage device */
|
||||
|
||||
/* Return the instance of the USB mass storage class */
|
||||
/* Return the instance of the USB class driver */
|
||||
|
||||
return &priv->class;
|
||||
}
|
||||
@@ -983,8 +980,8 @@ static int usbhost_disconnected(struct usbhost_class_s *class)
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
|
||||
/* Set an indication to any users of the mass storage device that the device
|
||||
* is no longer available.
|
||||
/* Set an indication to any users of the device that the device is no
|
||||
* longer available.
|
||||
*/
|
||||
|
||||
flags = irqsave();
|
||||
|
||||
@@ -121,7 +121,7 @@ struct usbhost_state_s
|
||||
|
||||
struct usbhost_driver_s *drvr;
|
||||
|
||||
/* The remainder of the fields are provide o the mass storage class */
|
||||
/* The remainder of the fields are provide to the mass storage class */
|
||||
|
||||
char sdchar; /* Character identifying the /dev/sd[n] device */
|
||||
volatile bool disconnected; /* TRUE: Device has been disconnected */
|
||||
@@ -130,8 +130,8 @@ struct usbhost_state_s
|
||||
uint32_t nblocks; /* Number of blocks on the USB mass storage device */
|
||||
sem_t exclsem; /* Used to maintain mutual exclusive access */
|
||||
struct work_s work; /* For interacting with the worker thread */
|
||||
FAR uint8_t *tdbuffer; /* The allocated transfer descriptor buffer */
|
||||
size_t tdbuflen; /* Size of the allocated transfer buffer */
|
||||
FAR uint8_t *tbuffer; /* The allocated transfer buffer */
|
||||
size_t tbuflen; /* Size of the allocated transfer buffer */
|
||||
usbhost_ep_t bulkin; /* Bulk IN endpoint */
|
||||
usbhost_ep_t bulkout; /* Bulk OUT endpoint */
|
||||
};
|
||||
@@ -210,8 +210,8 @@ static void usbhost_putbe32(uint8_t *dest, uint32_t val);
|
||||
|
||||
/* Transfer descriptor memory management */
|
||||
|
||||
static inline int usbhost_tdalloc(FAR struct usbhost_state_s *priv);
|
||||
static inline int usbhost_tdfree(FAR struct usbhost_state_s *priv);
|
||||
static inline int usbhost_talloc(FAR struct usbhost_state_s *priv);
|
||||
static inline int usbhost_tfree(FAR struct usbhost_state_s *priv);
|
||||
static FAR struct usbstrg_cbw_s *usbhost_cbwalloc(FAR struct usbhost_state_s *priv);
|
||||
|
||||
/* struct usbhost_registry_s methods */
|
||||
@@ -665,8 +665,8 @@ usbhost_writecbw(size_t startsector, uint16_t blocksize,
|
||||
|
||||
static inline int usbhost_maxlunreq(FAR struct usbhost_state_s *priv)
|
||||
{
|
||||
FAR struct usb_ctrlreq_s *req = (FAR struct usb_ctrlreq_s *)priv->tdbuffer;
|
||||
DEBUGASSERT(priv && priv->tdbuffer);
|
||||
FAR struct usb_ctrlreq_s *req = (FAR struct usb_ctrlreq_s *)priv->tbuffer;
|
||||
DEBUGASSERT(priv && priv->tbuffer);
|
||||
|
||||
/* Request maximum logical unit number. NOTE: On an IN transaction, The
|
||||
* req and buffer pointers passed to DRVR_CTRLIN may refer to the same
|
||||
@@ -678,7 +678,7 @@ static inline int usbhost_maxlunreq(FAR struct usbhost_state_s *priv)
|
||||
req->type = USB_DIR_IN|USB_REQ_TYPE_CLASS|USB_REQ_RECIPIENT_INTERFACE;
|
||||
req->req = USBSTRG_REQ_GETMAXLUN;
|
||||
usbhost_putle16(req->len, 1);
|
||||
return DRVR_CTRLIN(priv->drvr, req, priv->tdbuffer);
|
||||
return DRVR_CTRLIN(priv->drvr, req, priv->tbuffer);
|
||||
}
|
||||
|
||||
static inline int usbhost_testunitready(FAR struct usbhost_state_s *priv)
|
||||
@@ -705,10 +705,10 @@ static inline int usbhost_testunitready(FAR struct usbhost_state_s *priv)
|
||||
/* Receive the CSW */
|
||||
|
||||
result = DRVR_TRANSFER(priv->drvr, priv->bulkin,
|
||||
priv->tdbuffer, USBSTRG_CSW_SIZEOF);
|
||||
priv->tbuffer, USBSTRG_CSW_SIZEOF);
|
||||
if (result == OK)
|
||||
{
|
||||
usbhost_dumpcsw((FAR struct usbstrg_csw_s *)priv->tdbuffer);
|
||||
usbhost_dumpcsw((FAR struct usbstrg_csw_s *)priv->tbuffer);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@@ -738,16 +738,16 @@ static inline int usbhost_requestsense(FAR struct usbhost_state_s *priv)
|
||||
/* Receive the sense data response */
|
||||
|
||||
result = DRVR_TRANSFER(priv->drvr, priv->bulkin,
|
||||
priv->tdbuffer, SCSIRESP_FIXEDSENSEDATA_SIZEOF);
|
||||
priv->tbuffer, SCSIRESP_FIXEDSENSEDATA_SIZEOF);
|
||||
if (result == OK)
|
||||
{
|
||||
/* Receive the CSW */
|
||||
|
||||
result = DRVR_TRANSFER(priv->drvr, priv->bulkin,
|
||||
priv->tdbuffer, USBSTRG_CSW_SIZEOF);
|
||||
priv->tbuffer, USBSTRG_CSW_SIZEOF);
|
||||
if (result == OK)
|
||||
{
|
||||
usbhost_dumpcsw((FAR struct usbstrg_csw_s *)priv->tdbuffer);
|
||||
usbhost_dumpcsw((FAR struct usbstrg_csw_s *)priv->tbuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -780,22 +780,22 @@ static inline int usbhost_readcapacity(FAR struct usbhost_state_s *priv)
|
||||
/* Receive the read capacity CBW IN response */
|
||||
|
||||
result = DRVR_TRANSFER(priv->drvr, priv->bulkin,
|
||||
priv->tdbuffer, SCSIRESP_READCAPACITY10_SIZEOF);
|
||||
priv->tbuffer, SCSIRESP_READCAPACITY10_SIZEOF);
|
||||
if (result == OK)
|
||||
{
|
||||
/* Save the capacity information */
|
||||
|
||||
resp = (FAR struct scsiresp_readcapacity10_s *)priv->tdbuffer;
|
||||
resp = (FAR struct scsiresp_readcapacity10_s *)priv->tbuffer;
|
||||
priv->nblocks = usbhost_getbe32(resp->lba);
|
||||
priv->blocksize = usbhost_getbe32(resp->blklen);
|
||||
|
||||
/* Receive the CSW */
|
||||
|
||||
result = DRVR_TRANSFER(priv->drvr, priv->bulkin,
|
||||
priv->tdbuffer, USBSTRG_CSW_SIZEOF);
|
||||
priv->tbuffer, USBSTRG_CSW_SIZEOF);
|
||||
if (result == OK)
|
||||
{
|
||||
usbhost_dumpcsw((FAR struct usbstrg_csw_s *)priv->tdbuffer);
|
||||
usbhost_dumpcsw((FAR struct usbstrg_csw_s *)priv->tbuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -828,20 +828,20 @@ static inline int usbhost_inquiry(FAR struct usbhost_state_s *priv)
|
||||
/* Receive the CBW IN response */
|
||||
|
||||
result = DRVR_TRANSFER(priv->drvr, priv->bulkin,
|
||||
priv->tdbuffer, SCSIRESP_INQUIRY_SIZEOF);
|
||||
priv->tbuffer, SCSIRESP_INQUIRY_SIZEOF);
|
||||
if (result == OK)
|
||||
{
|
||||
/* TODO: If USB debug is enabled, dump the response data here */
|
||||
|
||||
resp = (FAR struct scsiresp_inquiry_s *)priv->tdbuffer;
|
||||
resp = (FAR struct scsiresp_inquiry_s *)priv->tbuffer;
|
||||
|
||||
/* Receive the CSW */
|
||||
|
||||
result = DRVR_TRANSFER(priv->drvr, priv->bulkin,
|
||||
priv->tdbuffer, USBSTRG_CSW_SIZEOF);
|
||||
priv->tbuffer, USBSTRG_CSW_SIZEOF);
|
||||
if (result == OK)
|
||||
{
|
||||
usbhost_dumpcsw((FAR struct usbstrg_csw_s *)priv->tdbuffer);
|
||||
usbhost_dumpcsw((FAR struct usbstrg_csw_s *)priv->tbuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -896,7 +896,7 @@ static void usbhost_destroy(FAR void *arg)
|
||||
|
||||
/* Free any transfer buffers */
|
||||
|
||||
usbhost_tdfree(priv);
|
||||
usbhost_tfree(priv);
|
||||
|
||||
/* Destroy the semaphores */
|
||||
|
||||
@@ -1153,7 +1153,7 @@ static inline int usbhost_initvolume(FAR struct usbhost_state_s *priv)
|
||||
|
||||
/* Set aside a transfer buffer for exclusive use by the mass storage driver */
|
||||
|
||||
ret = usbhost_tdalloc(priv);
|
||||
ret = usbhost_talloc(priv);
|
||||
if (ret != OK)
|
||||
{
|
||||
udbg("ERROR: Failed to allocate transfer buffer\n");
|
||||
@@ -1185,7 +1185,7 @@ static inline int usbhost_initvolume(FAR struct usbhost_state_s *priv)
|
||||
{
|
||||
/* Is the unit is ready */
|
||||
|
||||
csw = (FAR struct usbstrg_csw_s *)priv->tdbuffer;
|
||||
csw = (FAR struct usbstrg_csw_s *)priv->tbuffer;
|
||||
if (csw->status == 0)
|
||||
{
|
||||
/* Yes... break out of the loop */
|
||||
@@ -1221,7 +1221,7 @@ static inline int usbhost_initvolume(FAR struct usbhost_state_s *priv)
|
||||
{
|
||||
/* Check the CSW for errors */
|
||||
|
||||
csw = (FAR struct usbstrg_csw_s *)priv->tdbuffer;
|
||||
csw = (FAR struct usbstrg_csw_s *)priv->tbuffer;
|
||||
if (csw->status != 0)
|
||||
{
|
||||
udbg("ERROR: CSW status error: %d\n", csw->status);
|
||||
@@ -1242,7 +1242,7 @@ static inline int usbhost_initvolume(FAR struct usbhost_state_s *priv)
|
||||
{
|
||||
/* Check the CSW for errors */
|
||||
|
||||
csw = (FAR struct usbstrg_csw_s *)priv->tdbuffer;
|
||||
csw = (FAR struct usbstrg_csw_s *)priv->tbuffer;
|
||||
if (csw->status != 0)
|
||||
{
|
||||
udbg("ERROR: CSW status error: %d\n", csw->status);
|
||||
@@ -1478,10 +1478,10 @@ static void usbhost_putbe32(uint8_t *dest, uint32_t val)
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: usbhost_tdalloc
|
||||
* Name: usbhost_talloc
|
||||
*
|
||||
* Description:
|
||||
* Allocate transfer descriptor memory.
|
||||
* Allocate transfer buffer memory.
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - A reference to the class instance.
|
||||
@@ -1492,17 +1492,17 @@ static void usbhost_putbe32(uint8_t *dest, uint32_t val)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline int usbhost_tdalloc(FAR struct usbhost_state_s *priv)
|
||||
static inline int usbhost_talloc(FAR struct usbhost_state_s *priv)
|
||||
{
|
||||
DEBUGASSERT(priv && priv->tdbuffer == NULL);
|
||||
return DRVR_ALLOC(priv->drvr, &priv->tdbuffer, &priv->tdbuflen);
|
||||
DEBUGASSERT(priv && priv->tbuffer == NULL);
|
||||
return DRVR_ALLOC(priv->drvr, &priv->tbuffer, &priv->tbuflen);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: usbhost_tdfree
|
||||
* Name: usbhost_tfree
|
||||
*
|
||||
* Description:
|
||||
* Free transfer descriptor memory.
|
||||
* Free transfer buffer memory.
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - A reference to the class instance.
|
||||
@@ -1513,17 +1513,17 @@ static inline int usbhost_tdalloc(FAR struct usbhost_state_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline int usbhost_tdfree(FAR struct usbhost_state_s *priv)
|
||||
static inline int usbhost_tfree(FAR struct usbhost_state_s *priv)
|
||||
{
|
||||
int result = OK;
|
||||
DEBUGASSERT(priv);
|
||||
|
||||
if (priv->tdbuffer)
|
||||
if (priv->tbuffer)
|
||||
{
|
||||
DEBUGASSERT(priv->drvr);
|
||||
result = DRVR_FREE(priv->drvr, priv->tdbuffer);
|
||||
priv->tdbuffer = NULL;
|
||||
priv->tdbuflen = 0;
|
||||
result = DRVR_FREE(priv->drvr, priv->tbuffer);
|
||||
priv->tbuffer = NULL;
|
||||
priv->tbuflen = 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -1547,11 +1547,11 @@ static FAR struct usbstrg_cbw_s *usbhost_cbwalloc(FAR struct usbhost_state_s *pr
|
||||
{
|
||||
FAR struct usbstrg_cbw_s *cbw = NULL;
|
||||
|
||||
DEBUGASSERT(priv->tdbuffer && priv->tdbuflen >= sizeof(struct usbstrg_cbw_s))
|
||||
DEBUGASSERT(priv->tbuffer && priv->tbuflen >= sizeof(struct usbstrg_cbw_s))
|
||||
|
||||
/* Intialize the CBW sructure */
|
||||
|
||||
cbw = (FAR struct usbstrg_cbw_s *)priv->tdbuffer;
|
||||
cbw = (FAR struct usbstrg_cbw_s *)priv->tbuffer;
|
||||
memset(cbw, 0, sizeof(struct usbstrg_cbw_s));
|
||||
usbhost_putle32(cbw->signature, USBSTRG_CBW_SIGNATURE);
|
||||
return cbw;
|
||||
@@ -1943,14 +1943,14 @@ static ssize_t usbhost_read(FAR struct inode *inode, unsigned char *buffer,
|
||||
/* Receive the CSW */
|
||||
|
||||
result = DRVR_TRANSFER(priv->drvr, priv->bulkin,
|
||||
priv->tdbuffer, USBSTRG_CSW_SIZEOF);
|
||||
priv->tbuffer, USBSTRG_CSW_SIZEOF);
|
||||
if (result == OK)
|
||||
{
|
||||
FAR struct usbstrg_csw_s *csw;
|
||||
|
||||
/* Check the CSW status */
|
||||
|
||||
csw = (FAR struct usbstrg_csw_s *)priv->tdbuffer;
|
||||
csw = (FAR struct usbstrg_csw_s *)priv->tbuffer;
|
||||
if (csw->status == 0)
|
||||
{
|
||||
ret = nsectors;
|
||||
@@ -2035,14 +2035,14 @@ static ssize_t usbhost_write(FAR struct inode *inode, const unsigned char *buffe
|
||||
/* Receive the CSW */
|
||||
|
||||
result = DRVR_TRANSFER(priv->drvr, priv->bulkin,
|
||||
priv->tdbuffer, USBSTRG_CSW_SIZEOF);
|
||||
priv->tbuffer, USBSTRG_CSW_SIZEOF);
|
||||
if (result == OK)
|
||||
{
|
||||
FAR struct usbstrg_csw_s *csw;
|
||||
|
||||
/* Check the CSW status */
|
||||
|
||||
csw = (FAR struct usbstrg_csw_s *)priv->tdbuffer;
|
||||
csw = (FAR struct usbstrg_csw_s *)priv->tbuffer;
|
||||
if (csw->status == 0)
|
||||
{
|
||||
ret = nsectors;
|
||||
|
||||
@@ -150,7 +150,7 @@ int user_start(int argc, char *argv[])
|
||||
/* First, register all of the USB host HID keyboard class driver */
|
||||
|
||||
printf("user_start: Register class drivers\n");
|
||||
ret = usbhost_storageinit();
|
||||
ret = usbhost_kbdinit();
|
||||
if (ret != OK)
|
||||
{
|
||||
printf("user_start: Failed to register the KBD class\n");
|
||||
|
||||
Reference in New Issue
Block a user