|
From: Peter K. <pk...@us...> - 2001-09-07 12:53:26
|
The following files were modified in linux/drivers/char/bluetooth:
Name Old version New version Comment
---- ----------- ----------- -------
bcsp.c 1.18 1.19=20=20=20=20=20=20=20=20=20=20=20=20
bluetooth.c 1.191 1.192=20=20=20=20=20=20=20=20=20=20=20
hci.c 1.174 1.175=20=20=20=20=20=20=20=20=20=20=20
hci_vendor.c 1.51 1.52=20=20=20=20=20=20=20=20=20=20=20=20
The accompanying log:
Added BCSP DFU support.
The diff of the modified file(s):
--- bcsp.c 2001/09/06 15:56:56 1.18
+++ bcsp.c 2001/09/07 12:53:24 1.19
@@ -165,7 +165,7 @@
/* notify bt driver that sync failed */
if (!bcsp_sync) {
return -1;
- } else {
+ } else if (!bt_dfu_mode(-1)) {
csr_waitcmdnum(); /* Wait for command status */
}
return 0;=09
@@ -224,6 +224,9 @@
break;
case BCSP_ACL_CHN:
hci_receive_acl(data, (s32)len);
+ break;
+ case BCSP_DFU_CHN:
+ hci_receive_dfu(data, len);
break;
default:
D_ERR(__FUNCTION__ ": Unknown channel: %d\n", chn);
--- bluetooth.c 2001/08/29 09:35:07 1.191
+++ bluetooth.c 2001/09/07 12:53:24 1.192
@@ -503,6 +503,9 @@
s32 size =3D _IOC_SIZE(cmd);
bt_connection btcon;
u8 bd_addr[6];
+#ifdef CONFIG_BLUETOOTH_SUPPORT_BCSP
+ static u8 dfu_data[2044];
+#endif
=20
/* The direction is a bitmask, and VERIFY_WRITE catches R/W transfer.
The ioctl direction is user-oriented, while verify_area is kernel-
@@ -1104,18 +1107,71 @@
copy_to_user((s32*)arg, msg, u16_size*sizeof(u16));
return 0;
}
+#endif /* CONFIG_BLUETOOTH_CSR */
=20
#ifdef CONFIG_BLUETOOTH_SUPPORT_BCSP
case BTINITBCSP:
{
BT_DRIVER("BTINITBCSP\n");
- if (bcsp_init() < 0)
+ if (bcsp_init() < 0) {
printk("Sync failed\n");
+ return -ETIMEDOUT;
+ }
return 0;
}
-#endif
-#endif /* CONFIG_BLUETOOTH_CSR */
=20
+ case BT_SET_DFU_MODE:
+ {
+ GET_USER(tmp, (s32*)arg);
+
+ BT_DRIVER("BT_SET_DFU_MODE: %d\n", tmp);
+
+ tmp =3D bt_dfu_mode(tmp);
+ put_user(tmp, (s32*)arg);
+
+ return 0;
+ }
+
+ case BT_SEND_DFU_COMMAND:
+ {
+ int ret;
+ s32 dfu_len;
+
+ if (!bt_use_bcsp(-1))
+ return -EPERM;
+
+ GET_USER(dfu_len, (s32*)arg);
+ if (dfu_len > sizeof dfu_data)
+ return -EINVAL;
+
+ copy_from_user(dfu_data, (s32*)arg + 1, dfu_len);
+
+ ret =3D bcsp_sequence_send(dfu_data, dfu_len, BCSP_DFU_CHN=
);
+ if (ret < 0)
+ return ret;
+ return 0;
+ }
+
+ case BT_RETRIEVE_DFU_RESPONSE:
+ {
+ s32 dfu_len;
+
+ if (!bt_use_bcsp(-1))
+ return -EPERM;
+
+ GET_USER(dfu_len, (s32*)arg);
+ if (dfu_len > sizeof dfu_data)
+ return -EINVAL;
+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20
+ dfu_len =3D hci_read_dfu((u8*)((s32*)arg + 1), dfu_len);
+ if (dfu_len < 0)
+ return dfu_len;
+
+ put_user(dfu_len, (s32*)arg);
+ return 0;
+ }
+#endif /* CONFIG_BLUETOOTH_SUPPORT_BCSP */
+
default:=09=09
return -ENOIOCTLCMD;
=20
@@ -1129,6 +1185,7 @@
u32 cmd, unsigned long arg)
{
s32 tmp;
+
//printk(__FUNCTION__"[%s:%x] lock !\n", current->comm, cmd);
down(&ioctl_sem);
//printk(__FUNCTION__"[%s:%x] running...\n", current->comm, cmd);
@@ -2255,7 +2312,7 @@
(bt_connections && active =3D=3D NO_BLUETOOTH_ACTIVITY));
=20
if (light_leds) {
- LED_ACTIVE_SET(LED_GREEN);
+ LED_ACTIVE_SET(bt_dfu_mode(-1) ? LED_ORANGE : LED_GREEN);
}
else {
LED_ACTIVE_SET(LED_OFF);
@@ -2520,6 +2577,21 @@
}
=20
s32
+bt_dfu_mode(s32 new_dfu_mode)
+{=20=20
+ static s32 dfu_mode =3D 0;
+ s32 old =3D dfu_mode;
+
+ if (new_dfu_mode >=3D 0)
+ {
+#ifdef CONFIG_BLUETOOTH_SUPPORT_BCSP
+ dfu_mode =3D new_dfu_mode;
+#endif
+ }
+ return old;
+}
+
+s32
bt_init_stack(void)
{
unsigned long page;=09
@@ -2561,6 +2633,7 @@
}
#endif
=20
+ if (!bt_dfu_mode(-1)) {
/* Always check if hci succeeded */
if (hci_init() < 0){
D_ERR("HCI failed to initialize\n");
@@ -2577,6 +2650,7 @@
tcs_init();
test_init();
#endif
+ }
=20
bt_stack_initiated =3D 1;
bt_stat.bytes_received =3D 0;
@@ -2587,6 +2661,7 @@
=20
#ifdef __CRIS__
/* start led timer */
+ bt_set_leds(NO_BLUETOOTH_ACTIVITY);
init_timer(&bt_clear_led_timer);
bt_clear_led_timer.function =3D &bt_clear_led;
bt_clear_led_timer.expires =3D jiffies + HZ/10;
@@ -2948,11 +3023,8 @@
struct bt_session *bt;
DSYS("Shutting down bluetooth stack\n");
=20
- if (!bt_stack_initiated) {
- D_WARN("Bluetooth stack not initiated\n");
- return;
- }
-
+ if (bt_stack_initiated) {
+ if (!bt_dfu_mode(-1)) {
/* disconnect all active connections */
for (i =3D 0; i < BT_NBR_DATAPORTS;i++) {
bt =3D &bt_ctrl.session[i];
@@ -2975,23 +3047,30 @@
tcs_shutdown();
l2cap_shutdown();
hci_shutdown();
+ }
+ }
=20
+ bt_dfu_mode(0);
+
#ifdef CONFIG_BLUETOOTH_SUPPORT_BCSP
- if (bt_use_bcsp(-1))
bcsp_shutdown();
#endif
=20
btmem_shutdown();
=20
+#ifdef __CRIS__
+ if (bt_stack_initiated) {
+ del_timer(&bt_clear_led_timer);
+ }
+ bt_set_leds(NO_BLUETOOTH_ACTIVITY);
+#endif
+
bt_stack_initiated =3D 0;
=20=09
if (tmp_bt_buf) {
free_page((unsigned long) tmp_bt_buf);
tmp_bt_buf =3D NULL;
}
-#ifdef __CRIS__
- del_timer(&bt_clear_led_timer);
-#endif
}
=20
static inline s32
--- hci.c 2001/08/06 15:52:05 1.174
+++ hci.c 2001/09/07 12:53:24 1.175
@@ -1848,6 +1848,10 @@
#endif /* LINUX_VERSION_CODE */
#endif /* __KERNEL__ */
=20
+#ifdef CONFIG_BLUETOOTH_SUPPORT_BCSP
+ hci_init_dfu();
+#endif
+
DSYS("Initialising HCI inbuffers [%d]\n", HCI_IN_SIZE);
=20=09
/* Initiate the hci inbuffers */
@@ -1936,6 +1940,10 @@
=20
#ifdef USE_NCPTIMER
release_ncp_timer();
+#endif
+
+#ifdef CONFIG_BLUETOOTH_SUPPORT_BCSP
+ hci_shutdown_dfu();
#endif
}
=20
--- hci_vendor.c 2001/08/29 10:08:42 1.51
+++ hci_vendor.c 2001/09/07 12:53:24 1.52
@@ -655,7 +655,100 @@
wake_up_interruptible(&hci_wq);=09
}
=20
+static struct dfu_response
+{
+ struct dfu_response *next;
+ u32 length;
+ u8 data[0];
+} *dfu_responses =3D NULL;
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
+static struct wait_queue *dfu_wq =3D NULL;
+#else
+static wait_queue_head_t dfu_wq;
+#endif /* LINUX_VERSION_CODE */
+
+void
+hci_init_dfu(void)
+{
+#ifdef __KERNEL__
+#if LINUX_VERSION_CODE >=3D KERNEL_VERSION(2,4,0)
+ init_waitqueue_head(&dfu_wq);
+#endif /* LINUX_VERSION_CODE */
+#endif /* __KERNEL__ */
+}
+
+void
+hci_shutdown_dfu(void)
+{
+ struct dfu_response *response;
+
+ while (dfu_responses) {
+ cli();
+ response =3D dfu_responses;
+ dfu_responses =3D response->next;
+ sti();
+
+ kfree(response);
+ }
+}
+
+void
+hci_receive_dfu(u8 *data, u32 count)
+{
+ struct dfu_response *response;
+
+ if ((response =3D kmalloc(sizeof(*response) + count, GFP_ATOMIC))) {
+ response->length =3D count;
+ memcpy(response->data, data, count);
+
+ cli();
+ response->next =3D dfu_responses;
+ dfu_responses =3D response;
+ sti();
+
+ wake_up_interruptible(&dfu_wq);
+ }
+}
+
s32
+hci_read_dfu(u8* data, u32 count)
+{
+ struct dfu_response *response;
+ u32 length;
+
+ if (!dfu_responses)
+ interruptible_sleep_on(&dfu_wq);
+
+ cli();
+ response =3D dfu_responses;
+ dfu_responses =3D response->next;
+ sti();
+
+ if (!response)
+ return -EINTR;
+=20=20=20=20=20=20=20=20
+ length =3D response->length;
+
+ if (count < length) {
+ cli();
+ response->next =3D dfu_responses;
+ dfu_responses =3D response;
+ sti();
+
+ printk(__FUNCTION__ ": DFU response was too big!\n");
+
+ return -E2BIG;
+ }
+
+ copy_from_user(data, response->data, length);
+
+ kfree(response);
+
+ return (s32)length;
+}
+
+s32
csr_send_general_hq(csr_bccmd *cmd)
{
csr_msg *msg;
@@ -700,7 +793,7 @@
}
}
=20
-#endif
+#endif /* CONFIG_BLUETOOTH_SUPPORT_BCSP */
=20
s32=20
csr_pskey(u16 ps_key, u16 rw_mode, u16 *retb, u16 n_pars)
|