diff options
Diffstat (limited to 'drivers/staging/gdm72xx')
-rw-r--r-- | drivers/staging/gdm72xx/gdm_qos.c | 118 | ||||
-rw-r--r-- | drivers/staging/gdm72xx/gdm_qos.h | 58 | ||||
-rw-r--r-- | drivers/staging/gdm72xx/gdm_sdio.c | 37 | ||||
-rw-r--r-- | drivers/staging/gdm72xx/gdm_usb.c | 62 | ||||
-rw-r--r-- | drivers/staging/gdm72xx/gdm_usb.h | 16 | ||||
-rw-r--r-- | drivers/staging/gdm72xx/gdm_wimax.c | 16 | ||||
-rw-r--r-- | drivers/staging/gdm72xx/usb_boot.c | 220 |
7 files changed, 241 insertions, 286 deletions
diff --git a/drivers/staging/gdm72xx/gdm_qos.c b/drivers/staging/gdm72xx/gdm_qos.c index 80bde053fbc2..e26c6a8b2627 100644 --- a/drivers/staging/gdm72xx/gdm_qos.c +++ b/drivers/staging/gdm72xx/gdm_qos.c @@ -106,8 +106,8 @@ void gdm_qos_init(void *nic_ptr) for (i = 0 ; i < QOS_MAX; i++) { INIT_LIST_HEAD(&qcb->qos_list[i]); - qcb->csr[i].QoSBufCount = 0; - qcb->csr[i].Enabled = 0; + qcb->csr[i].qos_buf_count = 0; + qcb->csr[i].enabled = 0; } qcb->qos_list_cnt = 0; @@ -133,8 +133,8 @@ void gdm_qos_release_list(void *nic_ptr) spin_lock_irqsave(&qcb->qos_lock, flags); for (i = 0; i < QOS_MAX; i++) { - qcb->csr[i].QoSBufCount = 0; - qcb->csr[i].Enabled = 0; + qcb->csr[i].qos_buf_count = 0; + qcb->csr[i].enabled = 0; } qcb->qos_list_cnt = 0; @@ -153,42 +153,42 @@ static u32 chk_ipv4_rule(struct gdm_wimax_csr_s *csr, u8 *Stream, u8 *port) { int i; - if (csr->ClassifierRuleEnable&IPTYPEOFSERVICE) { - if (((Stream[1] & csr->IPToSMask) < csr->IPToSLow) || - ((Stream[1] & csr->IPToSMask) > csr->IPToSHigh)) + if (csr->classifier_rule_en&IPTYPEOFSERVICE) { + if (((Stream[1] & csr->ip2s_mask) < csr->ip2s_lo) || + ((Stream[1] & csr->ip2s_mask) > csr->ip2s_hi)) return 1; } - if (csr->ClassifierRuleEnable&PROTOCOL) { - if (Stream[9] != csr->Protocol) + if (csr->classifier_rule_en&PROTOCOL) { + if (Stream[9] != csr->protocol) return 1; } - if (csr->ClassifierRuleEnable&IPMASKEDSRCADDRESS) { + if (csr->classifier_rule_en&IPMASKEDSRCADDRESS) { for (i = 0; i < 4; i++) { - if ((Stream[12 + i] & csr->IPSrcAddrMask[i]) != - (csr->IPSrcAddr[i] & csr->IPSrcAddrMask[i])) + if ((Stream[12 + i] & csr->ipsrc_addrmask[i]) != + (csr->ipsrc_addr[i] & csr->ipsrc_addrmask[i])) return 1; } } - if (csr->ClassifierRuleEnable&IPMASKEDDSTADDRESS) { + if (csr->classifier_rule_en&IPMASKEDDSTADDRESS) { for (i = 0; i < 4; i++) { - if ((Stream[16 + i] & csr->IPDstAddrMask[i]) != - (csr->IPDstAddr[i] & csr->IPDstAddrMask[i])) + if ((Stream[16 + i] & csr->ipdst_addrmask[i]) != + (csr->ipdst_addr[i] & csr->ipdst_addrmask[i])) return 1; } } - if (csr->ClassifierRuleEnable&PROTOCOLSRCPORTRANGE) { + if (csr->classifier_rule_en&PROTOCOLSRCPORTRANGE) { i = ((port[0]<<8)&0xff00)+port[1]; - if ((i < csr->SrcPortLow) || (i > csr->SrcPortHigh)) + if ((i < csr->srcport_lo) || (i > csr->srcport_hi)) return 1; } - if (csr->ClassifierRuleEnable&PROTOCOLDSTPORTRANGE) { + if (csr->classifier_rule_en&PROTOCOLDSTPORTRANGE) { i = ((port[2]<<8)&0xff00)+port[3]; - if ((i < csr->DstPortLow) || (i > csr->DstPortHigh)) + if ((i < csr->dstport_lo) || (i > csr->dstport_hi)) return 1; } @@ -208,8 +208,8 @@ static u32 get_qos_index(struct nic *nic, u8 *iph, u8 *tcpudph) if (IP_Ver == 4) { for (i = 0; i < QOS_MAX; i++) { - if (qcb->csr[i].Enabled) { - if (qcb->csr[i].ClassifierRuleEnable) { + if (qcb->csr[i].enabled) { + if (qcb->csr[i].classifier_rule_en) { if (chk_ipv4_rule(&qcb->csr[i], iph, tcpudph) == 0) return i; @@ -230,14 +230,14 @@ static u32 extract_qos_list(struct nic *nic, struct list_head *head) INIT_LIST_HEAD(head); for (i = 0; i < QOS_MAX; i++) { - if (qcb->csr[i].Enabled) { - if (qcb->csr[i].QoSBufCount < qcb->qos_limit_size) { + if (qcb->csr[i].enabled) { + if (qcb->csr[i].qos_buf_count < qcb->qos_limit_size) { if (!list_empty(&qcb->qos_list[i])) { entry = list_entry( qcb->qos_list[i].prev, struct qos_entry_s, list); list_move_tail(&entry->list, head); - qcb->csr[i].QoSBufCount++; + qcb->csr[i].qos_buf_count++; if (!list_empty(&qcb->qos_list[i])) wprintk("QoS Index(%d) is piled!!\n", i); @@ -322,8 +322,8 @@ static u32 get_csr(struct qos_cb_s *qcb, u32 SFID, int mode) if (mode) { for (i = 0; i < QOS_MAX; i++) { - if (qcb->csr[i].Enabled == 0) { - qcb->csr[i].Enabled = 1; + if (qcb->csr[i].enabled == 0) { + qcb->csr[i].enabled = 1; qcb->qos_list_cnt++; return i; } @@ -365,7 +365,7 @@ void gdm_recv_qos_hci_packet(void *nic_ptr, u8 *buf, int size) eprintk("QoS ERROR: No SF\n"); return; } - qcb->csr[index].QoSBufCount = buf[(i*5)+10]; + qcb->csr[index].qos_buf_count = buf[(i*5)+10]; } extract_qos_list(nic, &send_list); @@ -391,38 +391,38 @@ void gdm_recv_qos_hci_packet(void *nic_ptr, u8 *buf, int size) spin_lock_irqsave(&qcb->qos_lock, flags); qcb->csr[index].SFID = SFID; - qcb->csr[index].ClassifierRuleEnable = ((buf[pos++]<<8)&0xff00); - qcb->csr[index].ClassifierRuleEnable += buf[pos++]; - if (qcb->csr[index].ClassifierRuleEnable == 0) + qcb->csr[index].classifier_rule_en = ((buf[pos++]<<8)&0xff00); + qcb->csr[index].classifier_rule_en += buf[pos++]; + if (qcb->csr[index].classifier_rule_en == 0) qcb->qos_null_idx = index; - qcb->csr[index].IPToSMask = buf[pos++]; - qcb->csr[index].IPToSLow = buf[pos++]; - qcb->csr[index].IPToSHigh = buf[pos++]; - qcb->csr[index].Protocol = buf[pos++]; - qcb->csr[index].IPSrcAddrMask[0] = buf[pos++]; - qcb->csr[index].IPSrcAddrMask[1] = buf[pos++]; - qcb->csr[index].IPSrcAddrMask[2] = buf[pos++]; - qcb->csr[index].IPSrcAddrMask[3] = buf[pos++]; - qcb->csr[index].IPSrcAddr[0] = buf[pos++]; - qcb->csr[index].IPSrcAddr[1] = buf[pos++]; - qcb->csr[index].IPSrcAddr[2] = buf[pos++]; - qcb->csr[index].IPSrcAddr[3] = buf[pos++]; - qcb->csr[index].IPDstAddrMask[0] = buf[pos++]; - qcb->csr[index].IPDstAddrMask[1] = buf[pos++]; - qcb->csr[index].IPDstAddrMask[2] = buf[pos++]; - qcb->csr[index].IPDstAddrMask[3] = buf[pos++]; - qcb->csr[index].IPDstAddr[0] = buf[pos++]; - qcb->csr[index].IPDstAddr[1] = buf[pos++]; - qcb->csr[index].IPDstAddr[2] = buf[pos++]; - qcb->csr[index].IPDstAddr[3] = buf[pos++]; - qcb->csr[index].SrcPortLow = ((buf[pos++]<<8)&0xff00); - qcb->csr[index].SrcPortLow += buf[pos++]; - qcb->csr[index].SrcPortHigh = ((buf[pos++]<<8)&0xff00); - qcb->csr[index].SrcPortHigh += buf[pos++]; - qcb->csr[index].DstPortLow = ((buf[pos++]<<8)&0xff00); - qcb->csr[index].DstPortLow += buf[pos++]; - qcb->csr[index].DstPortHigh = ((buf[pos++]<<8)&0xff00); - qcb->csr[index].DstPortHigh += buf[pos++]; + qcb->csr[index].ip2s_mask = buf[pos++]; + qcb->csr[index].ip2s_lo = buf[pos++]; + qcb->csr[index].ip2s_hi = buf[pos++]; + qcb->csr[index].protocol = buf[pos++]; + qcb->csr[index].ipsrc_addrmask[0] = buf[pos++]; + qcb->csr[index].ipsrc_addrmask[1] = buf[pos++]; + qcb->csr[index].ipsrc_addrmask[2] = buf[pos++]; + qcb->csr[index].ipsrc_addrmask[3] = buf[pos++]; + qcb->csr[index].ipsrc_addr[0] = buf[pos++]; + qcb->csr[index].ipsrc_addr[1] = buf[pos++]; + qcb->csr[index].ipsrc_addr[2] = buf[pos++]; + qcb->csr[index].ipsrc_addr[3] = buf[pos++]; + qcb->csr[index].ipdst_addrmask[0] = buf[pos++]; + qcb->csr[index].ipdst_addrmask[1] = buf[pos++]; + qcb->csr[index].ipdst_addrmask[2] = buf[pos++]; + qcb->csr[index].ipdst_addrmask[3] = buf[pos++]; + qcb->csr[index].ipdst_addr[0] = buf[pos++]; + qcb->csr[index].ipdst_addr[1] = buf[pos++]; + qcb->csr[index].ipdst_addr[2] = buf[pos++]; + qcb->csr[index].ipdst_addr[3] = buf[pos++]; + qcb->csr[index].srcport_lo = ((buf[pos++]<<8)&0xff00); + qcb->csr[index].srcport_lo += buf[pos++]; + qcb->csr[index].srcport_hi = ((buf[pos++]<<8)&0xff00); + qcb->csr[index].srcport_hi += buf[pos++]; + qcb->csr[index].dstport_lo = ((buf[pos++]<<8)&0xff00); + qcb->csr[index].dstport_lo += buf[pos++]; + qcb->csr[index].dstport_hi = ((buf[pos++]<<8)&0xff00); + qcb->csr[index].dstport_hi += buf[pos++]; qcb->qos_limit_size = 254/qcb->qos_list_cnt; spin_unlock_irqrestore(&qcb->qos_lock, flags); @@ -444,7 +444,7 @@ void gdm_recv_qos_hci_packet(void *nic_ptr, u8 *buf, int size) INIT_LIST_HEAD(&free_list); spin_lock_irqsave(&qcb->qos_lock, flags); - qcb->csr[index].Enabled = 0; + qcb->csr[index].enabled = 0; qcb->qos_list_cnt--; qcb->qos_limit_size = 254/qcb->qos_list_cnt; diff --git a/drivers/staging/gdm72xx/gdm_qos.h b/drivers/staging/gdm72xx/gdm_qos.h index 33f2bd4cee32..8f18119d22a9 100644 --- a/drivers/staging/gdm72xx/gdm_qos.h +++ b/drivers/staging/gdm72xx/gdm_qos.h @@ -20,18 +20,18 @@ #define BOOLEAN u8 -#define QOS_MAX 16 -#define IPTYPEOFSERVICE 0x8000 -#define PROTOCOL 0x4000 -#define IPMASKEDSRCADDRESS 0x2000 -#define IPMASKEDDSTADDRESS 0x1000 +#define QOS_MAX 16 +#define IPTYPEOFSERVICE 0x8000 +#define PROTOCOL 0x4000 +#define IPMASKEDSRCADDRESS 0x2000 +#define IPMASKEDDSTADDRESS 0x1000 #define PROTOCOLSRCPORTRANGE 0x800 #define PROTOCOLDSTPORTRANGE 0x400 -#define DSTMACADDR 0x200 -#define SRCMACADDR 0x100 -#define ETHERTYPE 0x80 +#define DSTMACADDR 0x200 +#define SRCMACADDR 0x100 +#define ETHERTYPE 0x80 #define IEEE802_1DUSERPRIORITY 0x40 -#define IEEE802_1QVLANID 0x10 +#define IEEE802_1QVLANID 0x10 struct gdm_wimax_csr_s { /* union{ @@ -51,28 +51,28 @@ struct gdm_wimax_csr_s { Reserved:5; } fields; } */ - BOOLEAN Enabled; - u32 SFID; - u8 QoSBufCount; - u16 ClassifierRuleEnable; - u8 IPToSLow; - u8 IPToSHigh; - u8 IPToSMask; - u8 Protocol; - u8 IPSrcAddr[16]; - u8 IPSrcAddrMask[16]; - u8 IPDstAddr[16]; - u8 IPDstAddrMask[16]; - u16 SrcPortLow; - u16 SrcPortHigh; - u16 DstPortLow; - u16 DstPortHigh; + BOOLEAN enabled; + u32 SFID; + u8 qos_buf_count; + u16 classifier_rule_en; + u8 ip2s_lo; + u8 ip2s_hi; + u8 ip2s_mask; + u8 protocol; + u8 ipsrc_addr[16]; + u8 ipsrc_addrmask[16]; + u8 ipdst_addr[16]; + u8 ipdst_addrmask[16]; + u16 srcport_lo; + u16 srcport_hi; + u16 dstport_lo; + u16 dstport_hi; }; struct qos_entry_s { - struct list_head list; - struct sk_buff *skb; - struct net_device *dev; + struct list_head list; + struct sk_buff *skb; + struct net_device *dev; }; @@ -81,7 +81,7 @@ struct qos_cb_s { u32 qos_list_cnt; u32 qos_null_idx; struct gdm_wimax_csr_s csr[QOS_MAX]; - spinlock_t qos_lock; + spinlock_t qos_lock; u32 qos_limit_size; }; diff --git a/drivers/staging/gdm72xx/gdm_sdio.c b/drivers/staging/gdm72xx/gdm_sdio.c index 3e43c012ef27..ca38d719a1f8 100644 --- a/drivers/staging/gdm72xx/gdm_sdio.c +++ b/drivers/staging/gdm72xx/gdm_sdio.c @@ -60,27 +60,20 @@ static void hexdump(char *title, u8 *data, int len) static struct sdio_tx *alloc_tx_struct(struct tx_cxt *tx) { - struct sdio_tx *t = NULL; - - t = kmalloc(sizeof(*t), GFP_ATOMIC); - if (t == NULL) - goto out; + struct sdio_tx *t = kzalloc(sizeof(*t), GFP_ATOMIC); - memset(t, 0, sizeof(*t)); + if (!t) + return NULL; t->buf = kmalloc(TX_BUF_SIZE, GFP_ATOMIC); - if (t->buf == NULL) - goto out; + if (!t->buf) { + kfree(t); + return NULL; + } t->tx_cxt = tx; return t; -out: - if (t) { - kfree(t->buf); - kfree(t); - } - return NULL; } static void free_tx_struct(struct sdio_tx *t) @@ -93,20 +86,12 @@ static void free_tx_struct(struct sdio_tx *t) static struct sdio_rx *alloc_rx_struct(struct rx_cxt *rx) { - struct sdio_rx *r = NULL; + struct sdio_rx *r = kzalloc(sizeof(*r), GFP_ATOMIC); - r = kmalloc(sizeof(*r), GFP_ATOMIC); - if (r == NULL) - goto out; - - memset(r, 0, sizeof(*r)); - - r->rx_cxt = rx; + if (r) + r->rx_cxt = rx; return r; -out: - kfree(r); - return NULL; } static void free_rx_struct(struct sdio_rx *r) @@ -680,7 +665,7 @@ static int sdio_wimax_probe(struct sdio_func *func, phy_dev->rcv_func = gdm_sdio_receive; ret = init_sdio(sdev); - if (sdev < 0) + if (ret < 0) goto out; sdev->func = func; diff --git a/drivers/staging/gdm72xx/gdm_usb.c b/drivers/staging/gdm72xx/gdm_usb.c index d48d49c145ee..0c9e8958009b 100644 --- a/drivers/staging/gdm72xx/gdm_usb.c +++ b/drivers/staging/gdm72xx/gdm_usb.c @@ -26,11 +26,11 @@ MODULE_DEVICE_TABLE(usb, id_table); -#define TX_BUF_SIZE 2048 +#define TX_BUF_SIZE 2048 #if defined(CONFIG_WIMAX_GDM72XX_WIMAX2) -#define RX_BUF_SIZE (128*1024) /* For packet aggregation */ +#define RX_BUF_SIZE (128*1024) /* For packet aggregation */ #else -#define RX_BUF_SIZE 2048 +#define RX_BUF_SIZE 2048 #endif #define GDM7205_PADDING 256 @@ -39,7 +39,7 @@ MODULE_DEVICE_TABLE(usb, id_table); #define B2H(x) __be16_to_cpu(x) #define DB2H(x) __be32_to_cpu(x) -#define DOWNLOAD_CONF_VALUE 0x21 +#define DOWNLOAD_CONF_VALUE 0x21 #ifdef CONFIG_WIMAX_GDM72XX_K_MODE @@ -48,7 +48,7 @@ static LIST_HEAD(k_list); static DEFINE_SPINLOCK(k_lock); static int k_mode_stop; -#define K_WAIT_TIME (2 * HZ / 100) +#define K_WAIT_TIME (2 * HZ / 100) #endif /* CONFIG_WIMAX_GDM72XX_K_MODE */ @@ -73,29 +73,23 @@ static void hexdump(char *title, u8 *data, int len) static struct usb_tx *alloc_tx_struct(struct tx_cxt *tx) { - struct usb_tx *t = NULL; + struct usb_tx *t = kzalloc(sizeof(*t), GFP_ATOMIC); - t = kmalloc(sizeof(*t), GFP_ATOMIC); - if (t == NULL) - goto out; - - memset(t, 0, sizeof(*t)); + if (!t) + return NULL; t->urb = usb_alloc_urb(0, GFP_ATOMIC); t->buf = kmalloc(TX_BUF_SIZE, GFP_ATOMIC); - if (t->urb == NULL || t->buf == NULL) - goto out; - - t->tx_cxt = tx; - - return t; -out: - if (t) { + if (!t->urb || !t->buf) { usb_free_urb(t->urb); kfree(t->buf); kfree(t); + return NULL; } - return NULL; + + t->tx_cxt = tx; + + return t; } static void free_tx_struct(struct usb_tx *t) @@ -109,28 +103,22 @@ static void free_tx_struct(struct usb_tx *t) static struct usb_rx *alloc_rx_struct(struct rx_cxt *rx) { - struct usb_rx *r = NULL; + struct usb_rx *r = kzalloc(sizeof(*r), GFP_ATOMIC); - r = kmalloc(sizeof(*r), GFP_ATOMIC); - if (r == NULL) - goto out; - - memset(r, 0, sizeof(*r)); + if (!r) + return NULL; r->urb = usb_alloc_urb(0, GFP_ATOMIC); r->buf = kmalloc(RX_BUF_SIZE, GFP_ATOMIC); - if (r->urb == NULL || r->buf == NULL) - goto out; - - r->rx_cxt = rx; - return r; -out: - if (r) { + if (!r->urb || !r->buf) { usb_free_urb(r->urb); kfree(r->buf); kfree(r); + return NULL; } - return NULL; + + r->rx_cxt = rx; + return r; } static void free_rx_struct(struct usb_rx *r) @@ -180,8 +168,7 @@ static struct usb_rx *get_rx_struct(struct rx_cxt *rx) } r = list_entry(rx->free_list.next, struct usb_rx, list); - list_del(&r->list); - list_add_tail(&r->list, &rx->used_list); + list_move_tail(&r->list, &rx->used_list); return r; } @@ -189,8 +176,7 @@ static struct usb_rx *get_rx_struct(struct rx_cxt *rx) /* Before this function is called, spin lock should be locked. */ static void put_rx_struct(struct rx_cxt *rx, struct usb_rx *r) { - list_del(&r->list); - list_add(&r->list, &rx->free_list); + list_move(&r->list, &rx->free_list); } static int init_usb(struct usbwm_dev *udev) diff --git a/drivers/staging/gdm72xx/gdm_usb.h b/drivers/staging/gdm72xx/gdm_usb.h index ecb891f6a599..f2c54511bb96 100644 --- a/drivers/staging/gdm72xx/gdm_usb.h +++ b/drivers/staging/gdm72xx/gdm_usb.h @@ -18,8 +18,8 @@ #include <linux/usb.h> #include <linux/list.h> -#define B_DIFF_DL_DRV (1<<4) -#define B_DOWNLOAD (1 << 5) +#define B_DIFF_DL_DRV (1 << 4) +#define B_DOWNLOAD (1 << 5) #define MAX_NR_SDU_BUF 64 struct usb_tx { @@ -29,7 +29,7 @@ struct usb_tx { #endif struct tx_cxt *tx_cxt; - struct urb *urb; + struct urb *urb; u8 *buf; void (*callback)(void *cb_data); @@ -44,14 +44,14 @@ struct tx_cxt { struct list_head pending_list; #endif - spinlock_t lock; + spinlock_t lock; }; struct usb_rx { struct list_head list; struct rx_cxt *rx_cxt; - struct urb *urb; + struct urb *urb; u8 *buf; void (*callback)(void *cb_data, void *data, int len); @@ -61,7 +61,7 @@ struct usb_rx { struct rx_cxt { struct list_head free_list; struct list_head used_list; - spinlock_t lock; + spinlock_t lock; }; struct usbwm_dev { @@ -76,8 +76,8 @@ struct usbwm_dev { struct list_head list; #endif - struct tx_cxt tx; - struct rx_cxt rx; + struct tx_cxt tx; + struct rx_cxt rx; int padding; }; diff --git a/drivers/staging/gdm72xx/gdm_wimax.c b/drivers/staging/gdm72xx/gdm_wimax.c index 0716efc1817d..6cb810701a3e 100644 --- a/drivers/staging/gdm72xx/gdm_wimax.c +++ b/drivers/staging/gdm72xx/gdm_wimax.c @@ -258,12 +258,16 @@ static int gdm_wimax_event_init(void) if (!wm_event.ref_cnt) { wm_event.sock = netlink_init(NETLINK_WIMAX, gdm_wimax_event_rcv); - if (wm_event.sock) - wm_event.ref_cnt++; - INIT_LIST_HEAD(&wm_event.evtq); - INIT_LIST_HEAD(&wm_event.freeq); - INIT_WORK(&wm_event.ws, __gdm_wimax_event_send); - spin_lock_init(&wm_event.evt_lock); + if (wm_event.sock) { + INIT_LIST_HEAD(&wm_event.evtq); + INIT_LIST_HEAD(&wm_event.freeq); + INIT_WORK(&wm_event.ws, __gdm_wimax_event_send); + spin_lock_init(&wm_event.evt_lock); + } + } + + if (wm_event.sock) { + wm_event.ref_cnt++; return 0; } diff --git a/drivers/staging/gdm72xx/usb_boot.c b/drivers/staging/gdm72xx/usb_boot.c index e3dbd5a552ca..0787188728aa 100644 --- a/drivers/staging/gdm72xx/usb_boot.c +++ b/drivers/staging/gdm72xx/usb_boot.c @@ -18,25 +18,22 @@ #include <linux/usb.h> #include <linux/unistd.h> #include <linux/slab.h> +#include <linux/firmware.h> #include <asm/byteorder.h> #include "gdm_usb.h" #include "usb_boot.h" -#define DN_KERNEL_MAGIC_NUMBER 0x10760001 -#define DN_ROOTFS_MAGIC_NUMBER 0x10760002 +#define DN_KERNEL_MAGIC_NUMBER 0x10760001 +#define DN_ROOTFS_MAGIC_NUMBER 0x10760002 -#define DOWNLOAD_SIZE 1024 - -#define DH2B(x) __cpu_to_be32(x) -#define DL2H(x) __le32_to_cpu(x) - -#define MIN(a, b) ((a) > (b) ? (b) : (a)) +#define DOWNLOAD_SIZE 1024 #define MAX_IMG_CNT 16 -#define UIMG_PATH "/lib/firmware/gdm72xx/gdmuimg.bin" -#define KERN_PATH "/lib/firmware/gdm72xx/zImage" -#define FS_PATH "/lib/firmware/gdm72xx/ramdisk.jffs2" +#define FW_DIR "gdm72xx/" +#define FW_UIMG "gdmuimg.bin" +#define FW_KERN "zImage" +#define FW_FS "ramdisk.jffs2" struct dn_header { u32 magic_num; @@ -44,23 +41,23 @@ struct dn_header { }; struct img_header { - u32 magic_code; - u32 count; - u32 len; - u32 offset[MAX_IMG_CNT]; + u32 magic_code; + u32 count; + u32 len; + u32 offset[MAX_IMG_CNT]; char hostname[32]; char date[32]; }; struct fw_info { - u32 id; - u32 len; - u32 kernel_len; - u32 rootfs_len; - u32 kernel_offset; - u32 rootfs_offset; - u32 fw_ver; - u32 mac_ver; + u32 id; + u32 len; + u32 kernel_len; + u32 rootfs_len; + u32 kernel_offset; + u32 rootfs_offset; + u32 fw_ver; + u32 mac_ver; char hostname[32]; char userid[16]; char date[32]; @@ -71,7 +68,7 @@ static void array_le32_to_cpu(u32 *arr, int num) { int i; for (i = 0; i < num; i++, arr++) - *arr = DL2H(*arr); + *arr = __le32_to_cpu(*arr); } static u8 *tx_buf; @@ -107,44 +104,37 @@ static int gdm_wibro_recv(struct usb_device *usbdev, void *data, int len) return 0; } -static int download_image(struct usb_device *usbdev, struct file *filp, - loff_t *pos, u32 img_len, u32 magic_num) +static int download_image(struct usb_device *usbdev, + const struct firmware *firm, + loff_t pos, u32 img_len, u32 magic_num) { struct dn_header h; int ret = 0; u32 size; - int len, readn; - size = (img_len + DOWNLOAD_SIZE - 1) & ~(DOWNLOAD_SIZE - 1); - h.magic_num = DH2B(magic_num); - h.file_size = DH2B(size); + size = ALIGN(img_len, DOWNLOAD_SIZE); + h.magic_num = __cpu_to_be32(magic_num); + h.file_size = __cpu_to_be32(size); ret = gdm_wibro_send(usbdev, &h, sizeof(h)); if (ret < 0) - goto out; + return ret; - readn = 0; - while ((len = filp->f_op->read(filp, tx_buf, DOWNLOAD_SIZE, pos))) { + while (img_len > 0) { + if (img_len > DOWNLOAD_SIZE) + size = DOWNLOAD_SIZE; + else + size = img_len; /* the last chunk of data */ - if (len < 0) { - ret = -1; - goto out; - } - readn += len; + memcpy(tx_buf, firm->data + pos, size); + ret = gdm_wibro_send(usbdev, tx_buf, size); - ret = gdm_wibro_send(usbdev, tx_buf, DOWNLOAD_SIZE); if (ret < 0) - goto out; - if (readn >= img_len) - break; - } + return ret; - if (readn < img_len) { - printk(KERN_ERR "gdmwm: Cannot read to the requested size. " - "Read = %d Requested = %d\n", readn, img_len); - ret = -EIO; + img_len -= size; + pos += size; } -out: return ret; } @@ -152,14 +142,19 @@ out: int usb_boot(struct usb_device *usbdev, u16 pid) { int i, ret = 0; - struct file *filp = NULL; - struct inode *inode = NULL; - static mm_segment_t fs; struct img_header hdr; struct fw_info fw_info; loff_t pos = 0; - char *img_name = UIMG_PATH; - int len; + char *img_name = FW_DIR FW_UIMG; + const struct firmware *firm; + + ret = request_firmware(&firm, img_name, &usbdev->dev); + if (ret < 0) { + printk(KERN_ERR + "requesting firmware %s failed with error %d\n", + img_name, ret); + return ret; + } tx_buf = kmalloc(DOWNLOAD_SIZE, GFP_KERNEL); if (tx_buf == NULL) { @@ -167,29 +162,12 @@ int usb_boot(struct usb_device *usbdev, u16 pid) return -ENOMEM; } - fs = get_fs(); - set_fs(get_ds()); - - filp = filp_open(img_name, O_RDONLY | O_LARGEFILE, 0); - if (IS_ERR(filp)) { - printk(KERN_ERR "Can't find %s.\n", img_name); - ret = PTR_ERR(filp); - goto restore_fs; - } - - inode = filp->f_dentry->d_inode; - if (!S_ISREG(inode->i_mode)) { - printk(KERN_ERR "Invalid file type: %s\n", img_name); - ret = -EINVAL; - goto out; - } - - len = filp->f_op->read(filp, (u8 *)&hdr, sizeof(hdr), &pos); - if (len != sizeof(hdr)) { + if (firm->size < sizeof(hdr)) { printk(KERN_ERR "gdmwm: Cannot read the image info.\n"); ret = -EIO; goto out; } + memcpy(&hdr, firm->data, sizeof(hdr)); array_le32_to_cpu((u32 *)&hdr, 19); #if 0 @@ -217,13 +195,12 @@ int usb_boot(struct usb_device *usbdev, u16 pid) } pos = hdr.offset[i]; - len = filp->f_op->read(filp, (u8 *)&fw_info, sizeof(fw_info), - &pos); - if (len != sizeof(fw_info)) { + if (firm->size < sizeof(fw_info) + pos) { printk(KERN_ERR "gdmwm: Cannot read the FW info.\n"); ret = -EIO; goto out; } + memcpy(&fw_info, firm->data + pos, sizeof(fw_info)); array_le32_to_cpu((u32 *)&fw_info, 8); #if 0 @@ -239,14 +216,23 @@ int usb_boot(struct usb_device *usbdev, u16 pid) continue; pos = hdr.offset[i] + fw_info.kernel_offset; - ret = download_image(usbdev, filp, &pos, fw_info.kernel_len, - DN_KERNEL_MAGIC_NUMBER); + if (firm->size < fw_info.kernel_len + pos) { + printk(KERN_ERR "gdmwm: Kernel FW is too small.\n"); + goto out; + } + + ret = download_image(usbdev, firm, pos, + fw_info.kernel_len, DN_KERNEL_MAGIC_NUMBER); if (ret < 0) goto out; printk(KERN_INFO "GCT: Kernel download success.\n"); pos = hdr.offset[i] + fw_info.rootfs_offset; - ret = download_image(usbdev, filp, &pos, fw_info.rootfs_len, + if (firm->size < fw_info.rootfs_len + pos) { + printk(KERN_ERR "gdmwm: Filesystem FW is too small.\n"); + goto out; + } + ret = download_image(usbdev, firm, pos, fw_info.rootfs_len, DN_ROOTFS_MAGIC_NUMBER); if (ret < 0) goto out; @@ -260,10 +246,7 @@ int usb_boot(struct usb_device *usbdev, u16 pid) ret = -EINVAL; } out: - filp_close(filp, NULL); - -restore_fs: - set_fs(fs); + release_firmware(firm); kfree(tx_buf); return ret; } @@ -293,38 +276,27 @@ out: return ret; } -static int em_download_image(struct usb_device *usbdev, char *path, +static int em_download_image(struct usb_device *usbdev, const char *img_name, char *type_string) { - struct file *filp; - struct inode *inode; - static mm_segment_t fs; char *buf = NULL; loff_t pos = 0; int ret = 0; - int len, readn = 0; + int len; + int img_len; + const struct firmware *firm; #if defined(GDM7205_PADDING) const int pad_size = GDM7205_PADDING; #else const int pad_size = 0; #endif - fs = get_fs(); - set_fs(get_ds()); - - filp = filp_open(path, O_RDONLY | O_LARGEFILE, 0); - if (IS_ERR(filp)) { - printk(KERN_ERR "Can't find %s.\n", path); - set_fs(fs); - ret = -ENOENT; - goto restore_fs; - } - - inode = filp->f_dentry->d_inode; - if (!S_ISREG(inode->i_mode)) { - printk(KERN_ERR "Invalid file type: %s\n", path); - ret = -EINVAL; - goto out; + ret = request_firmware(&firm, img_name, &usbdev->dev); + if (ret < 0) { + printk(KERN_ERR + "requesting firmware %s failed with error %d\n", + img_name, ret); + return ret; } buf = kmalloc(DOWNLOAD_CHUCK + pad_size, GFP_KERNEL); @@ -338,18 +310,28 @@ static int em_download_image(struct usb_device *usbdev, char *path, if (ret < 0) goto out; - while ((len = filp->f_op->read(filp, buf+pad_size, DOWNLOAD_CHUCK, - &pos))) { - if (len < 0) { - ret = -1; - goto out; - } - readn += len; + img_len = firm->size; + + if (img_len <= 0) { + ret = -1; + goto out; + } + while (img_len > 0) { + if (img_len > DOWNLOAD_CHUCK) + len = DOWNLOAD_CHUCK; + else + len = img_len; /* the last chunk of data */ + + memcpy(buf+pad_size, firm->data + pos, len); ret = gdm_wibro_send(usbdev, buf, len+pad_size); + if (ret < 0) goto out; + img_len -= DOWNLOAD_CHUCK; + pos += DOWNLOAD_CHUCK; + ret = em_wait_ack(usbdev, ((len+pad_size) % 512 == 0)); if (ret < 0) goto out; @@ -360,11 +342,7 @@ static int em_download_image(struct usb_device *usbdev, char *path, goto out; out: - filp_close(filp, NULL); - -restore_fs: - set_fs(fs); - + release_firmware(firm); kfree(buf); return ret; @@ -382,18 +360,20 @@ static int em_fw_reset(struct usb_device *usbdev) int usb_emergency(struct usb_device *usbdev) { int ret; + const char *kern_name = FW_DIR FW_KERN; + const char *fs_name = FW_DIR FW_FS; - ret = em_download_image(usbdev, KERN_PATH, KERNEL_TYPE_STRING); + ret = em_download_image(usbdev, kern_name, KERNEL_TYPE_STRING); if (ret < 0) - goto out; + return ret; printk(KERN_INFO "GCT Emergency: Kernel download success.\n"); - ret = em_download_image(usbdev, FS_PATH, FS_TYPE_STRING); + ret = em_download_image(usbdev, fs_name, FS_TYPE_STRING); if (ret < 0) - goto out; + return ret; printk(KERN_INFO "GCT Emergency: Filesystem download success.\n"); ret = em_fw_reset(usbdev); -out: + return ret; } |