diff options
Diffstat (limited to 'drivers/staging/ozwpan')
-rw-r--r-- | drivers/staging/ozwpan/ozcdev.c | 14 | ||||
-rw-r--r-- | drivers/staging/ozwpan/ozevent.c | 6 | ||||
-rw-r--r-- | drivers/staging/ozwpan/ozhcd.c | 104 | ||||
-rw-r--r-- | drivers/staging/ozwpan/ozmain.c | 2 | ||||
-rw-r--r-- | drivers/staging/ozwpan/ozpd.c | 11 | ||||
-rw-r--r-- | drivers/staging/ozwpan/ozpd.h | 1 | ||||
-rw-r--r-- | drivers/staging/ozwpan/ozproto.c | 13 | ||||
-rw-r--r-- | drivers/staging/ozwpan/ozproto.h | 8 | ||||
-rw-r--r-- | drivers/staging/ozwpan/ozprotocol.h | 6 |
9 files changed, 119 insertions, 46 deletions
diff --git a/drivers/staging/ozwpan/ozcdev.c b/drivers/staging/ozwpan/ozcdev.c index 758ce0a..64913ae 100644 --- a/drivers/staging/ozwpan/ozcdev.c +++ b/drivers/staging/ozwpan/ozcdev.c @@ -104,10 +104,10 @@ ssize_t oz_cdev_read(struct file *filp, char __user *buf, size_t count, if (pd) oz_pd_get(pd); spin_unlock_bh(&g_cdev.lock); - if (pd == 0) + if (pd == NULL) return -1; ctx = oz_cdev_claim_ctx(pd); - if (ctx == 0) + if (ctx == NULL) goto out2; n = ctx->rd_in - ctx->rd_out; if (n < 0) @@ -157,11 +157,11 @@ ssize_t oz_cdev_write(struct file *filp, const char __user *buf, size_t count, if (pd) oz_pd_get(pd); spin_unlock_bh(&g_cdev.lock); - if (pd == 0) + if (pd == NULL) return -1; eb = &pd->elt_buff; ei = oz_elt_info_alloc(eb); - if (ei == 0) { + if (ei == NULL) { count = 0; goto out; } @@ -410,7 +410,7 @@ int oz_cdev_start(struct oz_pd *pd, int resume) return 0; } ctx = kzalloc(sizeof(struct oz_serial_ctx), GFP_ATOMIC); - if (ctx == 0) + if (ctx == NULL) return -ENOMEM; atomic_set(&ctx->ref_count, 1); ctx->tx_seq_num = 1; @@ -424,7 +424,7 @@ int oz_cdev_start(struct oz_pd *pd, int resume) spin_unlock_bh(&pd->app_lock[OZ_APPID_SERIAL-1]); } spin_lock(&g_cdev.lock); - if ((g_cdev.active_pd == 0) && + if ((g_cdev.active_pd == NULL) && (memcmp(pd->mac_addr, g_cdev.active_addr, ETH_ALEN) == 0)) { oz_pd_get(pd); g_cdev.active_pd = pd; @@ -477,7 +477,7 @@ void oz_cdev_rx(struct oz_pd *pd, struct oz_elt *elt) int ix; ctx = oz_cdev_claim_ctx(pd); - if (ctx == 0) { + if (ctx == NULL) { oz_trace("Cannot claim serial context.\n"); return; } diff --git a/drivers/staging/ozwpan/ozevent.c b/drivers/staging/ozwpan/ozevent.c index 7f66b4f..a48498b 100644 --- a/drivers/staging/ozwpan/ozevent.c +++ b/drivers/staging/ozwpan/ozevent.c @@ -14,7 +14,7 @@ #include "ozappif.h" /*------------------------------------------------------------------------------ * Although the event mask is logically part of the oz_evtdev structure, it is - * needed outside of this file so define it seperately to avoid the need to + * needed outside of this file so define it separately to avoid the need to * export definition of struct oz_evtdev. */ u32 g_evt_mask; @@ -39,8 +39,8 @@ static struct oz_evtdev g_evtdev; */ void oz_event_init(void) { - /* Because g_evtdev is static external all fields initally zero so no - * need to reinitialised those. + /* Because g_evtdev is static external all fields initially zero so no + * need to reinitialized those. */ oz_trace("Event tracing initialized\n"); spin_lock_init(&g_evtdev.lock); diff --git a/drivers/staging/ozwpan/ozhcd.c b/drivers/staging/ozwpan/ozhcd.c index 251f07c..2e087ac 100644 --- a/drivers/staging/ozwpan/ozhcd.c +++ b/drivers/staging/ozwpan/ozhcd.c @@ -417,6 +417,44 @@ static void oz_ep_free(struct oz_port *port, struct oz_endpoint *ep) /*------------------------------------------------------------------------------ * Context: softirq */ +void oz_complete_buffered_urb(struct oz_port *port, struct oz_endpoint *ep, + struct urb *urb) +{ + u8 data_len, available_space, copy_len; + + memcpy(&data_len, &ep->buffer[ep->out_ix], sizeof(u8)); + if (data_len <= urb->transfer_buffer_length) + available_space = data_len; + else + available_space = urb->transfer_buffer_length; + + if (++ep->out_ix == ep->buffer_size) + ep->out_ix = 0; + copy_len = ep->buffer_size - ep->out_ix; + if (copy_len >= available_space) + copy_len = available_space; + memcpy(urb->transfer_buffer, &ep->buffer[ep->out_ix], copy_len); + + if (copy_len < available_space) { + memcpy((urb->transfer_buffer + copy_len), ep->buffer, + (available_space - copy_len)); + ep->out_ix = available_space - copy_len; + } else { + ep->out_ix += copy_len; + } + urb->actual_length = available_space; + if (ep->out_ix == ep->buffer_size) + ep->out_ix = 0; + + ep->buffered_units--; + oz_trace("Trying to give back buffered frame of size=%d\n", + available_space); + oz_complete_urb(port->ozhcd->hcd, urb, 0, 0); +} + +/*------------------------------------------------------------------------------ + * Context: softirq + */ static int oz_enqueue_ep_urb(struct oz_port *port, u8 ep_addr, int in_dir, struct urb *urb, u8 req_id) { @@ -452,6 +490,18 @@ static int oz_enqueue_ep_urb(struct oz_port *port, u8 ep_addr, int in_dir, ep = port->in_ep[ep_addr]; else ep = port->out_ep[ep_addr]; + + /*For interrupt endpoint check for buffered data + * & complete urb + */ + if (((ep->attrib & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) + && ep->buffered_units > 0) { + oz_free_urb_link(urbl); + spin_unlock_bh(&port->ozhcd->hcd_lock); + oz_complete_buffered_urb(port, ep, urb); + return 0; + } + if (ep && port->hpd) { list_add_tail(&urbl->link, &ep->urb_list); if (!in_dir && ep_addr && (ep->credit < 0)) { @@ -883,13 +933,14 @@ void oz_hcd_control_cnf(void *hport, u8 req_id, u8 rcode, u8 *data, } else { int copy_len; oz_trace("VENDOR-CLASS - cnf\n"); - if (data_len <= urb->transfer_buffer_length) - copy_len = data_len; - else - copy_len = urb->transfer_buffer_length; - if (copy_len) + if (data_len) { + if (data_len <= urb->transfer_buffer_length) + copy_len = data_len; + else + copy_len = urb->transfer_buffer_length; memcpy(urb->transfer_buffer, data, copy_len); - urb->actual_length = copy_len; + urb->actual_length = copy_len; + } oz_complete_urb(hcd, urb, 0, 0); } } @@ -961,6 +1012,9 @@ void oz_hcd_data_ind(void *hport, u8 endpoint, u8 *data, int data_len) urb->actual_length = copy_len; oz_complete_urb(port->ozhcd->hcd, urb, 0, 0); return; + } else { + oz_trace("buffering frame as URB is not available\n"); + oz_hcd_buffer_data(ep, data, data_len); } break; case USB_ENDPOINT_XFER_ISOC: @@ -1000,7 +1054,7 @@ int oz_hcd_heartbeat(void *hport) ep = ep_from_link(e); if (ep->credit < 0) continue; - ep->credit += (now - ep->last_jiffies); + ep->credit += jiffies_to_msecs(now - ep->last_jiffies); if (ep->credit > ep->credit_ceiling) ep->credit = ep->credit_ceiling; oz_event_log(OZ_EVT_EP_CREDIT, ep->ep_num, 0, 0, ep->credit); @@ -1009,13 +1063,12 @@ int oz_hcd_heartbeat(void *hport) urbl = list_first_entry(&ep->urb_list, struct oz_urb_link, link); urb = urbl->urb; - if (ep->credit < urb->number_of_packets) + if ((ep->credit + 1) < urb->number_of_packets) break; ep->credit -= urb->number_of_packets; oz_event_log(OZ_EVT_EP_CREDIT, ep->ep_num, 0, 0, ep->credit); - list_del(&urbl->link); - list_add_tail(&urbl->link, &xfr_list); + list_move_tail(&urbl->link, &xfr_list); } } spin_unlock_bh(&ozhcd->hcd_lock); @@ -1052,7 +1105,7 @@ int oz_hcd_heartbeat(void *hport) } continue; } - ep->credit += (now - ep->last_jiffies); + ep->credit += jiffies_to_msecs(now - ep->last_jiffies); oz_event_log(OZ_EVT_EP_CREDIT, ep->ep_num | USB_DIR_IN, 0, 0, ep->credit); ep->last_jiffies = now; @@ -1064,7 +1117,7 @@ int oz_hcd_heartbeat(void *hport) int len = 0; int copy_len; int i; - if (ep->credit < urb->number_of_packets) + if ((ep->credit + 1) < urb->number_of_packets) break; if (ep->buffered_units < urb->number_of_packets) break; @@ -1096,8 +1149,7 @@ int oz_hcd_heartbeat(void *hport) urb->error_count = 0; urb->start_frame = ep->start_frame; ep->start_frame += urb->number_of_packets; - list_del(&urbl->link); - list_add_tail(&urbl->link, &xfr_list); + list_move_tail(&urbl->link, &xfr_list); ep->credit -= urb->number_of_packets; oz_event_log(OZ_EVT_EP_CREDIT, ep->ep_num | USB_DIR_IN, 0, 0, ep->credit); @@ -1129,8 +1181,7 @@ int oz_hcd_heartbeat(void *hport) oz_trace("%ld: Request 0x%p timeout\n", now, urbl->urb); urbl->submit_jiffies = now; - list_del(e); - list_add_tail(e, &xfr_list); + list_move_tail(e, &xfr_list); } } if (!list_empty(&ep->urb_list)) @@ -1167,10 +1218,16 @@ static int oz_build_endpoints_for_interface(struct usb_hcd *hcd, int buffer_size = 0; oz_trace("%d bEndpointAddress = %x\n", i, ep_addr); - if ((ep_addr & USB_ENDPOINT_DIR_MASK) && - ((hep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) - == USB_ENDPOINT_XFER_ISOC)) { - buffer_size = 24*1024; + if (ep_addr & USB_ENDPOINT_DIR_MASK) { + switch (hep->desc.bmAttributes & + USB_ENDPOINT_XFERTYPE_MASK) { + case USB_ENDPOINT_XFER_ISOC: + buffer_size = 24*1024; + break; + case USB_ENDPOINT_XFER_INT: + buffer_size = 128; + break; + } } ep = oz_ep_alloc(mem_flags, buffer_size); @@ -1247,16 +1304,14 @@ static void oz_clean_endpoints_for_interface(struct usb_hcd *hcd, port->out_ep[i] = 0; /* Remove from isoc list if present. */ - list_del(e); - list_add_tail(e, &ep_list); + list_move_tail(e, &ep_list); } /* Gather IN endpoints. */ if ((mask & (1<<(i+OZ_NB_ENDPOINTS))) && port->in_ep[i]) { e = &port->in_ep[i]->link; port->in_ep[i] = 0; - list_del(e); - list_add_tail(e, &ep_list); + list_move_tail(e, &ep_list); } } spin_unlock_bh(&ozhcd->hcd_lock); @@ -1458,6 +1513,7 @@ static void oz_process_ep0_urb(struct oz_hcd *ozhcd, struct urb *urb, int data_len = 0; if ((setup->bRequestType & USB_DIR_IN) == 0) data_len = wlength; + urb->actual_length = data_len; if (oz_usb_control_req(port->hpd, req_id, setup, urb->transfer_buffer, data_len)) { rc = -ENOMEM; diff --git a/drivers/staging/ozwpan/ozmain.c b/drivers/staging/ozwpan/ozmain.c index c1ed6b2..ef6c5ab 100644 --- a/drivers/staging/ozwpan/ozmain.c +++ b/drivers/staging/ozwpan/ozmain.c @@ -59,6 +59,6 @@ module_exit(ozwpan_exit); MODULE_AUTHOR("Chris Kelly"); MODULE_DESCRIPTION("Ozmo Devices USB over WiFi hcd driver"); -MODULE_VERSION("1.0.10"); +MODULE_VERSION("1.0.13"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/ozwpan/ozpd.c b/drivers/staging/ozwpan/ozpd.c index 6c287ac..0b3648c 100644 --- a/drivers/staging/ozwpan/ozpd.c +++ b/drivers/staging/ozwpan/ozpd.c @@ -24,12 +24,6 @@ /*------------------------------------------------------------------------------ */ #define OZ_MAX_TX_POOL_SIZE 6 -/* Maximum number of uncompleted isoc frames that can be pending in network. - */ -#define OZ_MAX_SUBMITTED_ISOC 16 -/* Maximum number of uncompleted isoc frames that can be pending in Tx Queue. - */ -#define OZ_MAX_TX_QUEUE_ISOC 32 /*------------------------------------------------------------------------------ */ static struct oz_tx_frame *oz_tx_frame_alloc(struct oz_pd *pd); @@ -752,8 +746,7 @@ int oz_isoc_stream_create(struct oz_pd *pd, u8 ep_num) */ static void oz_isoc_stream_free(struct oz_isoc_stream *st) { - if (st->skb) - kfree_skb(st->skb); + kfree_skb(st->skb); kfree(st); } /*------------------------------------------------------------------------------ @@ -854,7 +847,7 @@ int oz_send_isoc_unit(struct oz_pd *pd, u8 ep_num, u8 *data, int len) if (!(pd->mode & OZ_F_ISOC_ANYTIME)) { struct oz_tx_frame *isoc_unit = NULL; int nb = pd->nb_queued_isoc_frames; - if (nb >= OZ_MAX_TX_QUEUE_ISOC) { + if (nb >= pd->isoc_latency) { oz_trace2(OZ_TRACE_TX_FRAMES, "Dropping ISOC Unit nb= %d\n", nb); diff --git a/drivers/staging/ozwpan/ozpd.h b/drivers/staging/ozwpan/ozpd.h index ddf1341..d35b0ea 100644 --- a/drivers/staging/ozwpan/ozpd.h +++ b/drivers/staging/ozwpan/ozpd.h @@ -82,6 +82,7 @@ struct oz_pd { u8 heartbeat_requested; u8 mode; u8 ms_per_isoc; + unsigned isoc_latency; unsigned max_stream_buffering; int nb_queued_frames; int nb_queued_isoc_frames; diff --git a/drivers/staging/ozwpan/ozproto.c b/drivers/staging/ozwpan/ozproto.c index a50ab18..cfb5160 100644 --- a/drivers/staging/ozwpan/ozproto.c +++ b/drivers/staging/ozwpan/ozproto.c @@ -220,6 +220,19 @@ static struct oz_pd *oz_connect_req(struct oz_pd *cur_pd, struct oz_elt *elt, pd->ms_per_isoc = body->ms_per_isoc; if (!pd->ms_per_isoc) pd->ms_per_isoc = 4; + + switch (body->ms_isoc_latency & OZ_LATENCY_MASK) { + case OZ_ONE_MS_LATENCY: + pd->isoc_latency = (body->ms_isoc_latency & + ~OZ_LATENCY_MASK) / pd->ms_per_isoc; + break; + case OZ_TEN_MS_LATENCY: + pd->isoc_latency = ((body->ms_isoc_latency & + ~OZ_LATENCY_MASK) * 10) / pd->ms_per_isoc; + break; + default: + pd->isoc_latency = OZ_MAX_TX_QUEUE_ISOC; + } } if (body->max_len_div16) pd->max_tx_size = ((u16)body->max_len_div16)<<4; diff --git a/drivers/staging/ozwpan/ozproto.h b/drivers/staging/ozwpan/ozproto.h index 89aea28..755a08d 100644 --- a/drivers/staging/ozwpan/ozproto.h +++ b/drivers/staging/ozwpan/ozproto.h @@ -14,7 +14,7 @@ /* Converts millisecs to jiffies. */ -#define oz_ms_to_jiffies(__x) (((__x)*1000)/HZ) +#define oz_ms_to_jiffies(__x) msecs_to_jiffies(__x) /* Quantum milliseconds. */ @@ -30,6 +30,12 @@ /* Maximun sizes of tx frames. */ #define OZ_MAX_TX_SIZE 1514 +/* Maximum number of uncompleted isoc frames that can be pending in network. */ +#define OZ_MAX_SUBMITTED_ISOC 16 + +/* Maximum number of uncompleted isoc frames that can be pending in Tx Queue. */ +#define OZ_MAX_TX_QUEUE_ISOC 32 + /* Application handler functions. */ typedef int (*oz_app_init_fn_t)(void); diff --git a/drivers/staging/ozwpan/ozprotocol.h b/drivers/staging/ozwpan/ozprotocol.h index 1e4edbe..17b09b9 100644 --- a/drivers/staging/ozwpan/ozprotocol.h +++ b/drivers/staging/ozwpan/ozprotocol.h @@ -65,6 +65,10 @@ struct oz_hdr { #define OZ_LAST_PN_HALF_CYCLE 127 +#define OZ_LATENCY_MASK 0xc0 +#define OZ_ONE_MS_LATENCY 0x40 +#define OZ_TEN_MS_LATENCY 0x80 + /* Connect request data structure. */ struct oz_elt_connect_req { @@ -73,7 +77,7 @@ struct oz_elt_connect_req { u8 pd_info; u8 session_id; u8 presleep; - u8 resv2; + u8 ms_isoc_latency; u8 host_vendor; u8 keep_alive; u16 apps; |