Commit 7f9e05e1 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

greybus: es1: functionally complete

Have only tested USB device add/remove, the urbs seem to all be queued
up, no data has been tested to flow through yet.

Odds are the hc interface will have to change, but this is a good first
start to build on.
parent a1dc62b0
...@@ -14,7 +14,8 @@ ...@@ -14,7 +14,8 @@
#include "svc_msg.h" #include "svc_msg.h"
static const struct usb_device_id id_table[] = { static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0xffff, 0x0001) }, // FIXME /* Made up numbers for the SVC USB Bridge in ES1 */
{ USB_DEVICE(0xffff, 0x0001) },
{ }, { },
}; };
MODULE_DEVICE_TABLE(usb, id_table); MODULE_DEVICE_TABLE(usb, id_table);
...@@ -31,23 +32,42 @@ MODULE_DEVICE_TABLE(usb, id_table); ...@@ -31,23 +32,42 @@ MODULE_DEVICE_TABLE(usb, id_table);
*/ */
#define NUM_CPORT_OUT_URB 8 #define NUM_CPORT_OUT_URB 8
/**
* es1_ap_dev - ES1 USB Bridge to AP structure
* @usb_dev: pointer to the USB device we are.
* @usb_intf: pointer to the USB interface we are bound to.
* @hd: pointer to our greybus_host_device structure
* @control_endpoint: endpoint to send data to SVC
* @svc_endpoint: endpoint for SVC data in
* @cport_in_endpoint: bulk in endpoint for CPort data
* @cport-out_endpoint: bulk out endpoint for CPort data
* @svc_buffer: buffer for SVC messages coming in on @svc_endpoint
* @svc_urb: urb for SVC messages coming in on @svc_endpoint
* @cport_in_urb: array of urbs for the CPort in messages
* @cport_in_buffer: array of buffers for the @cport_in_urb urbs
* @cport_out_urb: array of urbs for the CPort out messages
* @cport_out_urb_busy: array of flags to see if the @cport_out_urb is busy or
* not.
* @cport_out_urb_lock: locks the @cport_out_urb_busy "list"
*/
struct es1_ap_dev { struct es1_ap_dev {
struct usb_device *usb_dev; struct usb_device *usb_dev;
struct usb_interface *usb_intf; struct usb_interface *usb_intf;
struct greybus_host_device *hd; struct greybus_host_device *hd;
__u8 control_endpoint; /* endpoint to send data to SVC */ __u8 control_endpoint;
__u8 svc_endpoint; /* endpoint for SVC data */ __u8 svc_endpoint;
__u8 cport_in_endpoint; /* bulk in for CPort data */ __u8 cport_in_endpoint;
__u8 cport_out_endpoint; /* bulk out for CPort data */ __u8 cport_out_endpoint;
u8 *svc_buffer; /* buffer for SVC messages coming in */
struct urb *svc_urb; /* urb for SVC messages coming in */ u8 *svc_buffer;
struct urb *cport_in_urb[NUM_CPORT_IN_URB]; /* CPort IN urbs */ struct urb *svc_urb;
u8 *cport_in_buffer[NUM_CPORT_IN_URB]; /* CPort IN buffers */
struct urb *cport_out_urb[NUM_CPORT_OUT_URB]; /* CPort OUT urbs */ struct urb *cport_in_urb[NUM_CPORT_IN_URB];
bool cport_out_urb_busy[NUM_CPORT_OUT_URB]; /* CPort OUT urb busy marker */ u8 *cport_in_buffer[NUM_CPORT_IN_URB];
spinlock_t cport_out_urb_lock; /* locks list of cport out urbs */ struct urb *cport_out_urb[NUM_CPORT_OUT_URB];
bool cport_out_urb_busy[NUM_CPORT_OUT_URB];
spinlock_t cport_out_urb_lock;
}; };
static inline struct es1_ap_dev *hd_to_es1(struct greybus_host_device *hd) static inline struct es1_ap_dev *hd_to_es1(struct greybus_host_device *hd)
...@@ -291,6 +311,7 @@ static void cport_out_callback(struct urb *urb) ...@@ -291,6 +311,7 @@ static void cport_out_callback(struct urb *urb)
int status = urb->status; int status = urb->status;
int i; int i;
/* do we care about errors going back up? */
switch (status) { switch (status) {
case 0: case 0:
break; break;
...@@ -308,15 +329,13 @@ static void cport_out_callback(struct urb *urb) ...@@ -308,15 +329,13 @@ static void cport_out_callback(struct urb *urb)
goto exit; goto exit;
} }
// FIXME - do we care about errors going back up?
/* Tell the core the gbuf is properly sent */ /* Tell the core the gbuf is properly sent */
greybus_gbuf_finished(gbuf); greybus_gbuf_finished(gbuf);
exit: exit:
/* /*
* See if this was an urb in our pool, if so mark it "free", otherwise we * See if this was an urb in our pool, if so mark it "free", otherwise
* need to free it ourselves. * we need to free it ourselves.
*/ */
spin_lock_irqsave(&es1->cport_out_urb_lock, flags); spin_lock_irqsave(&es1->cport_out_urb_lock, flags);
for (i = 0; i < NUM_CPORT_OUT_URB; ++i) { for (i = 0; i < NUM_CPORT_OUT_URB; ++i) {
...@@ -327,9 +346,9 @@ static void cport_out_callback(struct urb *urb) ...@@ -327,9 +346,9 @@ static void cport_out_callback(struct urb *urb)
} }
} }
spin_unlock_irqrestore(&es1->cport_out_urb_lock, flags); spin_unlock_irqrestore(&es1->cport_out_urb_lock, flags);
if (urb)
usb_free_urb(urb);
/* If urb is not NULL, then we need to free this urb */
usb_free_urb(urb);
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment