|
From: Mattias A. <mat...@us...> - 2001-04-25 16:54:47
|
The following file was modified in linux/drivers/char/bluetooth:
Name Old version New version Comment
---- ----------- ----------- -------
hci.c 1.142 1.143=20=20=20=20=20=20=20=20=20=20=20
The accompanying log:
* only wakeup hci_wq in COMMAND_COMPLETE (not COMMAND_STATUS)
* added read transmit power level
* added CONFIG_BLUETOOTH_EARLY_MSSWITCH which forces m/s switch in=20
lp_connect_rsp. If not defined, acl link is first established and
then a role switch is performed. (Requires scatternet functionality=20
if more than on slave).=20
* added ifdef __KERNEL__ around 2 sleeps (usermode stack)
* cleaned up
The diff of the modified file(s):
--- hci.c 2001/04/19 07:02:04 1.142
+++ hci.c 2001/04/25 16:54:47 1.143
@@ -721,7 +721,9 @@
/* we demand role switch as server */
if (force_msswitch && !i_am_initiator) {
/* FIXME -- check return code */
+#ifndef CONFIG_BLUETOOTH_EARLY_MSSWITCH
hci_switch_role(buf + 3, 0);
+#endif
}
/* reset variable again */
i_am_initiator =3D 0;
@@ -826,7 +828,7 @@
break;
=20
case QOS_SETUP_COMPLETE:
- DSYS(__FUNCTION__", QOS_SETUP_COMPLETE Not implemented!\n");
+ DSYS(__FUNCTION__", QOS_SETUP_COMPLETE\n");
break;
=20
case COMMAND_COMPLETE:
@@ -844,12 +846,16 @@
performing the task for this command */
=20=09=09
case COMMAND_STATUS:
- release_cmd_timer();
- /*FIXME: hci_switch_role() will generate COMMAND_STATUS that
- shouldn't call wake_up_interruptible() */
+=09=09
D_CMD(__FUNCTION__", COMMAND_STATUS\n");
=20=09=09
if (buf[0]) {
+
+ /* fixme -- add parser for command status e.g when trying
+ to connect an acl link which already is connected, a
+ command status with "ACL link already exist" is returned=20
+ This must be signalled using lp_connect_cfm (neg)
+ */
D_ERR(__FUNCTION__", COMMAND_STATUS: %s\n",get_err_msg(buf[0]));
#ifdef USE_INQTIMER
if (hci_inq_pending)
@@ -858,7 +864,6 @@
}
=20=09=09
update_nhcp(buf[1]);
- wake_up_interruptible(&hci_wq);
break;
case FLUSH_OCCURRED:
D_CMD(__FUNCTION__", FLUSH_OCCURRED on hci_hdl %d\n",
@@ -876,6 +881,9 @@
if (buf[0]) {=20
D_ERR(__FUNCTION__", Role changed failed due to %s\n",
get_err_msg(buf[0]));
+=09=09=09
+ /* fixme -- Notify l2cap that this BD will go down */
+=09=09=09
} else if (buf[7]) {
DSYS(__FUNCTION__", Current master is 0x%04x%08x\n",=20
CHAR2INT16(buf[6], buf[5]),=20
@@ -1143,6 +1151,19 @@
CHAR2INT16(r_val[2], r_val[1]));
break;=09
=20=20=20=20=20=20=20=20=20=20=20=20=20
+ case READ_TRANSMIT_POWER_LEVEL:=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20
+=09=09=20=20
+ printk(__FUNCTION__", READ_TRANSMIT_POWER_LEVEL\n");
+ if (r_val[0]) {
+ D_ERR(__FUNCTION__", READ_TRANSMIT_POWER_LEVEL: %s\n",
+ get_err_msg(r_val[0]));
+ break;
+ } else {
+ unsigned short hci_hdl =3D CHAR2INT12(r_val[2], r_val[1]);
+ DSYS("READ_TRANSMIT_POWER_LEVEL : handle %d, %d dBm\n", hci_hdl, r_val=
[3]);
+ }
+ break;
+
case SET_HOST_CONTROLLER_TO_HOST_FLOW_CONTROL:
D_CMD(__FUNCTION__", SET_HOST_CONTROLLER_TO_HOST_FLOW_CONTROL\n");
if (r_val[0]) {
@@ -1333,15 +1354,6 @@
break;
}
=20=09=09=09
- hci_ctrl.hc_buf.acl_len =3D CHAR2INT16(r_val[2],r_val[1]);
- hci_ctrl.hc_buf.sco_len =3D (u32) r_val[3];
- hci_ctrl.hc_buf.acl_num =3D CHAR2INT16(r_val[5],r_val[4]);
- hci_ctrl.hc_buf.sco_num =3D CHAR2INT16(r_val[7],r_val[6]);
- printk("\nHW module contains...\n");
- printk("%d ACL buffers at %d bytes\n%d SCO buffers at %d bytes\n\n",
- hci_ctrl.hc_buf.acl_num, hci_ctrl.hc_buf.acl_len,
- hci_ctrl.hc_buf.sco_num, hci_ctrl.hc_buf.sco_len);
-
break;
=20
case READ_BUFFER_SIZE:
@@ -1365,6 +1377,7 @@
hw.max_acl_num =3D hci_ctrl.hc_buf.acl_num;
#endif
#endif
+ wake_up_interruptible(&hci_wq);
break;
=20=20=20=20=20=20=20=20=20=20=20=20=20
case READ_BD_ADDR:
@@ -1710,13 +1723,9 @@
send_data_task.data =3D NULL;
#endif
=20
- /* Disable parity bit and set to H4 IF + flow ctrl */
- /* Not activated until after reset !!!! */
-
/* always... */
DSYS(__FUNCTION__", Reading buffer sizes in the module...\n");
hci_read_buffer_size(HCI_BLOCK);
-
hci_read_firmware_rev_info();=09
=20
#ifdef HOST_FLOW_CTRL
@@ -1731,11 +1740,24 @@
start_ncp_timer();=09
#endif
=20
+#ifdef CONFIG_BLUETOOTH_ENABLE_MSSWITCH
+ DSYS("M/S switch enabled\n");
+
+#ifdef CONFIG_BLUETOOTH_CSR
+ /* CSR can't do scatternet yet, so we need to do m/s switch=20
+ as early as in lp_connect_rsp */
+#define CONFIG_BLUETOOTH_EARLY_MSSWITCH
+#endif
+
#ifdef CONFIG_BLUETOOTH_FORCE_MSSWITCH
hci_force_msswitch(1);
#else
hci_force_msswitch(0);
#endif=20=20=20=20=20=20=20
+
+#else /* CONFIG_BLUETOOTH_ENABLE_MSSWITCH */
+ DSYS("M/S switch disabled\n");
+#endif
}
=20
void=20
@@ -1795,7 +1817,6 @@
tmp =3D send_inq_cmd_block((u8*) &c_pkt,=20
c_pkt.len + CMD_HDR_LEN + HCI_HDR_LEN,
inq_len);
-
return tmp;
}
=20
@@ -2127,7 +2148,7 @@
s32
hci_switch_role(u8 *bd, u8 role)
{
- printk(__FUNCTION__": role:%d\n", role);
+ DSYS(__FUNCTION__": role %d\n", role);
=20
c_pkt.type =3D CMD_PKT;
c_pkt.opcode =3D hci_put_opcode(SWITCH_ROLE, HCI_LP) ;
@@ -2357,7 +2378,7 @@
s32=20
hci_write_scan_enable(u32 enable)
{
- printk(__FUNCTION__", enable %d\n", enable);
+ D_CMD(__FUNCTION__", enable %d\n", enable);
c_pkt.type =3D CMD_PKT;
c_pkt.opcode =3D hci_put_opcode(WRITE_SCAN_ENABLE, HCI_HC) ;
=20=20=20
@@ -2576,6 +2597,20 @@
#endif
}
=20
+s32
+hci_read_power_transmit_level(u32 con_hdl, unsigned char type)
+{
+ D_CMD(__FUNCTION__"\n");
+ c_pkt.type =3D CMD_PKT;
+ c_pkt.opcode =3D hci_put_opcode(READ_TRANSMIT_POWER_LEVEL, HCI_LP) ;
+ c_pkt.len =3D 3;
+ c_pkt.data[0] =3D con_hdl & 0xff;
+ c_pkt.data[1] =3D (con_hdl >> 8) & 0xff;
+ c_pkt.data[2] =3D type;
+=09
+ return send_cmd((u8*) &c_pkt, c_pkt.len + CMD_HDR_LEN + HCI_HDR_LE=
N);
+}
+
/* The hci_host_buffer_size function is used by the Host to notify the Host
Controller about the maximum size of the data portion of HCI ACL and
SCO Data Packets sent from the Host Controller to the Host. The Host
@@ -2728,7 +2763,6 @@
memset(bd, 0, 6);=20
=20
tmp =3D send_cmd_block((u8*) &c_pkt ,c_pkt.len + CMD_HDR_LEN + HCI_HDR_LE=
N);
-
memcpy(bd, hci_ctrl.local_bd, 6);
return tmp;
}=20
@@ -2858,7 +2892,7 @@
void
hci_force_msswitch(u8 enable)
{
- printk("Setting force_msswitch to %d\n", enable);
+ DSYS("Force M/S switch set to %d\n", enable);
force_msswitch =3D enable;=20
}
=20
@@ -2889,7 +2923,18 @@
{=20
D_CMD(__FUNCTION__"Status:%d\n", cfm);
if (cfm) {
+#ifdef CONFIG_BLUETOOTH_EARLY_MSSWITCH
+ if (force_msswitch) {
+ DSYS("lp_connect_rsp : early m/s switch\n");
+ return accept_connection_request(bd_addr, MS_SWITCH_BECOME_MASTER);
+ } else
+ return accept_connection_request(bd_addr, MS_SWITCH_REMAIN_SLAVE);
+
+#else
return accept_connection_request(bd_addr, MS_SWITCH_REMAIN_SLAVE);
+#endif
+
+
} else {
return reject_connection_request(bd_addr, 0x0d);
/* FIXME: 0x0d =3D due to limited resourses store this
@@ -2956,12 +3001,14 @@
decreased by one and checks whether there are more packets
to send. Turn off interrupts since number_of_completed_packets
interrupt can change hci_ctrl.hc_buf.acl_num. */
-=09
cli();
while ((hci_ctrl.hc_buf.acl_num > 0) && bytes2send) {
hci_ctrl.hc_buf.acl_num--;
sti();
=20=09=09
+ /* FIXME -- what if send_acl_packet fails ???=20
+ Then acl_num will decrease anyway ... */=20
+
bytes2send -=3D send_acl_packet(tx_buf);
=20=09=09
D_QUEUE("<--%d (%d)\n", buf_byte_count(),=20
@@ -3184,9 +3231,10 @@
D_CMD(__FUNCTION__", ACCEPT_CONNECTION->connection complete\n");
o_len =3D set_con_cpl_event(out_event, 0, cmd->data,
HCI_HDL, ACL_CON);
+#ifndef __KERNEL__
sleep(1);
+#endif
bt_write_lower_driver(o_event, o_len);
-=20=20=20=20=20=20
lp_connect_cfm(data + 4, 0, 0);
break;
=20=20=20=20=20=20=20
@@ -3194,7 +3242,9 @@
D_CMD(__FUNCTION__", REJECT_CONNECTION->connection complete\n");
o_len =3D set_con_cpl_event(out_event, cmd->data[6],
cmd->data, HCI_HDL, ACL_CON);
+#ifndef __KERNEL__
sleep(1);
+#endif
bt_write_lower_driver(o_event, o_len);
lp_connect_cfm(data + 4, 0xd, 0);
break;
@@ -3631,7 +3681,7 @@
up(&hci_cmd_semaphore);
#else
while (hci_cmd_pending)=09=09
- usleep(50000);
+ usleep(10000);
#endif=20=20=20=20=20=20=20
return tmp;
}
|