#include "avr_usb.h"
-static void vhci_usb_attach_hook(struct avr_irq_t * irq, uint32_t value, void * param)
+static void
+vhci_usb_attach_hook(
+ struct avr_irq_t * irq,
+ uint32_t value,
+ void * param)
{
- struct vhci_usb_t * p = (struct vhci_usb_t*)param;
- p->attached=!!value;
- printf("avr attached: %d\n",p->attached);
+ struct vhci_usb_t * p = (struct vhci_usb_t*) param;
+ p->attached = !!value;
+ printf("avr attached: %d\n", p->attached);
}
struct usbsetup {
uint8_t epsz;
};
-char * setuprequests[] = {"GET_STATUS","CLEAR_FEAT","","SET_FEAT","","SET_ADDR","GET_DESCR","SET_DESCR","GET_CONF","SET_CONF"};
-
-static int control_read(struct vhci_usb_t * p, struct _ep * ep, uint8_t reqtype, uint8_t req, uint16_t wValue, uint16_t wIndex, uint16_t wLength, uint8_t * data)
+char * setuprequests[] =
+ { "GET_STATUS", "CLEAR_FEAT", "", "SET_FEAT", "", "SET_ADDR", "GET_DESCR",
+ "SET_DESCR", "GET_CONF", "SET_CONF" };
+
+static int
+control_read(
+ struct vhci_usb_t * p,
+ struct _ep * ep,
+ uint8_t reqtype,
+ uint8_t req,
+ uint16_t wValue,
+ uint16_t wIndex,
+ uint16_t wLength,
+ uint8_t * data)
{
assert(reqtype&0x80);
int ret;
- struct usbsetup buf = {reqtype,req,wValue,wIndex,wLength};
- struct avr_io_usb pkt = {ep->epnum,sizeof (struct usbsetup), (char*)&buf};
+ struct usbsetup buf =
+ { reqtype, req, wValue, wIndex, wLength };
+ struct avr_io_usb pkt =
+ { ep->epnum, sizeof(struct usbsetup), (uint8_t*) &buf };
avr_ioctl(p->avr, AVR_IOCTL_USB_SETUP, &pkt);
pkt.sz = wLength;
pkt.buf = data;
- while ( wLength ) {
+ while (wLength) {
usleep(1000);
ret = avr_ioctl(p->avr, AVR_IOCTL_USB_READ, &pkt);
- if (ret==AVR_IOCTL_USB_NAK) {printf(" NAK\n");usleep(50000); continue; }
- if (ret==AVR_IOCTL_USB_STALL) {printf(" STALL\n"); return ret;}
+ if (ret == AVR_IOCTL_USB_NAK) {
+ printf(" NAK\n");
+ usleep(50000);
+ continue;
+ }
+ if (ret == AVR_IOCTL_USB_STALL) {
+ printf(" STALL\n");
+ return ret;
+ }
assert(ret==0);
- pkt.buf+=pkt.sz;
- if (ep->epsz != pkt.sz) break;
- wLength-=pkt.sz;
+ pkt.buf += pkt.sz;
+ if (ep->epsz != pkt.sz)
+ break;
+ wLength -= pkt.sz;
pkt.sz = wLength;
}
- wLength=pkt.buf-data;
+ wLength = pkt.buf - data;
usleep(1000);
- pkt.sz=0;
- while ( (ret = avr_ioctl(p->avr, AVR_IOCTL_USB_WRITE, &pkt)) == AVR_IOCTL_USB_NAK) {
+ pkt.sz = 0;
+ while ((ret = avr_ioctl(p->avr, AVR_IOCTL_USB_WRITE, &pkt))
+ == AVR_IOCTL_USB_NAK) {
usleep(50000);
}
assert(ret==0);
return wLength;
}
-static int control_write(struct vhci_usb_t * p, struct _ep * ep, uint8_t reqtype, uint8_t req, uint16_t wValue, uint16_t wIndex, uint16_t wLength, uint8_t * data)
+static int
+control_write(
+ struct vhci_usb_t * p,
+ struct _ep * ep,
+ uint8_t reqtype,
+ uint8_t req,
+ uint16_t wValue,
+ uint16_t wIndex,
+ uint16_t wLength,
+ uint8_t * data)
{
assert((reqtype&0x80)==0);
int ret;
- struct usbsetup buf = {reqtype,req,wValue,wIndex,wLength};
- struct avr_io_usb pkt = {ep->epnum,sizeof (struct usbsetup), (char*)&buf};
+ struct usbsetup buf =
+ { reqtype, req, wValue, wIndex, wLength };
+ struct avr_io_usb pkt =
+ { ep->epnum, sizeof(struct usbsetup), (uint8_t*) &buf };
avr_ioctl(p->avr, AVR_IOCTL_USB_SETUP, &pkt);
usleep(10000);
- if (wLength>0) {
- pkt.sz = (wLength>ep->epsz ? ep->epsz : wLength);
+ if (wLength > 0) {
+ pkt.sz = (wLength > ep->epsz ? ep->epsz : wLength);
pkt.buf = data;
- while ( ret = avr_ioctl(p->avr, AVR_IOCTL_USB_WRITE, &pkt)) {
- if (ret==AVR_IOCTL_USB_NAK) {usleep(50000); continue; }
- if (ret==AVR_IOCTL_USB_STALL) {printf(" STALL\n"); return ret;}
+ while ((ret = avr_ioctl(p->avr, AVR_IOCTL_USB_WRITE, &pkt)) != 0) {
+ if (ret == AVR_IOCTL_USB_NAK) {
+ usleep(50000);
+ continue;
+ }
+ if (ret == AVR_IOCTL_USB_STALL) {
+ printf(" STALL\n");
+ return ret;
+ }
assert(ret==0);
- if (pkt.sz != ep->epsz) break;
- pkt.buf+=pkt.sz;
- wLength-=pkt.sz;
- pkt.sz = (wLength>ep->epsz ? ep->epsz : wLength);
+ if (pkt.sz != ep->epsz)
+ break;
+ pkt.buf += pkt.sz;
+ wLength -= pkt.sz;
+ pkt.sz = (wLength > ep->epsz ? ep->epsz : wLength);
}
}
- pkt.sz=0;
- while ( (ret = avr_ioctl(p->avr, AVR_IOCTL_USB_READ, &pkt)) == AVR_IOCTL_USB_NAK) {
+ pkt.sz = 0;
+ while ((ret = avr_ioctl(p->avr, AVR_IOCTL_USB_READ, &pkt))
+ == AVR_IOCTL_USB_NAK) {
usleep(50000);
}
return ret;
}
-
-static void handle_status_change(struct vhci_usb_t * p, struct usb_vhci_port_stat*prev, struct usb_vhci_port_stat*curr)
+static void
+handle_status_change(
+ struct vhci_usb_t * p,
+ struct usb_vhci_port_stat*prev,
+ struct usb_vhci_port_stat*curr)
{
- if (~prev->status & USB_VHCI_PORT_STAT_POWER && curr->status & USB_VHCI_PORT_STAT_POWER) {
- avr_ioctl(p->avr, AVR_IOCTL_USB_VBUS, (void*)1);
+ if (~prev->status & USB_VHCI_PORT_STAT_POWER
+ && curr->status & USB_VHCI_PORT_STAT_POWER) {
+ avr_ioctl(p->avr, AVR_IOCTL_USB_VBUS, (void*) 1);
if (p->attached) {
- if (usb_vhci_port_connect(p->fd, 1, USB_VHCI_DATA_RATE_FULL) <0) {
+ if (usb_vhci_port_connect(p->fd, 1, USB_VHCI_DATA_RATE_FULL) < 0) {
perror("port_connect");
abort();
}
}
}
- if (prev->status & USB_VHCI_PORT_STAT_POWER && ~curr->status & USB_VHCI_PORT_STAT_POWER)
+ if (prev->status & USB_VHCI_PORT_STAT_POWER
+ && ~curr->status & USB_VHCI_PORT_STAT_POWER)
avr_ioctl(p->avr, AVR_IOCTL_USB_VBUS, 0);
- if (curr->change & USB_VHCI_PORT_STAT_C_RESET &&
- ~curr->status & USB_VHCI_PORT_STAT_RESET &&
- curr->status & USB_VHCI_PORT_STAT_ENABLE) {
+ if (curr->change & USB_VHCI_PORT_STAT_C_RESET
+ && ~curr->status & USB_VHCI_PORT_STAT_RESET
+ && curr->status & USB_VHCI_PORT_STAT_ENABLE) {
// printf("END OF RESET\n");
}
- if (~prev->status & USB_VHCI_PORT_STAT_RESET &&
- curr->status & USB_VHCI_PORT_STAT_RESET) {
+ if (~prev->status & USB_VHCI_PORT_STAT_RESET
+ && curr->status & USB_VHCI_PORT_STAT_RESET) {
avr_ioctl(p->avr, AVR_IOCTL_USB_RESET, NULL);
usleep(50000);
if (curr->status & USB_VHCI_PORT_STAT_CONNECTION) {
- if (usb_vhci_port_reset_done(p->fd,1,1)<0) {
+ if (usb_vhci_port_reset_done(p->fd, 1, 1) < 0) {
perror("reset_done");
abort();
}
}
}
- if (~prev->flags & USB_VHCI_PORT_STAT_FLAG_RESUMING &&
- curr->flags & USB_VHCI_PORT_STAT_FLAG_RESUMING) {
+ if (~prev->flags & USB_VHCI_PORT_STAT_FLAG_RESUMING
+ && curr->flags & USB_VHCI_PORT_STAT_FLAG_RESUMING) {
printf("port resuming\n");
if (curr->status & USB_VHCI_PORT_STAT_CONNECTION) {
printf(" completing\n");
- if (usb_vhci_port_resumed(p->fd,1)<0) {
+ if (usb_vhci_port_resumed(p->fd, 1) < 0) {
perror("resumed");
abort();
}
}
}
- if (~prev->status & USB_VHCI_PORT_STAT_SUSPEND &&
- curr->status & USB_VHCI_PORT_STAT_SUSPEND)
+ if (~prev->status & USB_VHCI_PORT_STAT_SUSPEND
+ && curr->status & USB_VHCI_PORT_STAT_SUSPEND)
printf("port suspedning\n");
- if (prev->status & USB_VHCI_PORT_STAT_ENABLE &&
- ~curr->status & USB_VHCI_PORT_STAT_ENABLE)
+ if (prev->status & USB_VHCI_PORT_STAT_ENABLE
+ && ~curr->status & USB_VHCI_PORT_STAT_ENABLE)
printf("port disabled\n");
*prev = *curr;
}
-static int get_ep0_size(struct vhci_usb_t * p)
+static int
+get_ep0_size(
+ struct vhci_usb_t * p)
{
- struct _ep ep0 = {0,8};
+ struct _ep ep0 =
+ { 0, 8 };
uint8_t data[8];
- int res = control_read(p, &ep0, 0x80, 6, 1<<8,0,8,data);
+ int res = control_read(p, &ep0, 0x80, 6, 1 << 8, 0, 8, data);
assert(res==8);
return data[7];
}
-static void handle_ep0_control(struct vhci_usb_t * p, struct _ep * ep0, struct usb_vhci_urb * urb)
+static void
+handle_ep0_control(
+ struct vhci_usb_t * p,
+ struct _ep * ep0,
+ struct usb_vhci_urb * urb)
{
int res;
if (urb->bmRequestType &0x80) {
urb->status = USB_VHCI_STATUS_SUCCESS;
}
-
-static void * vhci_usb_thread(void * param)
+static void *
+vhci_usb_thread(
+ void * param)
{
- struct vhci_usb_t * p = (struct vhci_usb_t*)param;
- struct _ep ep0 = {0,0};
+ struct vhci_usb_t * p = (struct vhci_usb_t*) param;
+ struct _ep ep0 =
+ { 0, 0 };
struct usb_vhci_port_stat port_status;
- int id,busnum;char*busid;
+ int id, busnum;
+ char*busid;
p->fd = usb_vhci_open(1, &id, &busnum, &busid);
-
- if (p->fd<0) {
+ if (p->fd < 0) {
perror("open vhci failed");
printf("driver loaded, and access bits ok?\n");
abort();
}
- printf("Created virtual usb host with 1 port at %s (bus# %d)\n",busid,busnum);
- memset(&port_status,0,sizeof port_status);
+ printf("Created virtual usb host with 1 port at %s (bus# %d)\n", busid,
+ busnum);
+ memset(&port_status, 0, sizeof port_status);
- bool avrattached=false;
+ bool avrattached = false;
- for(unsigned cycle=0;;cycle++) {
+ for (unsigned cycle = 0;; cycle++) {
struct usb_vhci_work wrk;
int res = usb_vhci_fetch_work(p->fd, &wrk);
if (p->attached != avrattached) {
if (p->attached && port_status.status & USB_VHCI_PORT_STAT_POWER) {
- if (usb_vhci_port_connect(p->fd, 1, USB_VHCI_DATA_RATE_FULL) <0) {
+ if (usb_vhci_port_connect(p->fd, 1, USB_VHCI_DATA_RATE_FULL)
+ < 0) {
perror("port_connect");
abort();
}
}
if (!p->attached) {
- ep0.epsz=0;
+ ep0.epsz = 0;
//disconnect
}
- avrattached=p->attached;
+ avrattached = p->attached;
}
- if ( res<0 ) {
- if( errno == ETIMEDOUT || errno == EINTR || errno == ENODATA) continue;
+ if (res < 0) {
+ if (errno == ETIMEDOUT || errno == EINTR || errno == ENODATA)
+ continue;
perror("fetch work failed");
abort();
}
- switch(wrk.type) {
- case USB_VHCI_WORK_TYPE_PORT_STAT:
- handle_status_change(p, &port_status, &wrk.work.port_stat);
- break;
- case USB_VHCI_WORK_TYPE_PROCESS_URB:
- if (!ep0.epsz)
- ep0.epsz = get_ep0_size(p);
-
- wrk.work.urb.buffer=0;
- wrk.work.urb.iso_packets=0;
- if (wrk.work.urb.buffer_length)
- wrk.work.urb.buffer = malloc(wrk.work.urb.buffer_length);
- if (wrk.work.urb.packet_count)
- wrk.work.urb.iso_packets = malloc(wrk.work.urb.packet_count * sizeof (struct usb_vhci_iso_packet));
- if (res) {
- if (usb_vhci_fetch_data(p->fd, &wrk.work.urb)<0) {
- if (errno != ECANCELED) perror("fetch_data");
- free(wrk.work.urb.buffer);
- free(wrk.work.urb.iso_packets);
- usb_vhci_giveback(p->fd, &wrk.work.urb);
- break;
+ switch (wrk.type) {
+ case USB_VHCI_WORK_TYPE_PORT_STAT:
+ handle_status_change(p, &port_status, &wrk.work.port_stat);
+ break;
+ case USB_VHCI_WORK_TYPE_PROCESS_URB:
+ if (!ep0.epsz)
+ ep0.epsz = get_ep0_size(p);
+
+ wrk.work.urb.buffer = 0;
+ wrk.work.urb.iso_packets = 0;
+ if (wrk.work.urb.buffer_length)
+ wrk.work.urb.buffer = malloc(wrk.work.urb.buffer_length);
+ if (wrk.work.urb.packet_count)
+ wrk.work.urb.iso_packets = malloc(
+ wrk.work.urb.packet_count
+ * sizeof(struct usb_vhci_iso_packet));
+ if (res) {
+ if (usb_vhci_fetch_data(p->fd, &wrk.work.urb) < 0) {
+ if (errno != ECANCELED)
+ perror("fetch_data");
+ free(wrk.work.urb.buffer);
+ free(wrk.work.urb.iso_packets);
+ usb_vhci_giveback(p->fd, &wrk.work.urb);
+ break;
+ }
}
- }
- if(usb_vhci_is_control(wrk.work.urb.type) && !(wrk.work.urb.epadr & 0x7f)) {
- handle_ep0_control(p, &ep0, &wrk.work.urb);
+ if (usb_vhci_is_control(wrk.work.urb.type)
+ && !(wrk.work.urb.epadr & 0x7f)) {
+ handle_ep0_control(p, &ep0, &wrk.work.urb);
- } else {
- struct avr_io_usb pkt = {wrk.work.urb.epadr, wrk.work.urb.buffer_actual, wrk.work.urb.buffer};
+ } else {
+ struct avr_io_usb pkt =
+ { wrk.work.urb.epadr, wrk.work.urb.buffer_actual,
+ wrk.work.urb.buffer };
if (usb_vhci_is_out(wrk.work.urb.epadr))
- res=avr_ioctl(p->avr, AVR_IOCTL_USB_WRITE, &pkt);
- else {
+ res = avr_ioctl(p->avr, AVR_IOCTL_USB_WRITE, &pkt);
+ else {
pkt.sz = wrk.work.urb.buffer_length;
- res=avr_ioctl(p->avr, AVR_IOCTL_USB_READ, &pkt);
- wrk.work.urb.buffer_actual=pkt.sz;
+ res = avr_ioctl(p->avr, AVR_IOCTL_USB_READ, &pkt);
+ wrk.work.urb.buffer_actual = pkt.sz;
}
- if (res==AVR_IOCTL_USB_STALL)
- wrk.work.urb.status = USB_VHCI_STATUS_STALL;
- else if (res==AVR_IOCTL_USB_NAK)
- wrk.work.urb.status = USB_VHCI_STATUS_TIMEDOUT;
- else
- wrk.work.urb.status = USB_VHCI_STATUS_SUCCESS;
- }
- if (usb_vhci_giveback(p->fd, &wrk.work.urb)<0)
- perror("giveback");
- free(wrk.work.urb.buffer);
- free(wrk.work.urb.iso_packets);
- break;
- case USB_VHCI_WORK_TYPE_CANCEL_URB:
- printf("cancel urb\n");
- break;
- default:
- printf("illegal work type\n");
- abort();
+ if (res == AVR_IOCTL_USB_STALL)
+ wrk.work.urb.status = USB_VHCI_STATUS_STALL;
+ else if (res == AVR_IOCTL_USB_NAK)
+ wrk.work.urb.status = USB_VHCI_STATUS_TIMEDOUT;
+ else
+ wrk.work.urb.status = USB_VHCI_STATUS_SUCCESS;
+ }
+ if (usb_vhci_giveback(p->fd, &wrk.work.urb) < 0)
+ perror("giveback");
+ free(wrk.work.urb.buffer);
+ free(wrk.work.urb.iso_packets);
+ break;
+ case USB_VHCI_WORK_TYPE_CANCEL_URB:
+ printf("cancel urb\n");
+ break;
+ default:
+ printf("illegal work type\n");
+ abort();
}
}
}
-
-void vhci_usb_init(struct avr_t * avr, struct vhci_usb_t * p)
+void
+vhci_usb_init(
+ struct avr_t * avr,
+ struct vhci_usb_t * p)
{
p->avr = avr;
pthread_t thread;
}
-void vhci_usb_connect(struct vhci_usb_t * p, char uart)
+void
+vhci_usb_connect(
+ struct vhci_usb_t * p,
+ char uart)
{
- avr_irq_t * t = avr_io_getirq(p->avr, AVR_IOCTL_USB_GETIRQ(), USB_IRQ_ATTACH);
+ avr_irq_t * t = avr_io_getirq(p->avr, AVR_IOCTL_USB_GETIRQ(),
+ USB_IRQ_ATTACH);
avr_irq_register_notify(t, vhci_usb_attach_hook, p);
}