@@ -798,6 +798,12 @@ union sixaxis_output_report_01 {
798
798
__u8 buf [36 ];
799
799
};
800
800
801
+ #define DS4_REPORT_0x02_SIZE 37
802
+ #define DS4_REPORT_0x05_SIZE 32
803
+ #define DS4_REPORT_0x11_SIZE 78
804
+ #define DS4_REPORT_0x81_SIZE 7
805
+ #define SIXAXIS_REPORT_0xF2_SIZE 18
806
+
801
807
static spinlock_t sony_dev_list_lock ;
802
808
static LIST_HEAD (sony_device_list );
803
809
static DEFINE_IDA (sony_device_id_allocator );
@@ -811,6 +817,7 @@ struct sony_sc {
811
817
struct work_struct state_worker ;
812
818
struct power_supply battery ;
813
819
int device_id ;
820
+ __u8 * output_report_dmabuf ;
814
821
815
822
#ifdef CONFIG_SONY_FF
816
823
__u8 left ;
@@ -1142,9 +1149,20 @@ static int sixaxis_set_operational_usb(struct hid_device *hdev)
1142
1149
1143
1150
static int sixaxis_set_operational_bt (struct hid_device * hdev )
1144
1151
{
1145
- unsigned char buf [] = { 0xf4 , 0x42 , 0x03 , 0x00 , 0x00 };
1146
- return hid_hw_raw_request (hdev , buf [0 ], buf , sizeof (buf ),
1152
+ static const __u8 report [] = { 0xf4 , 0x42 , 0x03 , 0x00 , 0x00 };
1153
+ __u8 * buf ;
1154
+ int ret ;
1155
+
1156
+ buf = kmemdup (report , sizeof (report ), GFP_KERNEL );
1157
+ if (!buf )
1158
+ return - ENOMEM ;
1159
+
1160
+ ret = hid_hw_raw_request (hdev , buf [0 ], buf , sizeof (report ),
1147
1161
HID_FEATURE_REPORT , HID_REQ_SET_REPORT );
1162
+
1163
+ kfree (buf );
1164
+
1165
+ return ret ;
1148
1166
}
1149
1167
1150
1168
/*
@@ -1153,10 +1171,19 @@ static int sixaxis_set_operational_bt(struct hid_device *hdev)
1153
1171
*/
1154
1172
static int dualshock4_set_operational_bt (struct hid_device * hdev )
1155
1173
{
1156
- __u8 buf [37 ] = { 0 };
1174
+ __u8 * buf ;
1175
+ int ret ;
1157
1176
1158
- return hid_hw_raw_request (hdev , 0x02 , buf , sizeof (buf ),
1177
+ buf = kmalloc (DS4_REPORT_0x02_SIZE , GFP_KERNEL );
1178
+ if (!buf )
1179
+ return - ENOMEM ;
1180
+
1181
+ ret = hid_hw_raw_request (hdev , 0x02 , buf , DS4_REPORT_0x02_SIZE ,
1159
1182
HID_FEATURE_REPORT , HID_REQ_GET_REPORT );
1183
+
1184
+ kfree (buf );
1185
+
1186
+ return ret ;
1160
1187
}
1161
1188
1162
1189
static void sixaxis_set_leds_from_id (int id , __u8 values [MAX_LEDS ])
@@ -1471,9 +1498,7 @@ static int sony_leds_init(struct sony_sc *sc)
1471
1498
1472
1499
static void sixaxis_state_worker (struct work_struct * work )
1473
1500
{
1474
- struct sony_sc * sc = container_of (work , struct sony_sc , state_worker );
1475
- int n ;
1476
- union sixaxis_output_report_01 report = {
1501
+ static const union sixaxis_output_report_01 default_report = {
1477
1502
.buf = {
1478
1503
0x01 ,
1479
1504
0x00 , 0xff , 0x00 , 0xff , 0x00 ,
@@ -1485,20 +1510,27 @@ static void sixaxis_state_worker(struct work_struct *work)
1485
1510
0x00 , 0x00 , 0x00 , 0x00 , 0x00
1486
1511
}
1487
1512
};
1513
+ struct sony_sc * sc = container_of (work , struct sony_sc , state_worker );
1514
+ struct sixaxis_output_report * report =
1515
+ (struct sixaxis_output_report * )sc -> output_report_dmabuf ;
1516
+ int n ;
1517
+
1518
+ /* Initialize the report with default values */
1519
+ memcpy (report , & default_report , sizeof (struct sixaxis_output_report ));
1488
1520
1489
1521
#ifdef CONFIG_SONY_FF
1490
- report . data . rumble .right_motor_on = sc -> right ? 1 : 0 ;
1491
- report . data . rumble .left_motor_force = sc -> left ;
1522
+ report -> rumble .right_motor_on = sc -> right ? 1 : 0 ;
1523
+ report -> rumble .left_motor_force = sc -> left ;
1492
1524
#endif
1493
1525
1494
- report . data . leds_bitmap |= sc -> led_state [0 ] << 1 ;
1495
- report . data . leds_bitmap |= sc -> led_state [1 ] << 2 ;
1496
- report . data . leds_bitmap |= sc -> led_state [2 ] << 3 ;
1497
- report . data . leds_bitmap |= sc -> led_state [3 ] << 4 ;
1526
+ report -> leds_bitmap |= sc -> led_state [0 ] << 1 ;
1527
+ report -> leds_bitmap |= sc -> led_state [1 ] << 2 ;
1528
+ report -> leds_bitmap |= sc -> led_state [2 ] << 3 ;
1529
+ report -> leds_bitmap |= sc -> led_state [3 ] << 4 ;
1498
1530
1499
1531
/* Set flag for all leds off, required for 3rd party INTEC controller */
1500
- if ((report . data . leds_bitmap & 0x1E ) == 0 )
1501
- report . data . leds_bitmap |= 0x20 ;
1532
+ if ((report -> leds_bitmap & 0x1E ) == 0 )
1533
+ report -> leds_bitmap |= 0x20 ;
1502
1534
1503
1535
/*
1504
1536
* The LEDs in the report are indexed in reverse order to their
@@ -1511,28 +1543,30 @@ static void sixaxis_state_worker(struct work_struct *work)
1511
1543
*/
1512
1544
for (n = 0 ; n < 4 ; n ++ ) {
1513
1545
if (sc -> led_delay_on [n ] || sc -> led_delay_off [n ]) {
1514
- report . data . led [3 - n ].duty_off = sc -> led_delay_off [n ];
1515
- report . data . led [3 - n ].duty_on = sc -> led_delay_on [n ];
1546
+ report -> led [3 - n ].duty_off = sc -> led_delay_off [n ];
1547
+ report -> led [3 - n ].duty_on = sc -> led_delay_on [n ];
1516
1548
}
1517
1549
}
1518
1550
1519
- hid_hw_raw_request (sc -> hdev , report .data .report_id , report .buf ,
1520
- sizeof (report ), HID_OUTPUT_REPORT , HID_REQ_SET_REPORT );
1551
+ hid_hw_raw_request (sc -> hdev , report -> report_id , (__u8 * )report ,
1552
+ sizeof (struct sixaxis_output_report ),
1553
+ HID_OUTPUT_REPORT , HID_REQ_SET_REPORT );
1521
1554
}
1522
1555
1523
1556
static void dualshock4_state_worker (struct work_struct * work )
1524
1557
{
1525
1558
struct sony_sc * sc = container_of (work , struct sony_sc , state_worker );
1526
1559
struct hid_device * hdev = sc -> hdev ;
1560
+ __u8 * buf = sc -> output_report_dmabuf ;
1527
1561
int offset ;
1528
1562
1529
- __u8 buf [78 ] = { 0 };
1530
-
1531
1563
if (sc -> quirks & DUALSHOCK4_CONTROLLER_USB ) {
1564
+ memset (buf , 0 , DS4_REPORT_0x05_SIZE );
1532
1565
buf [0 ] = 0x05 ;
1533
1566
buf [1 ] = 0xFF ;
1534
1567
offset = 4 ;
1535
1568
} else {
1569
+ memset (buf , 0 , DS4_REPORT_0x11_SIZE );
1536
1570
buf [0 ] = 0x11 ;
1537
1571
buf [1 ] = 0xB0 ;
1538
1572
buf [3 ] = 0x0F ;
@@ -1560,12 +1594,33 @@ static void dualshock4_state_worker(struct work_struct *work)
1560
1594
buf [offset ++ ] = sc -> led_delay_off [3 ];
1561
1595
1562
1596
if (sc -> quirks & DUALSHOCK4_CONTROLLER_USB )
1563
- hid_hw_output_report (hdev , buf , 32 );
1597
+ hid_hw_output_report (hdev , buf , DS4_REPORT_0x05_SIZE );
1564
1598
else
1565
- hid_hw_raw_request (hdev , 0x11 , buf , 78 ,
1599
+ hid_hw_raw_request (hdev , 0x11 , buf , DS4_REPORT_0x11_SIZE ,
1566
1600
HID_OUTPUT_REPORT , HID_REQ_SET_REPORT );
1567
1601
}
1568
1602
1603
+ static int sony_allocate_output_report (struct sony_sc * sc )
1604
+ {
1605
+ if (sc -> quirks & SIXAXIS_CONTROLLER )
1606
+ sc -> output_report_dmabuf =
1607
+ kmalloc (sizeof (union sixaxis_output_report_01 ),
1608
+ GFP_KERNEL );
1609
+ else if (sc -> quirks & DUALSHOCK4_CONTROLLER_BT )
1610
+ sc -> output_report_dmabuf = kmalloc (DS4_REPORT_0x11_SIZE ,
1611
+ GFP_KERNEL );
1612
+ else if (sc -> quirks & DUALSHOCK4_CONTROLLER_USB )
1613
+ sc -> output_report_dmabuf = kmalloc (DS4_REPORT_0x05_SIZE ,
1614
+ GFP_KERNEL );
1615
+ else
1616
+ return 0 ;
1617
+
1618
+ if (!sc -> output_report_dmabuf )
1619
+ return - ENOMEM ;
1620
+
1621
+ return 0 ;
1622
+ }
1623
+
1569
1624
#ifdef CONFIG_SONY_FF
1570
1625
static int sony_play_effect (struct input_dev * dev , void * data ,
1571
1626
struct ff_effect * effect )
@@ -1754,6 +1809,7 @@ static int sony_get_bt_devaddr(struct sony_sc *sc)
1754
1809
1755
1810
static int sony_check_add (struct sony_sc * sc )
1756
1811
{
1812
+ __u8 * buf = NULL ;
1757
1813
int n , ret ;
1758
1814
1759
1815
if ((sc -> quirks & DUALSHOCK4_CONTROLLER_BT ) ||
@@ -1769,36 +1825,44 @@ static int sony_check_add(struct sony_sc *sc)
1769
1825
return 0 ;
1770
1826
}
1771
1827
} else if (sc -> quirks & DUALSHOCK4_CONTROLLER_USB ) {
1772
- __u8 buf [7 ];
1828
+ buf = kmalloc (DS4_REPORT_0x81_SIZE , GFP_KERNEL );
1829
+ if (!buf )
1830
+ return - ENOMEM ;
1773
1831
1774
1832
/*
1775
1833
* The MAC address of a DS4 controller connected via USB can be
1776
1834
* retrieved with feature report 0x81. The address begins at
1777
1835
* offset 1.
1778
1836
*/
1779
- ret = hid_hw_raw_request (sc -> hdev , 0x81 , buf , sizeof (buf ),
1780
- HID_FEATURE_REPORT , HID_REQ_GET_REPORT );
1837
+ ret = hid_hw_raw_request (sc -> hdev , 0x81 , buf ,
1838
+ DS4_REPORT_0x81_SIZE , HID_FEATURE_REPORT ,
1839
+ HID_REQ_GET_REPORT );
1781
1840
1782
- if (ret != 7 ) {
1841
+ if (ret != DS4_REPORT_0x81_SIZE ) {
1783
1842
hid_err (sc -> hdev , "failed to retrieve feature report 0x81 with the DualShock 4 MAC address\n" );
1784
- return ret < 0 ? ret : - EINVAL ;
1843
+ ret = ret < 0 ? ret : - EINVAL ;
1844
+ goto out_free ;
1785
1845
}
1786
1846
1787
1847
memcpy (sc -> mac_address , & buf [1 ], sizeof (sc -> mac_address ));
1788
1848
} else if (sc -> quirks & SIXAXIS_CONTROLLER_USB ) {
1789
- __u8 buf [18 ];
1849
+ buf = kmalloc (SIXAXIS_REPORT_0xF2_SIZE , GFP_KERNEL );
1850
+ if (!buf )
1851
+ return - ENOMEM ;
1790
1852
1791
1853
/*
1792
1854
* The MAC address of a Sixaxis controller connected via USB can
1793
1855
* be retrieved with feature report 0xf2. The address begins at
1794
1856
* offset 4.
1795
1857
*/
1796
- ret = hid_hw_raw_request (sc -> hdev , 0xf2 , buf , sizeof (buf ),
1797
- HID_FEATURE_REPORT , HID_REQ_GET_REPORT );
1858
+ ret = hid_hw_raw_request (sc -> hdev , 0xf2 , buf ,
1859
+ SIXAXIS_REPORT_0xF2_SIZE , HID_FEATURE_REPORT ,
1860
+ HID_REQ_GET_REPORT );
1798
1861
1799
- if (ret != 18 ) {
1862
+ if (ret != SIXAXIS_REPORT_0xF2_SIZE ) {
1800
1863
hid_err (sc -> hdev , "failed to retrieve feature report 0xf2 with the Sixaxis MAC address\n" );
1801
- return ret < 0 ? ret : - EINVAL ;
1864
+ ret = ret < 0 ? ret : - EINVAL ;
1865
+ goto out_free ;
1802
1866
}
1803
1867
1804
1868
/*
@@ -1811,7 +1875,13 @@ static int sony_check_add(struct sony_sc *sc)
1811
1875
return 0 ;
1812
1876
}
1813
1877
1814
- return sony_check_add_dev_list (sc );
1878
+ ret = sony_check_add_dev_list (sc );
1879
+
1880
+ out_free :
1881
+
1882
+ kfree (buf );
1883
+
1884
+ return ret ;
1815
1885
}
1816
1886
1817
1887
static int sony_set_device_id (struct sony_sc * sc )
@@ -1895,6 +1965,12 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
1895
1965
return ret ;
1896
1966
}
1897
1967
1968
+ ret = sony_allocate_output_report (sc );
1969
+ if (ret < 0 ) {
1970
+ hid_err (hdev , "failed to allocate the output report buffer\n" );
1971
+ goto err_stop ;
1972
+ }
1973
+
1898
1974
ret = sony_set_device_id (sc );
1899
1975
if (ret < 0 ) {
1900
1976
hid_err (hdev , "failed to allocate the device id\n" );
@@ -1984,6 +2060,7 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
1984
2060
if (sc -> quirks & SONY_BATTERY_SUPPORT )
1985
2061
sony_battery_remove (sc );
1986
2062
sony_cancel_work_sync (sc );
2063
+ kfree (sc -> output_report_dmabuf );
1987
2064
sony_remove_dev_list (sc );
1988
2065
sony_release_device_id (sc );
1989
2066
hid_hw_stop (hdev );
@@ -2004,6 +2081,8 @@ static void sony_remove(struct hid_device *hdev)
2004
2081
2005
2082
sony_cancel_work_sync (sc );
2006
2083
2084
+ kfree (sc -> output_report_dmabuf );
2085
+
2007
2086
sony_remove_dev_list (sc );
2008
2087
2009
2088
sony_release_device_id (sc );
0 commit comments