aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn/gigaset/capi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/isdn/gigaset/capi.c')
-rw-r--r--drivers/isdn/gigaset/capi.c144
1 files changed, 81 insertions, 63 deletions
diff --git a/drivers/isdn/gigaset/capi.c b/drivers/isdn/gigaset/capi.c
index c276a925b36f..ac0a2da1eef6 100644
--- a/drivers/isdn/gigaset/capi.c
+++ b/drivers/isdn/gigaset/capi.c
@@ -168,14 +168,6 @@ static inline void ignore_cstruct_param(struct cardstate *cs, _cstruct param,
168 msgname, paramname); 168 msgname, paramname);
169} 169}
170 170
171static inline void ignore_cmstruct_param(struct cardstate *cs, _cmstruct param,
172 char *msgname, char *paramname)
173{
174 if (param != CAPI_DEFAULT)
175 dev_warn(cs->dev, "%s: ignoring unsupported parameter: %s\n",
176 msgname, paramname);
177}
178
179/* 171/*
180 * check for legal hex digit 172 * check for legal hex digit
181 */ 173 */
@@ -1062,6 +1054,7 @@ static void do_facility_req(struct gigaset_capi_ctr *iif,
1062 struct sk_buff *skb) 1054 struct sk_buff *skb)
1063{ 1055{
1064 struct cardstate *cs = iif->ctr.driverdata; 1056 struct cardstate *cs = iif->ctr.driverdata;
1057 _cmsg *cmsg = &iif->acmsg;
1065 struct sk_buff *cskb; 1058 struct sk_buff *cskb;
1066 u8 *pparam; 1059 u8 *pparam;
1067 unsigned int msgsize = CAPI_FACILITY_CONF_BASELEN; 1060 unsigned int msgsize = CAPI_FACILITY_CONF_BASELEN;
@@ -1069,14 +1062,14 @@ static void do_facility_req(struct gigaset_capi_ctr *iif,
1069 static u8 confparam[10]; /* max. 9 octets + length byte */ 1062 static u8 confparam[10]; /* max. 9 octets + length byte */
1070 1063
1071 /* decode message */ 1064 /* decode message */
1072 capi_message2cmsg(&iif->acmsg, skb->data); 1065 capi_message2cmsg(cmsg, skb->data);
1073 dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg); 1066 dump_cmsg(DEBUG_CMD, __func__, cmsg);
1074 1067
1075 /* 1068 /*
1076 * Facility Request Parameter is not decoded by capi_message2cmsg() 1069 * Facility Request Parameter is not decoded by capi_message2cmsg()
1077 * encoding depends on Facility Selector 1070 * encoding depends on Facility Selector
1078 */ 1071 */
1079 switch (iif->acmsg.FacilitySelector) { 1072 switch (cmsg->FacilitySelector) {
1080 case CAPI_FACILITY_DTMF: /* ToDo */ 1073 case CAPI_FACILITY_DTMF: /* ToDo */
1081 info = CapiFacilityNotSupported; 1074 info = CapiFacilityNotSupported;
1082 confparam[0] = 2; /* length */ 1075 confparam[0] = 2; /* length */
@@ -1093,7 +1086,7 @@ static void do_facility_req(struct gigaset_capi_ctr *iif,
1093 1086
1094 case CAPI_FACILITY_SUPPSVC: 1087 case CAPI_FACILITY_SUPPSVC:
1095 /* decode Function parameter */ 1088 /* decode Function parameter */
1096 pparam = iif->acmsg.FacilityRequestParameter; 1089 pparam = cmsg->FacilityRequestParameter;
1097 if (pparam == NULL || *pparam < 2) { 1090 if (pparam == NULL || *pparam < 2) {
1098 dev_notice(cs->dev, "%s: %s missing\n", "FACILITY_REQ", 1091 dev_notice(cs->dev, "%s: %s missing\n", "FACILITY_REQ",
1099 "Facility Request Parameter"); 1092 "Facility Request Parameter");
@@ -1141,18 +1134,18 @@ static void do_facility_req(struct gigaset_capi_ctr *iif,
1141 } 1134 }
1142 1135
1143 /* send FACILITY_CONF with given Info and confirmation parameter */ 1136 /* send FACILITY_CONF with given Info and confirmation parameter */
1144 capi_cmsg_answer(&iif->acmsg); 1137 capi_cmsg_answer(cmsg);
1145 iif->acmsg.Info = info; 1138 cmsg->Info = info;
1146 iif->acmsg.FacilityConfirmationParameter = confparam; 1139 cmsg->FacilityConfirmationParameter = confparam;
1147 msgsize += confparam[0]; /* length */ 1140 msgsize += confparam[0]; /* length */
1148 cskb = alloc_skb(msgsize, GFP_ATOMIC); 1141 cskb = alloc_skb(msgsize, GFP_ATOMIC);
1149 if (!cskb) { 1142 if (!cskb) {
1150 dev_err(cs->dev, "%s: out of memory\n", __func__); 1143 dev_err(cs->dev, "%s: out of memory\n", __func__);
1151 return; 1144 return;
1152 } 1145 }
1153 capi_cmsg2message(&iif->acmsg, __skb_put(cskb, msgsize)); 1146 capi_cmsg2message(cmsg, __skb_put(cskb, msgsize));
1154 dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg); 1147 dump_cmsg(DEBUG_CMD, __func__, cmsg);
1155 capi_ctr_handle_message(&iif->ctr, ap->id, cskb); 1148 capi_ctr_handle_message(&iif->ctr, ap->id, cskb);
1156} 1149}
1157 1150
1158 1151
@@ -1207,8 +1200,8 @@ static void do_connect_req(struct gigaset_capi_ctr *iif,
1207 u16 info; 1200 u16 info;
1208 1201
1209 /* decode message */ 1202 /* decode message */
1210 capi_message2cmsg(&iif->acmsg, skb->data); 1203 capi_message2cmsg(cmsg, skb->data);
1211 dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg); 1204 dump_cmsg(DEBUG_CMD, __func__, cmsg);
1212 1205
1213 /* get free B channel & construct PLCI */ 1206 /* get free B channel & construct PLCI */
1214 bcs = gigaset_get_free_channel(cs); 1207 bcs = gigaset_get_free_channel(cs);
@@ -1411,8 +1404,16 @@ static void do_connect_req(struct gigaset_capi_ctr *iif,
1411 "CONNECT_REQ", "Calling pty subaddr"); 1404 "CONNECT_REQ", "Calling pty subaddr");
1412 ignore_cstruct_param(cs, cmsg->LLC, 1405 ignore_cstruct_param(cs, cmsg->LLC,
1413 "CONNECT_REQ", "LLC"); 1406 "CONNECT_REQ", "LLC");
1414 ignore_cmstruct_param(cs, cmsg->AdditionalInfo, 1407 if (cmsg->AdditionalInfo != CAPI_DEFAULT) {
1415 "CONNECT_REQ", "Additional Info"); 1408 ignore_cstruct_param(cs, cmsg->BChannelinformation,
1409 "CONNECT_REQ", "B Channel Information");
1410 ignore_cstruct_param(cs, cmsg->Keypadfacility,
1411 "CONNECT_REQ", "Keypad Facility");
1412 ignore_cstruct_param(cs, cmsg->Useruserdata,
1413 "CONNECT_REQ", "User-User Data");
1414 ignore_cstruct_param(cs, cmsg->Facilitydataarray,
1415 "CONNECT_REQ", "Facility Data Array");
1416 }
1416 1417
1417 /* encode parameter: B channel to use */ 1418 /* encode parameter: B channel to use */
1418 commands[AT_ISO] = kmalloc(9, GFP_KERNEL); 1419 commands[AT_ISO] = kmalloc(9, GFP_KERNEL);
@@ -1458,8 +1459,8 @@ static void do_connect_resp(struct gigaset_capi_ctr *iif,
1458 int channel; 1459 int channel;
1459 1460
1460 /* decode message */ 1461 /* decode message */
1461 capi_message2cmsg(&iif->acmsg, skb->data); 1462 capi_message2cmsg(cmsg, skb->data);
1462 dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg); 1463 dump_cmsg(DEBUG_CMD, __func__, cmsg);
1463 dev_kfree_skb(skb); 1464 dev_kfree_skb(skb);
1464 1465
1465 /* extract and check channel number from PLCI */ 1466 /* extract and check channel number from PLCI */
@@ -1524,8 +1525,16 @@ static void do_connect_resp(struct gigaset_capi_ctr *iif,
1524 "CONNECT_RESP", "Connected Subaddress"); 1525 "CONNECT_RESP", "Connected Subaddress");
1525 ignore_cstruct_param(cs, cmsg->LLC, 1526 ignore_cstruct_param(cs, cmsg->LLC,
1526 "CONNECT_RESP", "LLC"); 1527 "CONNECT_RESP", "LLC");
1527 ignore_cmstruct_param(cs, cmsg->AdditionalInfo, 1528 if (cmsg->AdditionalInfo != CAPI_DEFAULT) {
1528 "CONNECT_RESP", "Additional Info"); 1529 ignore_cstruct_param(cs, cmsg->BChannelinformation,
1530 "CONNECT_RESP", "BChannel Information");
1531 ignore_cstruct_param(cs, cmsg->Keypadfacility,
1532 "CONNECT_RESP", "Keypad Facility");
1533 ignore_cstruct_param(cs, cmsg->Useruserdata,
1534 "CONNECT_RESP", "User-User Data");
1535 ignore_cstruct_param(cs, cmsg->Facilitydataarray,
1536 "CONNECT_RESP", "Facility Data Array");
1537 }
1529 1538
1530 /* Accept call */ 1539 /* Accept call */
1531 if (!gigaset_add_event(cs, &cs->bcs[channel-1].at_state, 1540 if (!gigaset_add_event(cs, &cs->bcs[channel-1].at_state,
@@ -1587,17 +1596,18 @@ static void do_connect_b3_req(struct gigaset_capi_ctr *iif,
1587 struct sk_buff *skb) 1596 struct sk_buff *skb)
1588{ 1597{
1589 struct cardstate *cs = iif->ctr.driverdata; 1598 struct cardstate *cs = iif->ctr.driverdata;
1599 _cmsg *cmsg = &iif->acmsg;
1590 int channel; 1600 int channel;
1591 1601
1592 /* decode message */ 1602 /* decode message */
1593 capi_message2cmsg(&iif->acmsg, skb->data); 1603 capi_message2cmsg(cmsg, skb->data);
1594 dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg); 1604 dump_cmsg(DEBUG_CMD, __func__, cmsg);
1595 1605
1596 /* extract and check channel number from PLCI */ 1606 /* extract and check channel number from PLCI */
1597 channel = (iif->acmsg.adr.adrPLCI >> 8) & 0xff; 1607 channel = (cmsg->adr.adrPLCI >> 8) & 0xff;
1598 if (!channel || channel > cs->channels) { 1608 if (!channel || channel > cs->channels) {
1599 dev_notice(cs->dev, "%s: invalid %s 0x%02x\n", 1609 dev_notice(cs->dev, "%s: invalid %s 0x%02x\n",
1600 "CONNECT_B3_REQ", "PLCI", iif->acmsg.adr.adrPLCI); 1610 "CONNECT_B3_REQ", "PLCI", cmsg->adr.adrPLCI);
1601 send_conf(iif, ap, skb, CapiIllContrPlciNcci); 1611 send_conf(iif, ap, skb, CapiIllContrPlciNcci);
1602 return; 1612 return;
1603 } 1613 }
@@ -1606,14 +1616,12 @@ static void do_connect_b3_req(struct gigaset_capi_ctr *iif,
1606 ap->connected = APCONN_ACTIVE; 1616 ap->connected = APCONN_ACTIVE;
1607 1617
1608 /* build NCCI: always 1 (one B3 connection only) */ 1618 /* build NCCI: always 1 (one B3 connection only) */
1609 iif->acmsg.adr.adrNCCI |= 1 << 16; 1619 cmsg->adr.adrNCCI |= 1 << 16;
1610 1620
1611 /* NCPI parameter: not applicable for B3 Transparent */ 1621 /* NCPI parameter: not applicable for B3 Transparent */
1612 ignore_cstruct_param(cs, iif->acmsg.NCPI, 1622 ignore_cstruct_param(cs, cmsg->NCPI, "CONNECT_B3_REQ", "NCPI");
1613 "CONNECT_B3_REQ", "NCPI"); 1623 send_conf(iif, ap, skb, (cmsg->NCPI && cmsg->NCPI[0]) ?
1614 send_conf(iif, ap, skb, 1624 CapiNcpiNotSupportedByProtocol : CapiSuccess);
1615 (iif->acmsg.NCPI && iif->acmsg.NCPI[0]) ?
1616 CapiNcpiNotSupportedByProtocol : CapiSuccess);
1617} 1625}
1618 1626
1619/* 1627/*
@@ -1628,27 +1636,28 @@ static void do_connect_b3_resp(struct gigaset_capi_ctr *iif,
1628 struct sk_buff *skb) 1636 struct sk_buff *skb)
1629{ 1637{
1630 struct cardstate *cs = iif->ctr.driverdata; 1638 struct cardstate *cs = iif->ctr.driverdata;
1631 struct bc_state *bcs = NULL; 1639 _cmsg *cmsg = &iif->acmsg;
1640 struct bc_state *bcs;
1632 int channel; 1641 int channel;
1633 unsigned int msgsize; 1642 unsigned int msgsize;
1634 u8 command; 1643 u8 command;
1635 1644
1636 /* decode message */ 1645 /* decode message */
1637 capi_message2cmsg(&iif->acmsg, skb->data); 1646 capi_message2cmsg(cmsg, skb->data);
1638 dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg); 1647 dump_cmsg(DEBUG_CMD, __func__, cmsg);
1639 1648
1640 /* extract and check channel number and NCCI */ 1649 /* extract and check channel number and NCCI */
1641 channel = (iif->acmsg.adr.adrNCCI >> 8) & 0xff; 1650 channel = (cmsg->adr.adrNCCI >> 8) & 0xff;
1642 if (!channel || channel > cs->channels || 1651 if (!channel || channel > cs->channels ||
1643 ((iif->acmsg.adr.adrNCCI >> 16) & 0xffff) != 1) { 1652 ((cmsg->adr.adrNCCI >> 16) & 0xffff) != 1) {
1644 dev_notice(cs->dev, "%s: invalid %s 0x%02x\n", 1653 dev_notice(cs->dev, "%s: invalid %s 0x%02x\n",
1645 "CONNECT_B3_RESP", "NCCI", iif->acmsg.adr.adrNCCI); 1654 "CONNECT_B3_RESP", "NCCI", cmsg->adr.adrNCCI);
1646 dev_kfree_skb(skb); 1655 dev_kfree_skb(skb);
1647 return; 1656 return;
1648 } 1657 }
1649 bcs = &cs->bcs[channel-1]; 1658 bcs = &cs->bcs[channel-1];
1650 1659
1651 if (iif->acmsg.Reject) { 1660 if (cmsg->Reject) {
1652 /* Reject: clear B3 connect received flag */ 1661 /* Reject: clear B3 connect received flag */
1653 ap->connected = APCONN_SETUP; 1662 ap->connected = APCONN_SETUP;
1654 1663
@@ -1673,11 +1682,11 @@ static void do_connect_b3_resp(struct gigaset_capi_ctr *iif,
1673 command = CAPI_CONNECT_B3_ACTIVE; 1682 command = CAPI_CONNECT_B3_ACTIVE;
1674 msgsize = CAPI_CONNECT_B3_ACTIVE_IND_BASELEN; 1683 msgsize = CAPI_CONNECT_B3_ACTIVE_IND_BASELEN;
1675 } 1684 }
1676 capi_cmsg_header(&iif->acmsg, ap->id, command, CAPI_IND, 1685 capi_cmsg_header(cmsg, ap->id, command, CAPI_IND,
1677 ap->nextMessageNumber++, iif->acmsg.adr.adrNCCI); 1686 ap->nextMessageNumber++, cmsg->adr.adrNCCI);
1678 __skb_trim(skb, msgsize); 1687 __skb_trim(skb, msgsize);
1679 capi_cmsg2message(&iif->acmsg, skb->data); 1688 capi_cmsg2message(cmsg, skb->data);
1680 dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg); 1689 dump_cmsg(DEBUG_CMD, __func__, cmsg);
1681 capi_ctr_handle_message(&iif->ctr, ap->id, skb); 1690 capi_ctr_handle_message(&iif->ctr, ap->id, skb);
1682} 1691}
1683 1692
@@ -1691,28 +1700,37 @@ static void do_disconnect_req(struct gigaset_capi_ctr *iif,
1691 struct sk_buff *skb) 1700 struct sk_buff *skb)
1692{ 1701{
1693 struct cardstate *cs = iif->ctr.driverdata; 1702 struct cardstate *cs = iif->ctr.driverdata;
1703 _cmsg *cmsg = &iif->acmsg;
1694 struct bc_state *bcs; 1704 struct bc_state *bcs;
1695 _cmsg *b3cmsg; 1705 _cmsg *b3cmsg;
1696 struct sk_buff *b3skb; 1706 struct sk_buff *b3skb;
1697 int channel; 1707 int channel;
1698 1708
1699 /* decode message */ 1709 /* decode message */
1700 capi_message2cmsg(&iif->acmsg, skb->data); 1710 capi_message2cmsg(cmsg, skb->data);
1701 dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg); 1711 dump_cmsg(DEBUG_CMD, __func__, cmsg);
1702 1712
1703 /* extract and check channel number from PLCI */ 1713 /* extract and check channel number from PLCI */
1704 channel = (iif->acmsg.adr.adrPLCI >> 8) & 0xff; 1714 channel = (cmsg->adr.adrPLCI >> 8) & 0xff;
1705 if (!channel || channel > cs->channels) { 1715 if (!channel || channel > cs->channels) {
1706 dev_notice(cs->dev, "%s: invalid %s 0x%02x\n", 1716 dev_notice(cs->dev, "%s: invalid %s 0x%02x\n",
1707 "DISCONNECT_REQ", "PLCI", iif->acmsg.adr.adrPLCI); 1717 "DISCONNECT_REQ", "PLCI", cmsg->adr.adrPLCI);
1708 send_conf(iif, ap, skb, CapiIllContrPlciNcci); 1718 send_conf(iif, ap, skb, CapiIllContrPlciNcci);
1709 return; 1719 return;
1710 } 1720 }
1711 bcs = cs->bcs + channel - 1; 1721 bcs = cs->bcs + channel - 1;
1712 1722
1713 /* ToDo: process parameter: Additional info */ 1723 /* ToDo: process parameter: Additional info */
1714 ignore_cmstruct_param(cs, iif->acmsg.AdditionalInfo, 1724 if (cmsg->AdditionalInfo != CAPI_DEFAULT) {
1715 "DISCONNECT_REQ", "Additional Info"); 1725 ignore_cstruct_param(cs, cmsg->BChannelinformation,
1726 "DISCONNECT_REQ", "B Channel Information");
1727 ignore_cstruct_param(cs, cmsg->Keypadfacility,
1728 "DISCONNECT_REQ", "Keypad Facility");
1729 ignore_cstruct_param(cs, cmsg->Useruserdata,
1730 "DISCONNECT_REQ", "User-User Data");
1731 ignore_cstruct_param(cs, cmsg->Facilitydataarray,
1732 "DISCONNECT_REQ", "Facility Data Array");
1733 }
1716 1734
1717 /* skip if DISCONNECT_IND already sent */ 1735 /* skip if DISCONNECT_IND already sent */
1718 if (!ap->connected) 1736 if (!ap->connected)
@@ -1733,7 +1751,7 @@ static void do_disconnect_req(struct gigaset_capi_ctr *iif,
1733 } 1751 }
1734 capi_cmsg_header(b3cmsg, ap->id, CAPI_DISCONNECT_B3, CAPI_IND, 1752 capi_cmsg_header(b3cmsg, ap->id, CAPI_DISCONNECT_B3, CAPI_IND,
1735 ap->nextMessageNumber++, 1753 ap->nextMessageNumber++,
1736 iif->acmsg.adr.adrPLCI | (1 << 16)); 1754 cmsg->adr.adrPLCI | (1 << 16));
1737 b3cmsg->Reason_B3 = CapiProtocolErrorLayer1; 1755 b3cmsg->Reason_B3 = CapiProtocolErrorLayer1;
1738 b3skb = alloc_skb(CAPI_DISCONNECT_B3_IND_BASELEN, GFP_KERNEL); 1756 b3skb = alloc_skb(CAPI_DISCONNECT_B3_IND_BASELEN, GFP_KERNEL);
1739 if (b3skb == NULL) { 1757 if (b3skb == NULL) {
@@ -1769,18 +1787,19 @@ static void do_disconnect_b3_req(struct gigaset_capi_ctr *iif,
1769 struct sk_buff *skb) 1787 struct sk_buff *skb)
1770{ 1788{
1771 struct cardstate *cs = iif->ctr.driverdata; 1789 struct cardstate *cs = iif->ctr.driverdata;
1790 _cmsg *cmsg = &iif->acmsg;
1772 int channel; 1791 int channel;
1773 1792
1774 /* decode message */ 1793 /* decode message */
1775 capi_message2cmsg(&iif->acmsg, skb->data); 1794 capi_message2cmsg(cmsg, skb->data);
1776 dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg); 1795 dump_cmsg(DEBUG_CMD, __func__, cmsg);
1777 1796
1778 /* extract and check channel number and NCCI */ 1797 /* extract and check channel number and NCCI */
1779 channel = (iif->acmsg.adr.adrNCCI >> 8) & 0xff; 1798 channel = (cmsg->adr.adrNCCI >> 8) & 0xff;
1780 if (!channel || channel > cs->channels || 1799 if (!channel || channel > cs->channels ||
1781 ((iif->acmsg.adr.adrNCCI >> 16) & 0xffff) != 1) { 1800 ((cmsg->adr.adrNCCI >> 16) & 0xffff) != 1) {
1782 dev_notice(cs->dev, "%s: invalid %s 0x%02x\n", 1801 dev_notice(cs->dev, "%s: invalid %s 0x%02x\n",
1783 "DISCONNECT_B3_REQ", "NCCI", iif->acmsg.adr.adrNCCI); 1802 "DISCONNECT_B3_REQ", "NCCI", cmsg->adr.adrNCCI);
1784 send_conf(iif, ap, skb, CapiIllContrPlciNcci); 1803 send_conf(iif, ap, skb, CapiIllContrPlciNcci);
1785 return; 1804 return;
1786 } 1805 }
@@ -1803,11 +1822,10 @@ static void do_disconnect_b3_req(struct gigaset_capi_ctr *iif,
1803 gigaset_schedule_event(cs); 1822 gigaset_schedule_event(cs);
1804 1823
1805 /* NCPI parameter: not applicable for B3 Transparent */ 1824 /* NCPI parameter: not applicable for B3 Transparent */
1806 ignore_cstruct_param(cs, iif->acmsg.NCPI, 1825 ignore_cstruct_param(cs, cmsg->NCPI,
1807 "DISCONNECT_B3_REQ", "NCPI"); 1826 "DISCONNECT_B3_REQ", "NCPI");
1808 send_conf(iif, ap, skb, 1827 send_conf(iif, ap, skb, (cmsg->NCPI && cmsg->NCPI[0]) ?
1809 (iif->acmsg.NCPI && iif->acmsg.NCPI[0]) ? 1828 CapiNcpiNotSupportedByProtocol : CapiSuccess);
1810 CapiNcpiNotSupportedByProtocol : CapiSuccess);
1811} 1829}
1812 1830
1813/* 1831/*