summaryrefslogtreecommitdiff
path: root/kernel/drv/oss_usb
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/drv/oss_usb')
-rw-r--r--kernel/drv/oss_usb/.config3
-rw-r--r--kernel/drv/oss_usb/.devices28
-rw-r--r--kernel/drv/oss_usb/.name1
-rw-r--r--kernel/drv/oss_usb/.params2
-rwxr-xr-xkernel/drv/oss_usb/midisport1x1_fw.h677
-rwxr-xr-xkernel/drv/oss_usb/midisport2x2_fw.h756
-rw-r--r--kernel/drv/oss_usb/oss_usb.c2505
-rw-r--r--kernel/drv/oss_usb/oss_usb.man56
-rw-r--r--kernel/drv/oss_usb/ossusb.h246
-rw-r--r--kernel/drv/oss_usb/ossusb_audio.c1425
-rw-r--r--kernel/drv/oss_usb/ossusb_midi.c442
-rw-r--r--kernel/drv/oss_usb/ossusb_midisport.c957
-rw-r--r--kernel/drv/oss_usb/ossusb_ymhmidi.c653
-rwxr-xr-xkernel/drv/oss_usb/oxygen8_fw.h678
14 files changed, 8429 insertions, 0 deletions
diff --git a/kernel/drv/oss_usb/.config b/kernel/drv/oss_usb/.config
new file mode 100644
index 0000000..17d7733
--- /dev/null
+++ b/kernel/drv/oss_usb/.config
@@ -0,0 +1,3 @@
+bus=USB
+targetos=SunOS
+targetos=Linux
diff --git a/kernel/drv/oss_usb/.devices b/kernel/drv/oss_usb/.devices
new file mode 100644
index 0000000..456a797
--- /dev/null
+++ b/kernel/drv/oss_usb/.devices
@@ -0,0 +1,28 @@
+oss_usb usbif,class1 Generic USB audio/MIDI device (BETA)
+oss_usb usbif41e,3000 Creative Sound Blaster Extigy (BETA)
+oss_usb usbif41e,3010 Creative Sound Blaster MP3+ USB
+oss_usb usbif41e,3020 Creative Audigy2 NX USB (BETA)
+oss_usb usbif46d,8b2 Logitec Quickcam Pro 4000 (mic) (BETA)
+oss_usb usbif46d,a01 Logitec USB Headset
+oss_usb usbif471,311 Philips ToUcam Pro (mic) (BETA)
+oss_usb usbif672,1041 Labtec LCS1040 Speaker System (BETA)
+oss_usb usbifd8c,c C-Media USB audio adapter - model1
+oss_usb usbifd8c,103 C-Media USB audio adapter - model2
+oss_usb usbifd8c,102 C-Media USB 2/4/6/8ch audio adapter
+oss_usb usbif6f8,c000 Hercules Gamesurround MUSE Pocket (BETA)
+oss_usb usb763,1010 M Audio USB MIDISPORT 1x1 (BETA)
+oss_usb usb763,1011 M Audio USB MIDISPORT 1x1 (BETA)
+oss_usb usb763,1001 M Audio USB MIDISPORT 2x2 (BETA)
+oss_usb usb763,1002 M Audio USB MIDISPORT 2x2 (BETA)
+oss_usb usb763,1031 M Audio USB MIDISPORT 8x8 (BETA)
+oss_usb usbif763,2001 M Audio USB AudioSport Quatro (BETA)
+oss_usb usbif763,2002 M Audio USB AudioSport Duo (BETA)
+oss_usb usbif763,classff Generic M Audio USB MIDI interface (BETA)
+oss_usb usbif763,2007 M Audio Sonica Theater USB (BETA)
+oss_usb usbif763,200d M Audio OmniStudio USB (BETA)
+oss_usb usbif763,2805 M Audio Sonica USB (BETA)
+oss_usb usb763,1014 M Audio Oygen8 MIDI keyboard
+oss_usb usb763,1015 M Audio Oygen8 MIDI keyboard
+oss_usb usbifa92,1010 EGO SYStems RoMI/O USB MIDI interface (BETA)
+oss_usb usb499,1009 Yamaha UX16 USB MIDI interface (BETA)
+oss_usb usb499,101e Yamaha PSR-1K USB MIDI Keyboard (BETA)
diff --git a/kernel/drv/oss_usb/.name b/kernel/drv/oss_usb/.name
new file mode 100644
index 0000000..42bff9b
--- /dev/null
+++ b/kernel/drv/oss_usb/.name
@@ -0,0 +1 @@
+USB audio device support (BETA)
diff --git a/kernel/drv/oss_usb/.params b/kernel/drv/oss_usb/.params
new file mode 100644
index 0000000..01df07b
--- /dev/null
+++ b/kernel/drv/oss_usb/.params
@@ -0,0 +1,2 @@
+int usb_trace=0;
+int usb_mixerstyle=1;
diff --git a/kernel/drv/oss_usb/midisport1x1_fw.h b/kernel/drv/oss_usb/midisport1x1_fw.h
new file mode 100755
index 0000000..0a5eb07
--- /dev/null
+++ b/kernel/drv/oss_usb/midisport1x1_fw.h
@@ -0,0 +1,677 @@
+/*
+ * Purpose: Firmware download for Midiman MIDISport 1x1
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This this source file is released under GPL v2 license (no other versions).
+ * See the COPYING file included in the main directory of this source
+ * distribution for the license terms and conditions.
+ *
+ */
+const struct setup_request midisport1x1_setupRequest[] = {
+ {0x00, 0x05, 0x0002, 0x0000, 0x0000, 0x0000, ""},
+ {0x40, 0xA0, 0x7F92, 0x0000, 0x0001, 0x0001, "\x01"},
+ {0x40, 0xA0, 0x7F92, 0x0000, 0x0001, 0x0001, "\x01"},
+ {0x40, 0xA0, 0x146C, 0x0000, 0x0010, 0x0010,
+ "\xC2\x00\x90\x7F\xA5\xE0\x54\x18\xFF\x13\x13\x13\x54\x1F\x44\x50"},
+ {0x40, 0xA0, 0x147C, 0x0000, 0x0010, 0x0010,
+ "\xF5\x1C\x13\x92\x01\xD2\xE8\x90\x7F\xAB\x74\xFF\xF0\x90\x7F\xA9"},
+ {0x40, 0xA0, 0x148C, 0x0000, 0x0010, 0x0010,
+ "\xF0\x90\x7F\xAA\xF0\x53\x91\xEF\x90\x7F\x95\xE0\x44\xC0\xF0\x90"},
+ {0x40, 0xA0, 0x149C, 0x0000, 0x0010, 0x0010,
+ "\x7F\xAF\xE0\x44\x01\xF0\x90\x7F\xAE\xE0\x44\x05\xF0\xD2\xAF\x12"},
+ {0x40, 0xA0, 0x14AC, 0x0000, 0x000D, 0x000D,
+ "\x17\x5F\x30\x00\xFD\x12\x11\x00\xC2\x00\x80\xF6\x22"},
+ {0x40, 0xA0, 0x1100, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xE9\xE0\x24\x5D\x60\x0D\x14\x70\x03\x02\x12\x44\x24\x02"},
+ {0x40, 0xA0, 0x1110, 0x0000, 0x0010, 0x0010,
+ "\x60\x03\x02\x12\x4A\x90\x7F\xEA\xE0\x75\x08\x00\xF5\x09\xA3\xE0"},
+ {0x40, 0xA0, 0x1120, 0x0000, 0x0010, 0x0010,
+ "\xFE\xE4\x25\x09\xF5\x09\xEE\x35\x08\xF5\x08\x90\x7F\xEE\xE0\x75"},
+ {0x40, 0xA0, 0x1130, 0x0000, 0x0010, 0x0010,
+ "\x0A\x00\xF5\x0B\xA3\xE0\xFE\xE4\x25\x0B\xF5\x0B\xEE\x35\x0A\xF5"},
+ {0x40, 0xA0, 0x1140, 0x0000, 0x0010, 0x0010,
+ "\x0A\x90\x7F\xE8\xE0\x64\xC0\x60\x03\x02\x11\xD4\xE5\x0B\x45\x0A"},
+ {0x40, 0xA0, 0x1150, 0x0000, 0x0010, 0x0010,
+ "\x70\x03\x02\x12\x4A\xC3\xE5\x0B\x94\x40\xE5\x0A\x94\x00\x50\x08"},
+ {0x40, 0xA0, 0x1160, 0x0000, 0x0010, 0x0010,
+ "\x85\x0A\x0C\x85\x0B\x0D\x80\x06\x75\x0C\x00\x75\x0D\x40\x90\x7F"},
+ {0x40, 0xA0, 0x1170, 0x0000, 0x0010, 0x0010,
+ "\xE9\xE0\xB4\xA3\x25\xAE\x0C\xAF\x0D\xAA\x08\xA9\x09\x7B\x01\xC0"},
+ {0x40, 0xA0, 0x1180, 0x0000, 0x0010, 0x0010,
+ "\x03\xC0\x02\xC0\x01\x7A\x7F\x79\x00\x78\x00\x7C\x7F\xAD\x03\xD0"},
+ {0x40, 0xA0, 0x1190, 0x0000, 0x0010, 0x0010,
+ "\x01\xD0\x02\xD0\x03\x12\x13\x56\x80\x0F\xAF\x09\xAE\x08\xAD\x0D"},
+ {0x40, 0xA0, 0x11A0, 0x0000, 0x0010, 0x0010,
+ "\x7A\x7F\x79\x00\x7B\x00\x12\x15\xA4\x90\x7F\xB5\xE5\x0D\xF0\xE5"},
+ {0x40, 0xA0, 0x11B0, 0x0000, 0x0010, 0x0010,
+ "\x0D\x25\x09\xF5\x09\xE5\x0C\x35\x08\xF5\x08\xC3\xE5\x0B\x95\x0D"},
+ {0x40, 0xA0, 0x11C0, 0x0000, 0x0010, 0x0010,
+ "\xF5\x0B\xE5\x0A\x95\x0C\xF5\x0A\x90\x7F\xB4\xE0\x20\xE2\x03\x02"},
+ {0x40, 0xA0, 0x11D0, 0x0000, 0x0010, 0x0010,
+ "\x11\x4C\x80\xF4\x90\x7F\xE8\xE0\x64\x40\x70\x6E\xE5\x0B\x45\x0A"},
+ {0x40, 0xA0, 0x11E0, 0x0000, 0x0010, 0x0010,
+ "\x60\x68\xE4\x90\x7F\xC5\xF0\x90\x7F\xB4\xE0\x20\xE3\xF9\x90\x7F"},
+ {0x40, 0xA0, 0x11F0, 0x0000, 0x0010, 0x0010,
+ "\xC5\xE0\x75\x0C\x00\xF5\x0D\x90\x7F\xE9\xE0\xB4\xA3\x15\xAE\x0C"},
+ {0x40, 0xA0, 0x1200, 0x0000, 0x0010, 0x0010,
+ "\xAF\x0D\xA8\x09\xAC\x08\x7D\x01\x7B\x01\x7A\x7E\x79\xC0\x12\x13"},
+ {0x40, 0xA0, 0x1210, 0x0000, 0x0010, 0x0010,
+ "\x56\x80\x0F\xAF\x09\xAE\x08\xAD\x0D\x7A\x7F\x79\x00\x7B\x00\x12"},
+ {0x40, 0xA0, 0x1220, 0x0000, 0x0010, 0x0010,
+ "\x14\xB9\xE5\x0D\x25\x09\xF5\x09\xE5\x0C\x35\x08\xF5\x08\xC3\xE5"},
+ {0x40, 0xA0, 0x1230, 0x0000, 0x0010, 0x0010,
+ "\x0B\x95\x0D\xF5\x0B\xE5\x0A\x95\x0C\xF5\x0A\x90\x7F\xB4\xE0\x44"},
+ {0x40, 0xA0, 0x1240, 0x0000, 0x000A, 0x000A,
+ "\x02\xF0\x80\x98\x90\x7F\xEA\xE0\xF5\x1C"},
+ {0x40, 0xA0, 0x124A, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x1558, 0x0000, 0x0006, 0x0006, "\xAB\x07\xAA\x06\xAC\x05"},
+ {0x40, 0xA0, 0x155E, 0x0000, 0x0010, 0x0010,
+ "\xE4\xFD\x30\x01\x11\xEA\xFF\xAE\x05\x0D\xEE\x24\x00\xF5\x82\xE4"},
+ {0x40, 0xA0, 0x156E, 0x0000, 0x0010, 0x0010,
+ "\x34\xE0\xF5\x83\xEF\xF0\xEB\xAE\x05\x0D\x74\x00\x2E\xF5\x82\xE4"},
+ {0x40, 0xA0, 0x157E, 0x0000, 0x0010, 0x0010,
+ "\x34\xE0\xF5\x83\xEB\xF0\xAF\x05\x0D\x74\x00\x2F\xF5\x82\xE4\x34"},
+ {0x40, 0xA0, 0x158E, 0x0000, 0x0010, 0x0010,
+ "\xE0\xF5\x83\xEC\xF0\xAF\x1C\x7A\xE0\x7B\x00\x12\x17\x20\x7F\x0A"},
+ {0x40, 0xA0, 0x159E, 0x0000, 0x0005, 0x0005, "\x7E\x00\x12\x17\x3C"},
+ {0x40, 0xA0, 0x15A3, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x14B9, 0x0000, 0x000A, 0x000A,
+ "\x8E\x0E\x8F\x0F\x8D\x10\x8A\x11\x8B\x12"},
+ {0x40, 0xA0, 0x14C3, 0x0000, 0x0010, 0x0010,
+ "\xE4\xF5\x13\xE5\x13\xC3\x95\x10\x50\x20\x05\x0F\xE5\x0F\xAE\x0E"},
+ {0x40, 0xA0, 0x14D3, 0x0000, 0x0010, 0x0010,
+ "\x70\x02\x05\x0E\x14\xFF\xE5\x12\x25\x13\xF5\x82\xE4\x35\x11\xF5"},
+ {0x40, 0xA0, 0x14E3, 0x0000, 0x000A, 0x000A,
+ "\x83\xE0\xFD\x12\x15\x58\x05\x13\x80\xD9"},
+ {0x40, 0xA0, 0x14ED, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x15A4, 0x0000, 0x000A, 0x000A,
+ "\x8E\x0E\x8F\x0F\x8D\x10\x8A\x11\x8B\x12"},
+ {0x40, 0xA0, 0x15AE, 0x0000, 0x0010, 0x0010,
+ "\xE4\xFD\x30\x01\x12\xE5\x0E\xFF\xAE\x05\x0D\xEE\x24\x03\xF5\x82"},
+ {0x40, 0xA0, 0x15BE, 0x0000, 0x0010, 0x0010,
+ "\xE4\x34\xE0\xF5\x83\xEF\xF0\xE5\x0F\xAE\x05\x0D\x74\x03\x2E\xF5"},
+ {0x40, 0xA0, 0x15CE, 0x0000, 0x0010, 0x0010,
+ "\x82\xE4\x34\xE0\xF5\x83\xE5\x0F\xF0\xAF\x1C\x7A\xE0\x7B\x03\x12"},
+ {0x40, 0xA0, 0x15DE, 0x0000, 0x000D, 0x000D,
+ "\x17\x20\xAF\x1C\xAD\x10\xAB\x12\xAA\x11\x12\x17\x04"},
+ {0x40, 0xA0, 0x15EB, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x166E, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\xD2"},
+ {0x40, 0xA0, 0x167E, 0x0000, 0x0010, 0x0010,
+ "\x00\x53\x91\xEF\x90\x7F\xAB\x74\x01\xF0\xD0\x86\xD0\x84\xD0\x85"},
+ {0x40, 0xA0, 0x168E, 0x0000, 0x0007, 0x0007,
+ "\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x1644, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\x90"},
+ {0x40, 0xA0, 0x1654, 0x0000, 0x0010, 0x0010,
+ "\x7F\xC4\xE4\xF0\x53\x91\xEF\x90\x7F\xAB\x74\x04\xF0\xD0\x86\xD0"},
+ {0x40, 0xA0, 0x1664, 0x0000, 0x000A, 0x000A,
+ "\x84\xD0\x85\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x1695, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\x53"},
+ {0x40, 0xA0, 0x16A5, 0x0000, 0x0010, 0x0010,
+ "\x91\xEF\x90\x7F\xAB\x74\x02\xF0\xD0\x86\xD0\x84\xD0\x85\xD0\x82"},
+ {0x40, 0xA0, 0x16B5, 0x0000, 0x0005, 0x0005, "\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x16BA, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\x53"},
+ {0x40, 0xA0, 0x16CA, 0x0000, 0x0010, 0x0010,
+ "\x91\xEF\x90\x7F\xAB\x74\x10\xF0\xD0\x86\xD0\x84\xD0\x85\xD0\x82"},
+ {0x40, 0xA0, 0x16DA, 0x0000, 0x0005, 0x0005, "\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x14FF, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x16DF, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\x53"},
+ {0x40, 0xA0, 0x16EF, 0x0000, 0x0010, 0x0010,
+ "\x91\xEF\x90\x7F\xAB\x74\x08\xF0\xD0\x86\xD0\x84\xD0\x85\xD0\x82"},
+ {0x40, 0xA0, 0x16FF, 0x0000, 0x0005, 0x0005, "\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x1767, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1768, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1769, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x176A, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x176B, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x176C, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x176D, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x176E, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x176F, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1770, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1771, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1772, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1773, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1774, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1775, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1776, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0043, 0x0000, 0x0003, 0x0003, "\x02\x15\x00"},
+ {0x40, 0xA0, 0x1500, 0x0000, 0x0010, 0x0010,
+ "\x02\x16\x6E\x00\x02\x16\x95\x00\x02\x16\x44\x00\x02\x16\xDF\x00"},
+ {0x40, 0xA0, 0x1510, 0x0000, 0x0010, 0x0010,
+ "\x02\x16\xBA\x00\x02\x14\xFF\x00\x02\x17\x67\x00\x02\x17\x68\x00"},
+ {0x40, 0xA0, 0x1520, 0x0000, 0x0010, 0x0010,
+ "\x02\x17\x69\x00\x02\x17\x6A\x00\x02\x17\x6B\x00\x02\x17\x6C\x00"},
+ {0x40, 0xA0, 0x1530, 0x0000, 0x0010, 0x0010,
+ "\x02\x17\x6D\x00\x02\x17\x6E\x00\x02\x17\x6F\x00\x02\x17\x70\x00"},
+ {0x40, 0xA0, 0x1540, 0x0000, 0x0010, 0x0010,
+ "\x02\x17\x71\x00\x02\x17\x72\x00\x02\x17\x73\x00\x02\x17\x74\x00"},
+ {0x40, 0xA0, 0x1550, 0x0000, 0x0008, 0x0008,
+ "\x02\x17\x75\x00\x02\x17\x76\x00"},
+ {0x40, 0xA0, 0x173C, 0x0000, 0x0010, 0x0010,
+ "\x8E\x14\x8F\x15\xE5\x15\x15\x15\xAE\x14\x70\x02\x15\x14\x4E\x60"},
+ {0x40, 0xA0, 0x174C, 0x0000, 0x0007, 0x0007,
+ "\x05\x12\x14\xEE\x80\xEE\x22"},
+ {0x40, 0xA0, 0x175F, 0x0000, 0x0008, 0x0008,
+ "\xE4\xF5\x1B\xD2\xE9\xD2\xAF\x22"},
+ {0x40, 0xA0, 0x1619, 0x0000, 0x0010, 0x0010,
+ "\xA9\x07\xE5\x1B\x70\x23\x90\x7F\xA5\xE0\x44\x80\xF0\xE9\x25\xE0"},
+ {0x40, 0xA0, 0x1629, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xA6\xF0\x8D\x16\xAF\x03\xA9\x07\x75\x17\x01\x8A\x18\x89"},
+ {0x40, 0xA0, 0x1639, 0x0000, 0x000B, 0x000B,
+ "\x19\xE4\xF5\x1A\x75\x1B\x01\xD3\x22\xC3\x22"},
+ {0x40, 0xA0, 0x15EC, 0x0000, 0x0010, 0x0010,
+ "\xA9\x07\xE5\x1B\x70\x25\x90\x7F\xA5\xE0\x44\x80\xF0\xE9\x25\xE0"},
+ {0x40, 0xA0, 0x15FC, 0x0000, 0x0010, 0x0010,
+ "\x44\x01\x90\x7F\xA6\xF0\x8D\x16\xAF\x03\xA9\x07\x75\x17\x01\x8A"},
+ {0x40, 0xA0, 0x160C, 0x0000, 0x000D, 0x000D,
+ "\x18\x89\x19\xE4\xF5\x1A\x75\x1B\x03\xD3\x22\xC3\x22"},
+ {0x40, 0xA0, 0x004B, 0x0000, 0x0003, 0x0003, "\x02\x13\x7F"},
+ {0x40, 0xA0, 0x137F, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\xC0"},
+ {0x40, 0xA0, 0x138F, 0x0000, 0x0010, 0x0010,
+ "\xD0\x75\xD0\x00\xC0\x00\xC0\x01\xC0\x02\xC0\x03\xC0\x06\xC0\x07"},
+ {0x40, 0xA0, 0x139F, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xA5\xE0\x30\xE2\x06\x75\x1B\x06\x02\x14\x4E\x90\x7F\xA5"},
+ {0x40, 0xA0, 0x13AF, 0x0000, 0x0010, 0x0010,
+ "\xE0\x20\xE1\x0C\xE5\x1B\x64\x02\x60\x06\x75\x1B\x07\x02\x14\x4E"},
+ {0x40, 0xA0, 0x13BF, 0x0000, 0x0010, 0x0010,
+ "\xAF\x1B\xEF\x24\xFE\x60\x48\x14\x60\x2C\x24\xFE\x60\x77\x24\x04"},
+ {0x40, 0xA0, 0x13CF, 0x0000, 0x0010, 0x0010,
+ "\x60\x03\x02\x14\x4E\xAB\x17\xAA\x18\xA9\x19\xAF\x1A\x05\x1A\x8F"},
+ {0x40, 0xA0, 0x13DF, 0x0000, 0x0010, 0x0010,
+ "\x82\x75\x83\x00\x12\x12\x4B\x90\x7F\xA6\xF0\xE5\x1A\x65\x16\x70"},
+ {0x40, 0xA0, 0x13EF, 0x0000, 0x0010, 0x0010,
+ "\x5E\x75\x1B\x05\x80\x59\x90\x7F\xA6\xE0\xAB\x17\xAA\x18\xA9\x19"},
+ {0x40, 0xA0, 0x13FF, 0x0000, 0x0010, 0x0010,
+ "\xAE\x1A\x8E\x82\x75\x83\x00\x12\x12\x78\x75\x1B\x02\x80\x40\xE5"},
+ {0x40, 0xA0, 0x140F, 0x0000, 0x0010, 0x0010,
+ "\x16\x24\xFE\xB5\x1A\x07\x90\x7F\xA5\xE0\x44\x20\xF0\xE5\x16\x14"},
+ {0x40, 0xA0, 0x141F, 0x0000, 0x0010, 0x0010,
+ "\xB5\x1A\x0A\x90\x7F\xA5\xE0\x44\x40\xF0\x75\x1B\x00\x90\x7F\xA6"},
+ {0x40, 0xA0, 0x142F, 0x0000, 0x0010, 0x0010,
+ "\xE0\xAB\x17\xAA\x18\xA9\x19\xAE\x1A\x8E\x82\x75\x83\x00\x12\x12"},
+ {0x40, 0xA0, 0x143F, 0x0000, 0x0010, 0x0010,
+ "\x78\x05\x1A\x80\x0A\x90\x7F\xA5\xE0\x44\x40\xF0\x75\x1B\x00\x53"},
+ {0x40, 0xA0, 0x144F, 0x0000, 0x0010, 0x0010,
+ "\x91\xDF\xD0\x07\xD0\x06\xD0\x03\xD0\x02\xD0\x01\xD0\x00\xD0\xD0"},
+ {0x40, 0xA0, 0x145F, 0x0000, 0x000D, 0x000D,
+ "\xD0\x86\xD0\x84\xD0\x85\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x1704, 0x0000, 0x0010, 0x0010,
+ "\x12\x15\xEC\xE5\x1B\x24\xFA\x60\x0E\x14\x60\x06\x24\x07\x70\xF3"},
+ {0x40, 0xA0, 0x1714, 0x0000, 0x000C, 0x000C,
+ "\xD3\x22\xE4\xF5\x1B\xD3\x22\xE4\xF5\x1B\xD3\x22"},
+ {0x40, 0xA0, 0x1720, 0x0000, 0x0010, 0x0010,
+ "\x12\x16\x19\xE5\x1B\x24\xFA\x60\x0E\x14\x60\x06\x24\x07\x70\xF3"},
+ {0x40, 0xA0, 0x1730, 0x0000, 0x000C, 0x000C,
+ "\xD3\x22\xE4\xF5\x1B\xD3\x22\xE4\xF5\x1B\xD3\x22"},
+ {0x40, 0xA0, 0x14EE, 0x0000, 0x0010, 0x0010,
+ "\x74\x00\xF5\x86\x90\xFD\xA5\x7C\x05\xA3\xE5\x82\x45\x83\x70\xF9"},
+ {0x40, 0xA0, 0x14FE, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0000, 0x0000, 0x0003, 0x0003, "\x02\x17\x53"},
+ {0x40, 0xA0, 0x1753, 0x0000, 0x000C, 0x000C,
+ "\x78\x7F\xE4\xF6\xD8\xFD\x75\x81\x20\x02\x14\x6C"},
+ {0x40, 0xA0, 0x124B, 0x0000, 0x0010, 0x0010,
+ "\xBB\x01\x0C\xE5\x82\x29\xF5\x82\xE5\x83\x3A\xF5\x83\xE0\x22\x50"},
+ {0x40, 0xA0, 0x125B, 0x0000, 0x0010, 0x0010,
+ "\x06\xE9\x25\x82\xF8\xE6\x22\xBB\xFE\x06\xE9\x25\x82\xF8\xE2\x22"},
+ {0x40, 0xA0, 0x126B, 0x0000, 0x000D, 0x000D,
+ "\xE5\x82\x29\xF5\x82\xE5\x83\x3A\xF5\x83\xE4\x93\x22"},
+ {0x40, 0xA0, 0x1278, 0x0000, 0x0010, 0x0010,
+ "\xF8\xBB\x01\x0D\xE5\x82\x29\xF5\x82\xE5\x83\x3A\xF5\x83\xE8\xF0"},
+ {0x40, 0xA0, 0x1288, 0x0000, 0x0010, 0x0010,
+ "\x22\x50\x06\xE9\x25\x82\xC8\xF6\x22\xBB\xFE\x05\xE9\x25\x82\xC8"},
+ {0x40, 0xA0, 0x1298, 0x0000, 0x0002, 0x0002, "\xF2\x22"},
+ {0x40, 0xA0, 0x129A, 0x0000, 0x0010, 0x0010,
+ "\xE7\x09\xF6\x08\xDF\xFA\x80\x46\xE7\x09\xF2\x08\xDF\xFA\x80\x3E"},
+ {0x40, 0xA0, 0x12AA, 0x0000, 0x0010, 0x0010,
+ "\x88\x82\x8C\x83\xE7\x09\xF0\xA3\xDF\xFA\x80\x32\xE3\x09\xF6\x08"},
+ {0x40, 0xA0, 0x12BA, 0x0000, 0x0010, 0x0010,
+ "\xDF\xFA\x80\x6E\xE3\x09\xF2\x08\xDF\xFA\x80\x66\x88\x82\x8C\x83"},
+ {0x40, 0xA0, 0x12CA, 0x0000, 0x0010, 0x0010,
+ "\xE3\x09\xF0\xA3\xDF\xFA\x80\x5A\x89\x82\x8A\x83\xE0\xA3\xF6\x08"},
+ {0x40, 0xA0, 0x12DA, 0x0000, 0x0010, 0x0010,
+ "\xDF\xFA\x80\x4E\x89\x82\x8A\x83\xE0\xA3\xF2\x08\xDF\xFA\x80\x42"},
+ {0x40, 0xA0, 0x12EA, 0x0000, 0x0010, 0x0010,
+ "\x80\xD2\x80\xFA\x80\xC6\x80\xD4\x80\x55\x80\xF2\x80\x29\x80\x10"},
+ {0x40, 0xA0, 0x12FA, 0x0000, 0x0010, 0x0010,
+ "\x80\xA6\x80\xEA\x80\x9A\x80\xA8\x80\xDA\x80\xE2\x80\xCA\x80\x29"},
+ {0x40, 0xA0, 0x130A, 0x0000, 0x0010, 0x0010,
+ "\x88\x84\x8C\x85\x89\x82\x8A\x83\xE4\x93\xA3\x05\x86\xF0\xA3\x05"},
+ {0x40, 0xA0, 0x131A, 0x0000, 0x0010, 0x0010,
+ "\x86\xDF\xF5\xDE\xF3\x80\x0B\x89\x82\x8A\x83\xE4\x93\xA3\xF6\x08"},
+ {0x40, 0xA0, 0x132A, 0x0000, 0x0010, 0x0010,
+ "\xDF\xF9\xEC\xFA\xA9\xF0\xED\xFB\x22\x88\x84\x8C\x85\x89\x82\x8A"},
+ {0x40, 0xA0, 0x133A, 0x0000, 0x0010, 0x0010,
+ "\x83\xE0\xA3\x05\x86\xF0\xA3\x05\x86\xDF\xF6\xDE\xF4\x80\xE3\x89"},
+ {0x40, 0xA0, 0x134A, 0x0000, 0x0010, 0x0010,
+ "\x82\x8A\x83\xE4\x93\xA3\xF2\x08\xDF\xF9\x80\xD6\x88\xF0\xED\x24"},
+ {0x40, 0xA0, 0x135A, 0x0000, 0x0010, 0x0010,
+ "\x02\xB4\x04\x00\x50\xCC\xF5\x82\xEB\x24\x02\xB4\x04\x00\x50\xC2"},
+ {0x40, 0xA0, 0x136A, 0x0000, 0x0010, 0x0010,
+ "\x23\x23\x45\x82\xF5\x82\xEF\x4E\x60\xB8\xEF\x60\x01\x0E\xE5\x82"},
+ {0x40, 0xA0, 0x137A, 0x0000, 0x0005, 0x0005, "\x23\x90\x12\xEA\x73"},
+ {0x40, 0xA0, 0x7F92, 0x0000, 0x0001, 0x0001, "\x00"},
+ {0x40, 0xA0, 0x7F92, 0x0000, 0x0001, 0x0001, "\x01"},
+ {0x40, 0xA0, 0x0100, 0x0000, 0x0010, 0x0010,
+ "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x0110, 0x0000, 0x0010, 0x0010,
+ "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x0120, 0x0000, 0x0010, 0x0010,
+ "\x4D\x69\x64\x69\x6D\x61\x6E\x20\x55\x53\x42\x20\x4D\x69\x64\x69"},
+ {0x40, 0xA0, 0x0130, 0x0000, 0x0010, 0x0010,
+ "\x53\x70\x6F\x72\x74\x20\x31\x78\x31\x20\x20\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x0140, 0x0000, 0x0010, 0x0010,
+ "\x46\x69\x72\x6D\x77\x61\x72\x65\x20\x52\x65\x6C\x65\x61\x73\x65"},
+ {0x40, 0xA0, 0x0150, 0x0000, 0x0010, 0x0010,
+ "\x20\x31\x2E\x32\x31\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x0160, 0x0000, 0x0010, 0x0010,
+ "\x28\x63\x29\x20\x32\x30\x30\x30\x2D\x32\x30\x30\x31\x2C\x20\x4D"},
+ {0x40, 0xA0, 0x0170, 0x0000, 0x0010, 0x0010,
+ "\x69\x64\x69\x6D\x61\x6E\x20\x49\x6E\x63\x2E\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x0180, 0x0000, 0x0010, 0x0010,
+ "\x41\x6C\x6C\x20\x72\x69\x67\x68\x74\x73\x20\x72\x65\x73\x65\x72"},
+ {0x40, 0xA0, 0x0190, 0x0000, 0x0010, 0x0010,
+ "\x76\x65\x64\x2E\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x01A0, 0x0000, 0x0010, 0x0010,
+ "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x01B0, 0x0000, 0x0010, 0x0010,
+ "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x08B2, 0x0000, 0x0003, 0x0003, "\x01\x1C\x00"},
+ {0x40, 0xA0, 0x040D, 0x0000, 0x0010, 0x0010,
+ "\xC2\x01\xC2\x00\xC2\x04\xC2\x03\x12\x09\xE1\xD2\xE8\x43\xD8\x20"},
+ {0x40, 0xA0, 0x041D, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xAB\x74\xFF\xF0\x90\x7F\xA9\xF0\x90\x7F\xAA\xF0\x53\x91"},
+ {0x40, 0xA0, 0x042D, 0x0000, 0x0010, 0x0010,
+ "\xEF\x90\x7F\x95\xE0\x44\xC0\xF0\x90\x7F\xAF\xE0\x44\x01\xF0\x90"},
+ {0x40, 0xA0, 0x043D, 0x0000, 0x0010, 0x0010,
+ "\x7F\xAE\xE0\x44\x1D\xF0\x90\x7F\x92\xE0\x44\x02\xF0\x90\x7F\x95"},
+ {0x40, 0xA0, 0x044D, 0x0000, 0x0010, 0x0010,
+ "\xE0\x44\x01\xF0\x90\x7F\x9E\xE0\x54\xFE\xF0\x90\x7F\x95\xE0\x44"},
+ {0x40, 0xA0, 0x045D, 0x0000, 0x0010, 0x0010,
+ "\x02\xF0\x90\x7F\x9E\xE0\x44\x02\xF0\x90\x7F\x95\xE0\x54\x83\xF0"},
+ {0x40, 0xA0, 0x046D, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\x9E\xE0\x44\x7C\xF0\x90\x7F\x94\xE0\x54\xFE\xF0\x90\x7F"},
+ {0x40, 0xA0, 0x047D, 0x0000, 0x0010, 0x0010,
+ "\x9D\xE0\x44\x01\xF0\x90\x7F\x9A\xE0\x44\x01\x90\x7F\x97\xF0\x43"},
+ {0x40, 0xA0, 0x048D, 0x0000, 0x0010, 0x0010,
+ "\x21\x20\x43\x21\x40\x43\x21\x10\x53\x89\xF0\xE4\xF5\x8C\xF5\x8A"},
+ {0x40, 0xA0, 0x049D, 0x0000, 0x0010, 0x0010,
+ "\xD2\x8C\xD2\xA9\x12\x0B\xAE\xD2\xAF\xE5\x89\x54\x0F\x24\x20\xF5"},
+ {0x40, 0xA0, 0x04AD, 0x0000, 0x0010, 0x0010,
+ "\x89\x75\x8D\xFE\x75\x8B\xFE\xD2\x8E\xC2\xAC\x75\x98\x50\xC2\x98"},
+ {0x40, 0xA0, 0x04BD, 0x0000, 0x0010, 0x0010,
+ "\xC2\x99\xD2\xAC\x53\x21\xDF\x53\x21\xBF\x53\x21\xEF\x90\x7F\x9A"},
+ {0x40, 0xA0, 0x04CD, 0x0000, 0x0010, 0x0010,
+ "\xE0\x54\xFE\x90\x7F\x97\xF0\x90\x7F\x98\xE5\x21\xF0\x75\x24\x3D"},
+ {0x40, 0xA0, 0x04DD, 0x0000, 0x0010, 0x0010,
+ "\xE5\x24\x70\xFC\x43\x21\x20\x43\x21\x40\x43\x21\x10\x90\x7F\x98"},
+ {0x40, 0xA0, 0x04ED, 0x0000, 0x0010, 0x0010,
+ "\xE5\x21\xF0\x20\x01\x3C\x75\x24\xF4\xE5\x24\x60\x03\x30\x01\xF9"},
+ {0x40, 0xA0, 0x04FD, 0x0000, 0x0010, 0x0010,
+ "\x75\x24\xF4\xE5\x24\x60\x03\x30\x01\xF9\x75\x24\xF4\xE5\x24\x60"},
+ {0x40, 0xA0, 0x050D, 0x0000, 0x0010, 0x0010,
+ "\x03\x30\x01\xF9\x75\x24\xF4\xE5\x24\x60\x03\x30\x01\xF9\x75\x24"},
+ {0x40, 0xA0, 0x051D, 0x0000, 0x0010, 0x0010,
+ "\xF4\xE5\x24\x60\x03\x30\x01\xF9\x20\x01\xC8\xD2\x06\x12\x0A\xE0"},
+ {0x40, 0xA0, 0x052D, 0x0000, 0x0010, 0x0010,
+ "\x80\xC1\x30\x01\x0C\x12\x01\xFF\xC2\x01\x90\x7F\xAE\xE0\x44\x02"},
+ {0x40, 0xA0, 0x053D, 0x0000, 0x0010, 0x0010,
+ "\xF0\x30\x04\x1A\x12\x0B\x91\x50\x13\x12\x0B\x05\x20\x03\x07\x90"},
+ {0x40, 0xA0, 0x054D, 0x0000, 0x0010, 0x0010,
+ "\x7F\xD6\xE0\x20\xE7\xF3\x12\x0B\x26\x12\x0B\xB2\xC2\x04\x05\x1C"},
+ {0x40, 0xA0, 0x055D, 0x0000, 0x0010, 0x0010,
+ "\xE5\x1C\xC3\x94\x06\x40\x03\xE4\xF5\x1C\xE5\x1C\x75\xF0\x03\xA4"},
+ {0x40, 0xA0, 0x056D, 0x0000, 0x000E, 0x000E,
+ "\x24\x0A\xF8\x08\xE6\xFA\x08\xE6\xF9\x12\x07\x11\x80\xB4"},
+ {0x40, 0xA0, 0x057B, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0033, 0x0000, 0x0003, 0x0003, "\x02\x0B\xAA"},
+ {0x40, 0xA0, 0x0BAA, 0x0000, 0x0004, 0x0004, "\x53\xD8\xEF\x32"},
+ {0x40, 0xA0, 0x0023, 0x0000, 0x0003, 0x0003, "\x02\x07\x17"},
+ {0x40, 0xA0, 0x0717, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\xC0"},
+ {0x40, 0xA0, 0x0727, 0x0000, 0x000C, 0x000C,
+ "\xD0\x75\xD0\x00\xC0\x00\xC0\x05\xC0\x06\xC0\x07"},
+ {0x40, 0xA0, 0x0733, 0x0000, 0x0010, 0x0010,
+ "\x30\x99\x23\xC2\x99\xE5\x68\x60\x1B\xAF\x67\x05\x67\x74\x00\x2F"},
+ {0x40, 0xA0, 0x0743, 0x0000, 0x0010, 0x0010,
+ "\xF5\x82\xE4\x34\x0F\xF5\x83\xE0\xF5\x99\x15\x68\x53\x21\xBF\x75"},
+ {0x40, 0xA0, 0x0753, 0x0000, 0x0010, 0x0010,
+ "\x23\x0C\x80\x02\xD2\x02\x30\x98\x1E\xC2\x98\xAF\x99\xE5\x66\x04"},
+ {0x40, 0xA0, 0x0763, 0x0000, 0x0010, 0x0010,
+ "\x54\x3F\xFE\x65\x65\x60\x0A\xAD\x66\x74\x25\x2D\xF8\xA6\x07\x8E"},
+ {0x40, 0xA0, 0x0773, 0x0000, 0x0007, 0x0007,
+ "\x66\x53\x21\xDF\x75\x22\x0C"},
+ {0x40, 0xA0, 0x077A, 0x0000, 0x0010, 0x0010,
+ "\xD0\x07\xD0\x06\xD0\x05\xD0\x00\xD0\xD0\xD0\x86\xD0\x84\xD0\x85"},
+ {0x40, 0xA0, 0x078A, 0x0000, 0x0007, 0x0007,
+ "\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x0A17, 0x0000, 0x0010, 0x0010,
+ "\xA2\xAC\x92\x06\xC2\xAC\x30\x02\x0C\xC2\x02\x8F\x99\x53\x21\xBF"},
+ {0x40, 0xA0, 0x0A27, 0x0000, 0x0010, 0x0010,
+ "\x75\x23\x0C\x80\x12\xAE\x69\x05\x69\x74\x00\x2E\xF5\x82\xE4\x34"},
+ {0x40, 0xA0, 0x0A37, 0x0000, 0x000B, 0x000B,
+ "\x0F\xF5\x83\xEF\xF0\x05\x68\xA2\x06\x92\xAC"},
+ {0x40, 0xA0, 0x0A42, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x01C0, 0x0000, 0x0010, 0x0010,
+ "\x12\x01\x00\x01\x00\x00\x00\x40\x63\x07\x11\x10\x21\x01\x00\x00"},
+ {0x40, 0xA0, 0x01D0, 0x0000, 0x0010, 0x0010,
+ "\x00\x01\x09\x02\x27\x00\x01\x01\x00\xA0\x00\x09\x04\x00\x00\x03"},
+ {0x40, 0xA0, 0x01E0, 0x0000, 0x0010, 0x0010,
+ "\xFF\x00\x00\x00\x07\x05\x81\x03\x20\x00\x01\x07\x05\x82\x02\x20"},
+ {0x40, 0xA0, 0x01F0, 0x0000, 0x000F, 0x000F,
+ "\x00\x00\x07\x05\x02\x02\x20\x00\x00\x04\x03\x09\x04\x00\x00"},
+ {0x40, 0xA0, 0x08B5, 0x0000, 0x0010, 0x0010,
+ "\x01\x24\x00\xC1\x01\x01\x22\x00\x01\x21\xFF\x01\x23\x00\xC1\x82"},
+ {0x40, 0xA0, 0x08C5, 0x0000, 0x000F, 0x000F,
+ "\x01\x65\x00\x01\x66\x00\x01\x67\x00\x01\x69\x00\x01\x68\x00"},
+ {0x40, 0xA0, 0x0043, 0x0000, 0x0003, 0x0003, "\x02\x09\x00"},
+ {0x40, 0xA0, 0x0900, 0x0000, 0x0010, 0x0010,
+ "\x02\x0A\x6D\x00\x02\x08\x03\x00\x02\x0A\x43\x00\x02\x0A\x94\x00"},
+ {0x40, 0xA0, 0x0910, 0x0000, 0x0010, 0x0010,
+ "\x02\x0A\xBB\x00\x02\x0B\xBE\x00\x02\x0B\xBF\x00\x02\x0B\xC0\x00"},
+ {0x40, 0xA0, 0x0920, 0x0000, 0x0010, 0x0010,
+ "\x02\x0B\xC1\x00\x02\x0B\xC2\x00\x02\x0B\xC3\x00\x02\x0B\xC4\x00"},
+ {0x40, 0xA0, 0x0930, 0x0000, 0x0010, 0x0010,
+ "\x02\x0B\xC5\x00\x02\x0B\xC6\x00\x02\x0B\xC7\x00\x02\x0B\xC8\x00"},
+ {0x40, 0xA0, 0x0940, 0x0000, 0x0010, 0x0010,
+ "\x02\x0B\xC9\x00\x02\x0B\xCA\x00\x02\x0B\xCB\x00\x02\x0B\xCC\x00"},
+ {0x40, 0xA0, 0x0950, 0x0000, 0x0008, 0x0008,
+ "\x02\x0B\xCD\x00\x02\x0B\xCE\x00"},
+ {0x40, 0xA0, 0x08D4, 0x0000, 0x0010, 0x0010,
+ "\x12\x0A\xFF\x07\x91\xFF\x06\x08\xFF\x09\x58\xFF\x07\x91\xFF\x06"},
+ {0x40, 0xA0, 0x08E4, 0x0000, 0x000A, 0x000A,
+ "\x08\xFF\x0B\x57\x01\x08\xFF\x01\x09\x00"},
+ {0x40, 0xA0, 0x0791, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xB6\xE0\x20\xE1\x6A\x7A\x7E\x79\x80\x7E\x7E\x7F\x80\x74"},
+ {0x40, 0xA0, 0x07A1, 0x0000, 0x0010, 0x0010,
+ "\x7E\x90\x7F\xE3\xF0\x74\x80\x90\x7F\xE4\xF0\xE4\xFF\xE5\x66\x65"},
+ {0x40, 0xA0, 0x07B1, 0x0000, 0x0010, 0x0010,
+ "\x65\x60\x43\xEF\xC3\x94\x08\x50\x3D\xE4\xFD\xE5\x66\x65\x65\x60"},
+ {0x40, 0xA0, 0x07C1, 0x0000, 0x0010, 0x0010,
+ "\x1B\xED\xC3\x94\x03\x50\x15\x74\x25\x25\x65\xF8\xE6\x90\x7F\xE5"},
+ {0x40, 0xA0, 0x07D1, 0x0000, 0x0010, 0x0010,
+ "\xF0\x05\x65\xE5\x65\x54\x3F\xF5\x65\x0D\x80\xDF\xED\x60\xCE\xFE"},
+ {0x40, 0xA0, 0x07E1, 0x0000, 0x0010, 0x0010,
+ "\xEE\xC3\x94\x03\x50\x08\xE4\x90\x7F\xE5\xF0\x0E\x80\xF2\x90\x7F"},
+ {0x40, 0xA0, 0x07F1, 0x0000, 0x0010, 0x0010,
+ "\xE5\xED\xF0\x0F\x80\xB7\xEF\x60\x08\x25\xE0\x25\xE0\x90\x7F\xB7"},
+ {0x40, 0xA0, 0x0801, 0x0000, 0x0001, 0x0001, "\xF0"},
+ {0x40, 0xA0, 0x0802, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0958, 0x0000, 0x0010, 0x0010,
+ "\xE5\x08\x60\x16\x14\x60\x2A\x80\x00\x12\x08\xFD\xEF\x65\x09\x60"},
+ {0x40, 0xA0, 0x0968, 0x0000, 0x0010, 0x0010,
+ "\x36\x12\x08\xFD\x8F\x09\xE4\xF5\x08\x22\xE5\x22\x60\x10\xD5\x22"},
+ {0x40, 0xA0, 0x0978, 0x0000, 0x0010, 0x0010,
+ "\x0D\xA2\xAF\x92\x06\xC2\xAF\x43\x21\x20\xA2\x06\x92\xAF\x05\x08"},
+ {0x40, 0xA0, 0x0988, 0x0000, 0x0010, 0x0010,
+ "\x22\xE5\x23\x60\x10\xD5\x23\x0D\xA2\xAF\x92\x06\xC2\xAF\x43\x21"},
+ {0x40, 0xA0, 0x0998, 0x0000, 0x0007, 0x0007,
+ "\x40\xA2\x06\x92\xAF\x05\x08"},
+ {0x40, 0xA0, 0x099F, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0B57, 0x0000, 0x0010, 0x0010,
+ "\xA2\xAF\x92\x06\xC2\xAF\x90\x7F\x98\xE5\x21\xF0\xA2\x06\x92\xAF"},
+ {0x40, 0xA0, 0x0B67, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0608, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xC8\xE0\x30\xE1\x03\x02\x06\x92\x90\x7F\xC9\xE0\xF5\x6A"},
+ {0x40, 0xA0, 0x0618, 0x0000, 0x0010, 0x0010,
+ "\xC3\xE4\x95\x68\xFF\x74\x01\x94\x00\xFE\xC3\xE5\x6A\x9F\xE4\x9E"},
+ {0x40, 0xA0, 0x0628, 0x0000, 0x0010, 0x0010,
+ "\x50\x68\xE4\xF5\x6B\xE5\x6B\xC3\x95\x6A\x50\x59\x74\xC3\x25\x6B"},
+ {0x40, 0xA0, 0x0638, 0x0000, 0x0010, 0x0010,
+ "\xF5\x82\xE4\x34\x7D\xF5\x83\xE0\x54\x0F\xFD\x60\x48\x74\xC0\x25"},
+ {0x40, 0xA0, 0x0648, 0x0000, 0x0010, 0x0010,
+ "\x6B\xF5\x82\xE4\x34\x7D\x90\x7F\xE3\xF0\x74\xC0\x25\x6B\xF5\x82"},
+ {0x40, 0xA0, 0x0658, 0x0000, 0x0010, 0x0010,
+ "\xE4\x34\x7D\xE5\x82\x90\x7F\xE4\xF0\xAF\x05\xED\x14\x60\x16\x14"},
+ {0x40, 0xA0, 0x0668, 0x0000, 0x0010, 0x0010,
+ "\x60\x0B\x14\x70\x18\x90\x7F\xE5\xE0\xFF\x12\x0A\x17\x90\x7F\xE5"},
+ {0x40, 0xA0, 0x0678, 0x0000, 0x0010, 0x0010,
+ "\xE0\xFF\x12\x0A\x17\x90\x7F\xE5\xE0\xFF\x12\x0A\x17\x74\x04\x25"},
+ {0x40, 0xA0, 0x0688, 0x0000, 0x000A, 0x000A,
+ "\x6B\xF5\x6B\x80\xA0\xE4\x90\x7F\xC9\xF0"},
+ {0x40, 0xA0, 0x0692, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x08EE, 0x0000, 0x0003, 0x0003, "\x01\x1D\x00"},
+ {0x40, 0xA0, 0x000B, 0x0000, 0x0003, 0x0003, "\x02\x0B\x84"},
+ {0x40, 0xA0, 0x0B84, 0x0000, 0x000D, 0x000D,
+ "\xC0\xE0\x05\x1D\xE5\x24\x60\x02\x15\x24\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x08FD, 0x0000, 0x0003, 0x0003, "\xAF\x1D\x22"},
+ {0x40, 0xA0, 0x0BAE, 0x0000, 0x0004, 0x0004, "\xE4\xF5\x1D\x22"},
+ {0x40, 0xA0, 0x08F1, 0x0000, 0x000B, 0x000B,
+ "\x01\x72\x01\x01\x73\x01\xC1\x85\x01\x74\x02"},
+ {0x40, 0xA0, 0x01FF, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xE9\xE0\x70\x03\x02\x02\xD4\x14\x70\x03\x02\x03\x4F\x24"},
+ {0x40, 0xA0, 0x020F, 0x0000, 0x0010, 0x0010,
+ "\xFE\x70\x03\x02\x03\xA8\x24\xFB\x70\x03\x02\x02\xCE\x14\x70\x03"},
+ {0x40, 0xA0, 0x021F, 0x0000, 0x0010, 0x0010,
+ "\x02\x02\xC8\x14\x70\x03\x02\x02\xBC\x14\x70\x03\x02\x02\xC2\x24"},
+ {0x40, 0xA0, 0x022F, 0x0000, 0x0010, 0x0010,
+ "\x05\x60\x03\x02\x03\xFA\x12\x0B\xB4\x40\x03\x02\x04\x05\x90\x7F"},
+ {0x40, 0xA0, 0x023F, 0x0000, 0x0010, 0x0010,
+ "\xEB\xE0\x24\xFE\x60\x16\x14\x60\x3F\x24\x02\x70\x67\x74\x01\x90"},
+ {0x40, 0xA0, 0x024F, 0x0000, 0x0010, 0x0010,
+ "\x7F\xD4\xF0\x74\xC0\x90\x7F\xD5\xF0\x02\x04\x05\x90\x7F\xEA\xE0"},
+ {0x40, 0xA0, 0x025F, 0x0000, 0x0010, 0x0010,
+ "\xFF\x12\x08\x63\x8B\x6A\x8A\x6B\x89\x6C\xEA\x49\x60\x11\xAE\x02"},
+ {0x40, 0xA0, 0x026F, 0x0000, 0x0010, 0x0010,
+ "\xEE\x90\x7F\xD4\xF0\xAF\x01\xEF\x90\x7F\xD5\xF0\x02\x04\x05\x90"},
+ {0x40, 0xA0, 0x027F, 0x0000, 0x0010, 0x0010,
+ "\x7F\xC4\x74\x01\xF0\x02\x04\x05\x90\x7F\xEA\xE0\xFF\x12\x09\xA0"},
+ {0x40, 0xA0, 0x028F, 0x0000, 0x0010, 0x0010,
+ "\x8B\x6A\x8A\x6B\x89\x6C\xEA\x49\x60\x11\xAE\x02\xEE\x90\x7F\xD4"},
+ {0x40, 0xA0, 0x029F, 0x0000, 0x0010, 0x0010,
+ "\xF0\xAF\x01\xEF\x90\x7F\xD5\xF0\x02\x04\x05\x90\x7F\xC4\x74\x01"},
+ {0x40, 0xA0, 0x02AF, 0x0000, 0x0010, 0x0010,
+ "\xF0\x02\x04\x05\x90\x7F\xC4\x74\x01\xF0\x02\x04\x05\x12\x0B\x76"},
+ {0x40, 0xA0, 0x02BF, 0x0000, 0x0010, 0x0010,
+ "\x02\x04\x05\x12\x0B\xA2\x02\x04\x05\x12\x0B\x9A\x02\x04\x05\x12"},
+ {0x40, 0xA0, 0x02CF, 0x0000, 0x0010, 0x0010,
+ "\x0B\x68\x02\x04\x05\x12\x0B\xB6\x40\x03\x02\x04\x05\x90\x7F\xE8"},
+ {0x40, 0xA0, 0x02DF, 0x0000, 0x0010, 0x0010,
+ "\xE0\x24\x7F\x60\x24\x14\x60\x31\x24\x02\x70\x5B\xA2\x03\xE4\x33"},
+ {0x40, 0xA0, 0x02EF, 0x0000, 0x0010, 0x0010,
+ "\xFF\x25\xE0\xFF\xA2\x00\xE4\x33\x4F\x90\x7F\x00\xF0\xE4\xA3\xF0"},
+ {0x40, 0xA0, 0x02FF, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xB5\x74\x02\xF0\x02\x04\x05\xE4\x90\x7F\x00\xF0\xA3\xF0"},
+ {0x40, 0xA0, 0x030F, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xB5\x74\x02\xF0\x02\x04\x05\x90\x7F\xEC\xE0\xF4\x54\x80"},
+ {0x40, 0xA0, 0x031F, 0x0000, 0x0010, 0x0010,
+ "\xFF\xC4\x54\x0F\xFF\xE0\x54\x07\x2F\x25\xE0\x24\xB4\xF5\x82\xE4"},
+ {0x40, 0xA0, 0x032F, 0x0000, 0x0010, 0x0010,
+ "\x34\x7F\xF5\x83\xE0\x54\xFD\x90\x7F\x00\xF0\xE4\xA3\xF0\x90\x7F"},
+ {0x40, 0xA0, 0x033F, 0x0000, 0x0010, 0x0010,
+ "\xB5\x74\x02\xF0\x02\x04\x05\x90\x7F\xC4\x74\x01\xF0\x02\x04\x05"},
+ {0x40, 0xA0, 0x034F, 0x0000, 0x0010, 0x0010,
+ "\x12\x0B\xB8\x40\x03\x02\x04\x05\x90\x7F\xE8\xE0\x24\xFE\x60\x1C"},
+ {0x40, 0xA0, 0x035F, 0x0000, 0x0010, 0x0010,
+ "\x24\x02\x60\x03\x02\x04\x05\x90\x7F\xEA\xE0\xB4\x01\x05\xC2\x03"},
+ {0x40, 0xA0, 0x036F, 0x0000, 0x0010, 0x0010,
+ "\x02\x04\x05\x90\x7F\xC4\x74\x01\xF0\x02\x04\x05\x90\x7F\xEA\xE0"},
+ {0x40, 0xA0, 0x037F, 0x0000, 0x0010, 0x0010,
+ "\x70\x1F\x90\x7F\xEC\xE0\xF4\x54\x80\xFF\xC4\x54\x0F\xFF\xE0\x54"},
+ {0x40, 0xA0, 0x038F, 0x0000, 0x0010, 0x0010,
+ "\x07\x2F\x25\xE0\x24\xB4\xF5\x82\xE4\x34\x7F\xF5\x83\xE4\xF0\x80"},
+ {0x40, 0xA0, 0x039F, 0x0000, 0x0010, 0x0010,
+ "\x65\x90\x7F\xC4\x74\x01\xF0\x80\x5D\x12\x0B\xBA\x50\x58\x90\x7F"},
+ {0x40, 0xA0, 0x03AF, 0x0000, 0x0010, 0x0010,
+ "\xE8\xE0\x24\xFE\x60\x17\x24\x02\x70\x4C\x90\x7F\xEA\xE0\xB4\x01"},
+ {0x40, 0xA0, 0x03BF, 0x0000, 0x0010, 0x0010,
+ "\x04\xD2\x03\x80\x41\x90\x7F\xC4\x74\x01\xF0\x80\x39\x90\x7F\xEA"},
+ {0x40, 0xA0, 0x03CF, 0x0000, 0x0010, 0x0010,
+ "\xE0\x70\x20\x90\x7F\xEC\xE0\xF4\x54\x80\xFF\xC4\x54\x0F\xFF\xE0"},
+ {0x40, 0xA0, 0x03DF, 0x0000, 0x0010, 0x0010,
+ "\x54\x07\x2F\x25\xE0\x24\xB4\xF5\x82\xE4\x34\x7F\xF5\x83\x74\x01"},
+ {0x40, 0xA0, 0x03EF, 0x0000, 0x0010, 0x0010,
+ "\xF0\x80\x13\x90\x7F\xC4\x74\x01\xF0\x80\x0B\x12\x0B\xBC\x50\x06"},
+ {0x40, 0xA0, 0x03FF, 0x0000, 0x000D, 0x000D,
+ "\x90\x7F\xC4\x74\x01\xF0\x90\x7F\xB4\xE0\x44\x02\xF0"},
+ {0x40, 0xA0, 0x040C, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x09E1, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xDE\x74\x06\xF0\x90\x7F\xDF\x74\x04\xF0\x90\x7F\xDD\x74"},
+ {0x40, 0xA0, 0x09F1, 0x0000, 0x0010, 0x0010,
+ "\x18\xF0\x90\x7F\xB6\x74\x02\xF0\x90\x7F\xB8\xF0\x90\x7F\xBA\xF0"},
+ {0x40, 0xA0, 0x0A01, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xBC\xF0\x90\x7F\xBE\xF0\x90\x7F\xC0\xF0\x90\x7F\xC2\xF0"},
+ {0x40, 0xA0, 0x0A11, 0x0000, 0x0006, 0x0006, "\xE4\x90\x7F\xC9\xF0\x22"},
+ {0x40, 0xA0, 0x0B91, 0x0000, 0x0009, 0x0009,
+ "\x90\x7F\xAF\xE0\x44\x08\xF0\xD3\x22"},
+ {0x40, 0xA0, 0x0BB2, 0x0000, 0x0002, 0x0002, "\xD3\x22"},
+ {0x40, 0xA0, 0x0BB4, 0x0000, 0x0002, 0x0002, "\xD3\x22"},
+ {0x40, 0xA0, 0x0B9A, 0x0000, 0x0008, 0x0008,
+ "\x90\x7F\xEA\xE0\xF5\x76\xD3\x22"},
+ {0x40, 0xA0, 0x0B68, 0x0000, 0x000E, 0x000E,
+ "\x90\x7F\x00\xE5\x76\xF0\x90\x7F\xB5\x74\x01\xF0\xD3\x22"},
+ {0x40, 0xA0, 0x0BA2, 0x0000, 0x0008, 0x0008,
+ "\x90\x7F\xEA\xE0\xF5\x75\xD3\x22"},
+ {0x40, 0xA0, 0x0B76, 0x0000, 0x000E, 0x000E,
+ "\x90\x7F\x00\xE5\x75\xF0\x90\x7F\xB5\x74\x01\xF0\xD3\x22"},
+ {0x40, 0xA0, 0x0BB6, 0x0000, 0x0002, 0x0002, "\xD3\x22"},
+ {0x40, 0xA0, 0x0BB8, 0x0000, 0x0002, 0x0002, "\xD3\x22"},
+ {0x40, 0xA0, 0x0BBA, 0x0000, 0x0002, 0x0002, "\xD3\x22"},
+ {0x40, 0xA0, 0x0BBC, 0x0000, 0x0002, 0x0002, "\xD3\x22"},
+ {0x40, 0xA0, 0x0A6D, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\xD2"},
+ {0x40, 0xA0, 0x0A7D, 0x0000, 0x0010, 0x0010,
+ "\x01\x53\x91\xEF\x90\x7F\xAB\x74\x01\xF0\xD0\x86\xD0\x84\xD0\x85"},
+ {0x40, 0xA0, 0x0A8D, 0x0000, 0x0007, 0x0007,
+ "\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x0A43, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\x90"},
+ {0x40, 0xA0, 0x0A53, 0x0000, 0x0010, 0x0010,
+ "\x7F\xC4\xE4\xF0\x53\x91\xEF\x90\x7F\xAB\x74\x04\xF0\xD0\x86\xD0"},
+ {0x40, 0xA0, 0x0A63, 0x0000, 0x000A, 0x000A,
+ "\x84\xD0\x85\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x0803, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\xC0"},
+ {0x40, 0xA0, 0x0813, 0x0000, 0x0001, 0x0001, "\xD0"},
+ {0x40, 0xA0, 0x0814, 0x0000, 0x0010, 0x0010,
+ "\x53\x91\xEF\x90\x7F\xAB\x74\x02\xF0\x30\x05\x14\x15\x72\xE5\x72"},
+ {0x40, 0xA0, 0x0824, 0x0000, 0x0010, 0x0010,
+ "\x70\x2E\x43\x21\x10\xC2\x05\xC3\x74\x1E\x95\x74\xF5\x72\x80\x20"},
+ {0x40, 0xA0, 0x0834, 0x0000, 0x0010, 0x0010,
+ "\xD5\x72\x1D\x53\x21\xEF\xD2\x05\xE5\x73\x25\x74\xF5\x74\x64\x02"},
+ {0x40, 0xA0, 0x0844, 0x0000, 0x0010, 0x0010,
+ "\x60\x05\xE5\x74\xB4\x1C\x06\xE5\x73\xF4\x04\xF5\x73\x85\x74\x72"},
+ {0x40, 0xA0, 0x0854, 0x0000, 0x000F, 0x000F,
+ "\xD0\xD0\xD0\x86\xD0\x84\xD0\x85\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x0ABB, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\x53"},
+ {0x40, 0xA0, 0x0ACB, 0x0000, 0x0010, 0x0010,
+ "\x91\xEF\x90\x7F\xAB\x74\x10\xF0\xD0\x86\xD0\x84\xD0\x85\xD0\x82"},
+ {0x40, 0xA0, 0x0ADB, 0x0000, 0x0005, 0x0005, "\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x0BBE, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0A94, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\xD2"},
+ {0x40, 0xA0, 0x0AA4, 0x0000, 0x0010, 0x0010,
+ "\x04\x53\x91\xEF\x90\x7F\xAB\x74\x08\xF0\xD0\x86\xD0\x84\xD0\x85"},
+ {0x40, 0xA0, 0x0AB4, 0x0000, 0x0007, 0x0007,
+ "\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x0BBF, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BC0, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BC1, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BC2, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BC3, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BC4, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BC5, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BC6, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BC7, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BC8, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BC9, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BCA, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BCB, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BCC, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BCD, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BCE, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0B26, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xD6\xE0\x30\xE7\x12\xE0\x44\x01\xF0\x7F\x14\x7E\x00\x12"},
+ {0x40, 0xA0, 0x0B36, 0x0000, 0x000A, 0x000A,
+ "\x0B\x40\x90\x7F\xD6\xE0\x54\xFE\xF0\x22"},
+ {0x40, 0xA0, 0x0B05, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xD6\xE0\x44\x80\xF0\x43\x87\x01\x00\x00\x00\x00\x00\x22"},
+ {0x40, 0xA0, 0x0AE0, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xD6\xE0\x54\xFB\xF0\xE0\x44\x08\xF0\x30\x06\x04\xE0\x44"},
+ {0x40, 0xA0, 0x0AF0, 0x0000, 0x0010, 0x0010,
+ "\x02\xF0\x7F\xF4\x7E\x01\x12\x0B\x40\x90\x7F\xD6\xE0\x54\xF7\xF0"},
+ {0x40, 0xA0, 0x0B00, 0x0000, 0x0005, 0x0005, "\xE0\x44\x04\xF0\x22"},
+ {0x40, 0xA0, 0x09A0, 0x0000, 0x0002, 0x0002, "\x8F\x6D"},
+ {0x40, 0xA0, 0x09A2, 0x0000, 0x0010, 0x0010,
+ "\xE4\xF5\x6E\x75\x6F\xFF\x75\x70\x01\x75\x71\xF9\xAB\x6F\xAA\x70"},
+ {0x40, 0xA0, 0x09B2, 0x0000, 0x0010, 0x0010,
+ "\xA9\x71\x90\x00\x01\x12\x06\xAC\xB4\x03\x1D\xAF\x6E\x05\x6E\xEF"},
+ {0x40, 0xA0, 0x09C2, 0x0000, 0x0010, 0x0010,
+ "\xB5\x6D\x01\x22\x12\x06\x93\x7E\x00\x29\xFF\xEE\x3A\xA9\x07\x75"},
+ {0x40, 0xA0, 0x09D2, 0x0000, 0x000E, 0x000E,
+ "\x6F\xFF\xF5\x70\x89\x71\x80\xD4\x7B\x00\x7A\x00\x79\x00"},
+ {0x40, 0xA0, 0x09E0, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0863, 0x0000, 0x0010, 0x0010,
+ "\xE4\xFE\x75\x6F\xFF\x75\x70\x01\x75\x71\xD2\xAB\x6F\xAA\x70\xA9"},
+ {0x40, 0xA0, 0x0873, 0x0000, 0x0010, 0x0010,
+ "\x71\x90\x00\x01\x12\x06\xAC\x64\x02\x70\x2D\xAD\x06\x0E\xED\xB5"},
+ {0x40, 0xA0, 0x0883, 0x0000, 0x0010, 0x0010,
+ "\x07\x01\x22\x90\x00\x02\x12\x06\xD9\x85\xF0\x6D\xF5\x6E\x62\x6D"},
+ {0x40, 0xA0, 0x0893, 0x0000, 0x0010, 0x0010,
+ "\xE5\x6D\x62\x6E\xE5\x6E\x62\x6D\x29\xFD\xE5\x6D\x3A\xA9\x05\x75"},
+ {0x40, 0xA0, 0x08A3, 0x0000, 0x000E, 0x000E,
+ "\x6F\xFF\xF5\x70\x89\x71\x80\xC3\x7B\x00\x7A\x00\x79\x00"},
+ {0x40, 0xA0, 0x08B1, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0B40, 0x0000, 0x0010, 0x0010,
+ "\x8E\x6A\x8F\x6B\xE5\x6B\x15\x6B\xAE\x6A\x70\x02\x15\x6A\x4E\x60"},
+ {0x40, 0xA0, 0x0B50, 0x0000, 0x0007, 0x0007,
+ "\x05\x12\x0B\x15\x80\xEE\x22"},
+ {0x40, 0xA0, 0x0B15, 0x0000, 0x0010, 0x0010,
+ "\x74\x00\xF5\x86\x90\xFD\xA5\x7C\x05\xA3\xE5\x82\x45\x83\x70\xF9"},
+ {0x40, 0xA0, 0x0B25, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0000, 0x0000, 0x0003, 0x0003, "\x02\x05\x7C"},
+ {0x40, 0xA0, 0x057C, 0x0000, 0x000C, 0x000C,
+ "\x78\x7F\xE4\xF6\xD8\xFD\x75\x81\x76\x02\x05\xC3"},
+ {0x40, 0xA0, 0x0693, 0x0000, 0x0010, 0x0010,
+ "\xBB\x01\x06\x89\x82\x8A\x83\xE0\x22\x50\x02\xE7\x22\xBB\xFE\x02"},
+ {0x40, 0xA0, 0x06A3, 0x0000, 0x0009, 0x0009,
+ "\xE3\x22\x89\x82\x8A\x83\xE4\x93\x22"},
+ {0x40, 0xA0, 0x06AC, 0x0000, 0x0010, 0x0010,
+ "\xBB\x01\x0C\xE5\x82\x29\xF5\x82\xE5\x83\x3A\xF5\x83\xE0\x22\x50"},
+ {0x40, 0xA0, 0x06BC, 0x0000, 0x0010, 0x0010,
+ "\x06\xE9\x25\x82\xF8\xE6\x22\xBB\xFE\x06\xE9\x25\x82\xF8\xE2\x22"},
+ {0x40, 0xA0, 0x06CC, 0x0000, 0x000D, 0x000D,
+ "\xE5\x82\x29\xF5\x82\xE5\x83\x3A\xF5\x83\xE4\x93\x22"},
+ {0x40, 0xA0, 0x06D9, 0x0000, 0x0010, 0x0010,
+ "\xBB\x01\x10\xE5\x82\x29\xF5\x82\xE5\x83\x3A\xF5\x83\xE0\xF5\xF0"},
+ {0x40, 0xA0, 0x06E9, 0x0000, 0x0010, 0x0010,
+ "\xA3\xE0\x22\x50\x09\xE9\x25\x82\xF8\x86\xF0\x08\xE6\x22\xBB\xFE"},
+ {0x40, 0xA0, 0x06F9, 0x0000, 0x0010, 0x0010,
+ "\x0A\xE9\x25\x82\xF8\xE2\xF5\xF0\x08\xE2\x22\xE5\x83\x2A\xF5\x83"},
+ {0x40, 0xA0, 0x0709, 0x0000, 0x0008, 0x0008,
+ "\xE9\x93\xF5\xF0\xA3\xE9\x93\x22"},
+ {0x40, 0xA0, 0x0711, 0x0000, 0x0006, 0x0006, "\x8A\x83\x89\x82\xE4\x73"},
+ {0x40, 0xA0, 0x0588, 0x0000, 0x0010, 0x0010,
+ "\x02\x04\x0D\xE4\x93\xA3\xF8\xE4\x93\xA3\x40\x03\xF6\x80\x01\xF2"},
+ {0x40, 0xA0, 0x0598, 0x0000, 0x0010, 0x0010,
+ "\x08\xDF\xF4\x80\x29\xE4\x93\xA3\xF8\x54\x07\x24\x0C\xC8\xC3\x33"},
+ {0x40, 0xA0, 0x05A8, 0x0000, 0x0010, 0x0010,
+ "\xC4\x54\x0F\x44\x20\xC8\x83\x40\x04\xF4\x56\x80\x01\x46\xF6\xDF"},
+ {0x40, 0xA0, 0x05B8, 0x0000, 0x0010, 0x0010,
+ "\xE4\x80\x0B\x01\x02\x04\x08\x10\x20\x40\x80\x90\x08\xB2\xE4\x7E"},
+ {0x40, 0xA0, 0x05C8, 0x0000, 0x0010, 0x0010,
+ "\x01\x93\x60\xBC\xA3\xFF\x54\x3F\x30\xE5\x09\x54\x1F\xFE\xE4\x93"},
+ {0x40, 0xA0, 0x05D8, 0x0000, 0x0010, 0x0010,
+ "\xA3\x60\x01\x0E\xCF\x54\xC0\x25\xE0\x60\xA8\x40\xB8\xE4\x93\xA3"},
+ {0x40, 0xA0, 0x05E8, 0x0000, 0x0010, 0x0010,
+ "\xFA\xE4\x93\xA3\xF8\xE4\x93\xA3\xC8\xC5\x82\xC8\xCA\xC5\x83\xCA"},
+ {0x40, 0xA0, 0x05F8, 0x0000, 0x0010, 0x0010,
+ "\xF0\xA3\xC8\xC5\x82\xC8\xCA\xC5\x83\xCA\xDF\xE9\xDE\xE7\x80\xBE"},
+ {0x40, 0xA0, 0x08FC, 0x0000, 0x0001, 0x0001, "\x00"},
+ {0x40, 0xA0, 0x7F92, 0x0000, 0x0001, 0x0001, "\x01"},
+ {0x40, 0xA0, 0x7F92, 0x0000, 0x0001, 0x0001, "\x00"},
+ {0x00, 0x05, 0x0002, 0x0000, 0x0000, 0x0000, ""},
+ {0x00, 0x09, 0x0001, 0x0000, 0x0000, 0x0000, ""},
+ {0x00, 0x00, 0x0000, 0x0000, 0x0000, 0x0000, NULL}
+};
diff --git a/kernel/drv/oss_usb/midisport2x2_fw.h b/kernel/drv/oss_usb/midisport2x2_fw.h
new file mode 100755
index 0000000..8bfb036
--- /dev/null
+++ b/kernel/drv/oss_usb/midisport2x2_fw.h
@@ -0,0 +1,756 @@
+/*
+ * Purpose: Firmware download for Midiman MIDISport 2x2
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This this source file is released under GPL v2 license (no other versions).
+ * See the COPYING file included in the main directory of this source
+ * distribution for the license terms and conditions.
+ *
+ */
+struct setup_request
+{
+ unsigned char bmRequestType;
+ unsigned char bRequest;
+ unsigned short wValue;
+ unsigned short wIndex;
+ unsigned short wLength;
+ unsigned short cbData;
+ const /*unsigned */ char *pData;
+};
+
+const struct setup_request midisport2x2_setupRequest[] = {
+ {0x00, 0x05, 0x0002, 0x0000, 0x0000, 0x0000, ""},
+ {0x40, 0xA0, 0x7F92, 0x0000, 0x0001, 0x0001, "\x01"},
+ {0x40, 0xA0, 0x7F92, 0x0000, 0x0001, 0x0001, "\x01"},
+ {0x40, 0xA0, 0x146C, 0x0000, 0x0010, 0x0010,
+ "\xC2\x00\x90\x7F\xA5\xE0\x54\x18\xFF\x13\x13\x13\x54\x1F\x44\x50"},
+ {0x40, 0xA0, 0x147C, 0x0000, 0x0010, 0x0010,
+ "\xF5\x1C\x13\x92\x01\xD2\xE8\x90\x7F\xAB\x74\xFF\xF0\x90\x7F\xA9"},
+ {0x40, 0xA0, 0x148C, 0x0000, 0x0010, 0x0010,
+ "\xF0\x90\x7F\xAA\xF0\x53\x91\xEF\x90\x7F\x95\xE0\x44\xC0\xF0\x90"},
+ {0x40, 0xA0, 0x149C, 0x0000, 0x0010, 0x0010,
+ "\x7F\xAF\xE0\x44\x01\xF0\x90\x7F\xAE\xE0\x44\x05\xF0\xD2\xAF\x12"},
+ {0x40, 0xA0, 0x14AC, 0x0000, 0x000D, 0x000D,
+ "\x17\x5F\x30\x00\xFD\x12\x11\x00\xC2\x00\x80\xF6\x22"},
+ {0x40, 0xA0, 0x1100, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xE9\xE0\x24\x5D\x60\x0D\x14\x70\x03\x02\x12\x44\x24\x02"},
+ {0x40, 0xA0, 0x1110, 0x0000, 0x0010, 0x0010,
+ "\x60\x03\x02\x12\x4A\x90\x7F\xEA\xE0\x75\x08\x00\xF5\x09\xA3\xE0"},
+ {0x40, 0xA0, 0x1120, 0x0000, 0x0010, 0x0010,
+ "\xFE\xE4\x25\x09\xF5\x09\xEE\x35\x08\xF5\x08\x90\x7F\xEE\xE0\x75"},
+ {0x40, 0xA0, 0x1130, 0x0000, 0x0010, 0x0010,
+ "\x0A\x00\xF5\x0B\xA3\xE0\xFE\xE4\x25\x0B\xF5\x0B\xEE\x35\x0A\xF5"},
+ {0x40, 0xA0, 0x1140, 0x0000, 0x0010, 0x0010,
+ "\x0A\x90\x7F\xE8\xE0\x64\xC0\x60\x03\x02\x11\xD4\xE5\x0B\x45\x0A"},
+ {0x40, 0xA0, 0x1150, 0x0000, 0x0010, 0x0010,
+ "\x70\x03\x02\x12\x4A\xC3\xE5\x0B\x94\x40\xE5\x0A\x94\x00\x50\x08"},
+ {0x40, 0xA0, 0x1160, 0x0000, 0x0010, 0x0010,
+ "\x85\x0A\x0C\x85\x0B\x0D\x80\x06\x75\x0C\x00\x75\x0D\x40\x90\x7F"},
+ {0x40, 0xA0, 0x1170, 0x0000, 0x0010, 0x0010,
+ "\xE9\xE0\xB4\xA3\x25\xAE\x0C\xAF\x0D\xAA\x08\xA9\x09\x7B\x01\xC0"},
+ {0x40, 0xA0, 0x1180, 0x0000, 0x0010, 0x0010,
+ "\x03\xC0\x02\xC0\x01\x7A\x7F\x79\x00\x78\x00\x7C\x7F\xAD\x03\xD0"},
+ {0x40, 0xA0, 0x1190, 0x0000, 0x0010, 0x0010,
+ "\x01\xD0\x02\xD0\x03\x12\x13\x56\x80\x0F\xAF\x09\xAE\x08\xAD\x0D"},
+ {0x40, 0xA0, 0x11A0, 0x0000, 0x0010, 0x0010,
+ "\x7A\x7F\x79\x00\x7B\x00\x12\x15\xA4\x90\x7F\xB5\xE5\x0D\xF0\xE5"},
+ {0x40, 0xA0, 0x11B0, 0x0000, 0x0010, 0x0010,
+ "\x0D\x25\x09\xF5\x09\xE5\x0C\x35\x08\xF5\x08\xC3\xE5\x0B\x95\x0D"},
+ {0x40, 0xA0, 0x11C0, 0x0000, 0x0010, 0x0010,
+ "\xF5\x0B\xE5\x0A\x95\x0C\xF5\x0A\x90\x7F\xB4\xE0\x20\xE2\x03\x02"},
+ {0x40, 0xA0, 0x11D0, 0x0000, 0x0010, 0x0010,
+ "\x11\x4C\x80\xF4\x90\x7F\xE8\xE0\x64\x40\x70\x6E\xE5\x0B\x45\x0A"},
+ {0x40, 0xA0, 0x11E0, 0x0000, 0x0010, 0x0010,
+ "\x60\x68\xE4\x90\x7F\xC5\xF0\x90\x7F\xB4\xE0\x20\xE3\xF9\x90\x7F"},
+ {0x40, 0xA0, 0x11F0, 0x0000, 0x0010, 0x0010,
+ "\xC5\xE0\x75\x0C\x00\xF5\x0D\x90\x7F\xE9\xE0\xB4\xA3\x15\xAE\x0C"},
+ {0x40, 0xA0, 0x1200, 0x0000, 0x0010, 0x0010,
+ "\xAF\x0D\xA8\x09\xAC\x08\x7D\x01\x7B\x01\x7A\x7E\x79\xC0\x12\x13"},
+ {0x40, 0xA0, 0x1210, 0x0000, 0x0010, 0x0010,
+ "\x56\x80\x0F\xAF\x09\xAE\x08\xAD\x0D\x7A\x7F\x79\x00\x7B\x00\x12"},
+ {0x40, 0xA0, 0x1220, 0x0000, 0x0010, 0x0010,
+ "\x14\xB9\xE5\x0D\x25\x09\xF5\x09\xE5\x0C\x35\x08\xF5\x08\xC3\xE5"},
+ {0x40, 0xA0, 0x1230, 0x0000, 0x0010, 0x0010,
+ "\x0B\x95\x0D\xF5\x0B\xE5\x0A\x95\x0C\xF5\x0A\x90\x7F\xB4\xE0\x44"},
+ {0x40, 0xA0, 0x1240, 0x0000, 0x000A, 0x000A,
+ "\x02\xF0\x80\x98\x90\x7F\xEA\xE0\xF5\x1C"},
+ {0x40, 0xA0, 0x124A, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x1558, 0x0000, 0x0006, 0x0006, "\xAB\x07\xAA\x06\xAC\x05"},
+ {0x40, 0xA0, 0x155E, 0x0000, 0x0010, 0x0010,
+ "\xE4\xFD\x30\x01\x11\xEA\xFF\xAE\x05\x0D\xEE\x24\x00\xF5\x82\xE4"},
+ {0x40, 0xA0, 0x156E, 0x0000, 0x0010, 0x0010,
+ "\x34\xE0\xF5\x83\xEF\xF0\xEB\xAE\x05\x0D\x74\x00\x2E\xF5\x82\xE4"},
+ {0x40, 0xA0, 0x157E, 0x0000, 0x0010, 0x0010,
+ "\x34\xE0\xF5\x83\xEB\xF0\xAF\x05\x0D\x74\x00\x2F\xF5\x82\xE4\x34"},
+ {0x40, 0xA0, 0x158E, 0x0000, 0x0010, 0x0010,
+ "\xE0\xF5\x83\xEC\xF0\xAF\x1C\x7A\xE0\x7B\x00\x12\x17\x20\x7F\x0A"},
+ {0x40, 0xA0, 0x159E, 0x0000, 0x0005, 0x0005, "\x7E\x00\x12\x17\x3C"},
+ {0x40, 0xA0, 0x15A3, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x14B9, 0x0000, 0x000A, 0x000A,
+ "\x8E\x0E\x8F\x0F\x8D\x10\x8A\x11\x8B\x12"},
+ {0x40, 0xA0, 0x14C3, 0x0000, 0x0010, 0x0010,
+ "\xE4\xF5\x13\xE5\x13\xC3\x95\x10\x50\x20\x05\x0F\xE5\x0F\xAE\x0E"},
+ {0x40, 0xA0, 0x14D3, 0x0000, 0x0010, 0x0010,
+ "\x70\x02\x05\x0E\x14\xFF\xE5\x12\x25\x13\xF5\x82\xE4\x35\x11\xF5"},
+ {0x40, 0xA0, 0x14E3, 0x0000, 0x000A, 0x000A,
+ "\x83\xE0\xFD\x12\x15\x58\x05\x13\x80\xD9"},
+ {0x40, 0xA0, 0x14ED, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x15A4, 0x0000, 0x000A, 0x000A,
+ "\x8E\x0E\x8F\x0F\x8D\x10\x8A\x11\x8B\x12"},
+ {0x40, 0xA0, 0x15AE, 0x0000, 0x0010, 0x0010,
+ "\xE4\xFD\x30\x01\x12\xE5\x0E\xFF\xAE\x05\x0D\xEE\x24\x03\xF5\x82"},
+ {0x40, 0xA0, 0x15BE, 0x0000, 0x0010, 0x0010,
+ "\xE4\x34\xE0\xF5\x83\xEF\xF0\xE5\x0F\xAE\x05\x0D\x74\x03\x2E\xF5"},
+ {0x40, 0xA0, 0x15CE, 0x0000, 0x0010, 0x0010,
+ "\x82\xE4\x34\xE0\xF5\x83\xE5\x0F\xF0\xAF\x1C\x7A\xE0\x7B\x03\x12"},
+ {0x40, 0xA0, 0x15DE, 0x0000, 0x000D, 0x000D,
+ "\x17\x20\xAF\x1C\xAD\x10\xAB\x12\xAA\x11\x12\x17\x04"},
+ {0x40, 0xA0, 0x15EB, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x166E, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\xD2"},
+ {0x40, 0xA0, 0x167E, 0x0000, 0x0010, 0x0010,
+ "\x00\x53\x91\xEF\x90\x7F\xAB\x74\x01\xF0\xD0\x86\xD0\x84\xD0\x85"},
+ {0x40, 0xA0, 0x168E, 0x0000, 0x0007, 0x0007,
+ "\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x1644, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\x90"},
+ {0x40, 0xA0, 0x1654, 0x0000, 0x0010, 0x0010,
+ "\x7F\xC4\xE4\xF0\x53\x91\xEF\x90\x7F\xAB\x74\x04\xF0\xD0\x86\xD0"},
+ {0x40, 0xA0, 0x1664, 0x0000, 0x000A, 0x000A,
+ "\x84\xD0\x85\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x1695, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\x53"},
+ {0x40, 0xA0, 0x16A5, 0x0000, 0x0010, 0x0010,
+ "\x91\xEF\x90\x7F\xAB\x74\x02\xF0\xD0\x86\xD0\x84\xD0\x85\xD0\x82"},
+ {0x40, 0xA0, 0x16B5, 0x0000, 0x0005, 0x0005, "\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x16BA, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\x53"},
+ {0x40, 0xA0, 0x16CA, 0x0000, 0x0010, 0x0010,
+ "\x91\xEF\x90\x7F\xAB\x74\x10\xF0\xD0\x86\xD0\x84\xD0\x85\xD0\x82"},
+ {0x40, 0xA0, 0x16DA, 0x0000, 0x0005, 0x0005, "\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x14FF, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x16DF, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\x53"},
+ {0x40, 0xA0, 0x16EF, 0x0000, 0x0010, 0x0010,
+ "\x91\xEF\x90\x7F\xAB\x74\x08\xF0\xD0\x86\xD0\x84\xD0\x85\xD0\x82"},
+ {0x40, 0xA0, 0x16FF, 0x0000, 0x0005, 0x0005, "\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x1767, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1768, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1769, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x176A, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x176B, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x176C, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x176D, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x176E, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x176F, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1770, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1771, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1772, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1773, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1774, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1775, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1776, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0043, 0x0000, 0x0003, 0x0003, "\x02\x15\x00"},
+ {0x40, 0xA0, 0x1500, 0x0000, 0x0010, 0x0010,
+ "\x02\x16\x6E\x00\x02\x16\x95\x00\x02\x16\x44\x00\x02\x16\xDF\x00"},
+ {0x40, 0xA0, 0x1510, 0x0000, 0x0010, 0x0010,
+ "\x02\x16\xBA\x00\x02\x14\xFF\x00\x02\x17\x67\x00\x02\x17\x68\x00"},
+ {0x40, 0xA0, 0x1520, 0x0000, 0x0010, 0x0010,
+ "\x02\x17\x69\x00\x02\x17\x6A\x00\x02\x17\x6B\x00\x02\x17\x6C\x00"},
+ {0x40, 0xA0, 0x1530, 0x0000, 0x0010, 0x0010,
+ "\x02\x17\x6D\x00\x02\x17\x6E\x00\x02\x17\x6F\x00\x02\x17\x70\x00"},
+ {0x40, 0xA0, 0x1540, 0x0000, 0x0010, 0x0010,
+ "\x02\x17\x71\x00\x02\x17\x72\x00\x02\x17\x73\x00\x02\x17\x74\x00"},
+ {0x40, 0xA0, 0x1550, 0x0000, 0x0008, 0x0008,
+ "\x02\x17\x75\x00\x02\x17\x76\x00"},
+ {0x40, 0xA0, 0x173C, 0x0000, 0x0010, 0x0010,
+ "\x8E\x14\x8F\x15\xE5\x15\x15\x15\xAE\x14\x70\x02\x15\x14\x4E\x60"},
+ {0x40, 0xA0, 0x174C, 0x0000, 0x0007, 0x0007,
+ "\x05\x12\x14\xEE\x80\xEE\x22"},
+ {0x40, 0xA0, 0x175F, 0x0000, 0x0008, 0x0008,
+ "\xE4\xF5\x1B\xD2\xE9\xD2\xAF\x22"},
+ {0x40, 0xA0, 0x1619, 0x0000, 0x0010, 0x0010,
+ "\xA9\x07\xE5\x1B\x70\x23\x90\x7F\xA5\xE0\x44\x80\xF0\xE9\x25\xE0"},
+ {0x40, 0xA0, 0x1629, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xA6\xF0\x8D\x16\xAF\x03\xA9\x07\x75\x17\x01\x8A\x18\x89"},
+ {0x40, 0xA0, 0x1639, 0x0000, 0x000B, 0x000B,
+ "\x19\xE4\xF5\x1A\x75\x1B\x01\xD3\x22\xC3\x22"},
+ {0x40, 0xA0, 0x15EC, 0x0000, 0x0010, 0x0010,
+ "\xA9\x07\xE5\x1B\x70\x25\x90\x7F\xA5\xE0\x44\x80\xF0\xE9\x25\xE0"},
+ {0x40, 0xA0, 0x15FC, 0x0000, 0x0010, 0x0010,
+ "\x44\x01\x90\x7F\xA6\xF0\x8D\x16\xAF\x03\xA9\x07\x75\x17\x01\x8A"},
+ {0x40, 0xA0, 0x160C, 0x0000, 0x000D, 0x000D,
+ "\x18\x89\x19\xE4\xF5\x1A\x75\x1B\x03\xD3\x22\xC3\x22"},
+ {0x40, 0xA0, 0x004B, 0x0000, 0x0003, 0x0003, "\x02\x13\x7F"},
+ {0x40, 0xA0, 0x137F, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\xC0"},
+ {0x40, 0xA0, 0x138F, 0x0000, 0x0010, 0x0010,
+ "\xD0\x75\xD0\x00\xC0\x00\xC0\x01\xC0\x02\xC0\x03\xC0\x06\xC0\x07"},
+ {0x40, 0xA0, 0x139F, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xA5\xE0\x30\xE2\x06\x75\x1B\x06\x02\x14\x4E\x90\x7F\xA5"},
+ {0x40, 0xA0, 0x13AF, 0x0000, 0x0010, 0x0010,
+ "\xE0\x20\xE1\x0C\xE5\x1B\x64\x02\x60\x06\x75\x1B\x07\x02\x14\x4E"},
+ {0x40, 0xA0, 0x13BF, 0x0000, 0x0010, 0x0010,
+ "\xAF\x1B\xEF\x24\xFE\x60\x48\x14\x60\x2C\x24\xFE\x60\x77\x24\x04"},
+ {0x40, 0xA0, 0x13CF, 0x0000, 0x0010, 0x0010,
+ "\x60\x03\x02\x14\x4E\xAB\x17\xAA\x18\xA9\x19\xAF\x1A\x05\x1A\x8F"},
+ {0x40, 0xA0, 0x13DF, 0x0000, 0x0010, 0x0010,
+ "\x82\x75\x83\x00\x12\x12\x4B\x90\x7F\xA6\xF0\xE5\x1A\x65\x16\x70"},
+ {0x40, 0xA0, 0x13EF, 0x0000, 0x0010, 0x0010,
+ "\x5E\x75\x1B\x05\x80\x59\x90\x7F\xA6\xE0\xAB\x17\xAA\x18\xA9\x19"},
+ {0x40, 0xA0, 0x13FF, 0x0000, 0x0010, 0x0010,
+ "\xAE\x1A\x8E\x82\x75\x83\x00\x12\x12\x78\x75\x1B\x02\x80\x40\xE5"},
+ {0x40, 0xA0, 0x140F, 0x0000, 0x0010, 0x0010,
+ "\x16\x24\xFE\xB5\x1A\x07\x90\x7F\xA5\xE0\x44\x20\xF0\xE5\x16\x14"},
+ {0x40, 0xA0, 0x141F, 0x0000, 0x0010, 0x0010,
+ "\xB5\x1A\x0A\x90\x7F\xA5\xE0\x44\x40\xF0\x75\x1B\x00\x90\x7F\xA6"},
+ {0x40, 0xA0, 0x142F, 0x0000, 0x0010, 0x0010,
+ "\xE0\xAB\x17\xAA\x18\xA9\x19\xAE\x1A\x8E\x82\x75\x83\x00\x12\x12"},
+ {0x40, 0xA0, 0x143F, 0x0000, 0x0010, 0x0010,
+ "\x78\x05\x1A\x80\x0A\x90\x7F\xA5\xE0\x44\x40\xF0\x75\x1B\x00\x53"},
+ {0x40, 0xA0, 0x144F, 0x0000, 0x0010, 0x0010,
+ "\x91\xDF\xD0\x07\xD0\x06\xD0\x03\xD0\x02\xD0\x01\xD0\x00\xD0\xD0"},
+ {0x40, 0xA0, 0x145F, 0x0000, 0x000D, 0x000D,
+ "\xD0\x86\xD0\x84\xD0\x85\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x1704, 0x0000, 0x0010, 0x0010,
+ "\x12\x15\xEC\xE5\x1B\x24\xFA\x60\x0E\x14\x60\x06\x24\x07\x70\xF3"},
+ {0x40, 0xA0, 0x1714, 0x0000, 0x000C, 0x000C,
+ "\xD3\x22\xE4\xF5\x1B\xD3\x22\xE4\xF5\x1B\xD3\x22"},
+ {0x40, 0xA0, 0x1720, 0x0000, 0x0010, 0x0010,
+ "\x12\x16\x19\xE5\x1B\x24\xFA\x60\x0E\x14\x60\x06\x24\x07\x70\xF3"},
+ {0x40, 0xA0, 0x1730, 0x0000, 0x000C, 0x000C,
+ "\xD3\x22\xE4\xF5\x1B\xD3\x22\xE4\xF5\x1B\xD3\x22"},
+ {0x40, 0xA0, 0x14EE, 0x0000, 0x0010, 0x0010,
+ "\x74\x00\xF5\x86\x90\xFD\xA5\x7C\x05\xA3\xE5\x82\x45\x83\x70\xF9"},
+ {0x40, 0xA0, 0x14FE, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0000, 0x0000, 0x0003, 0x0003, "\x02\x17\x53"},
+ {0x40, 0xA0, 0x1753, 0x0000, 0x000C, 0x000C,
+ "\x78\x7F\xE4\xF6\xD8\xFD\x75\x81\x20\x02\x14\x6C"},
+ {0x40, 0xA0, 0x124B, 0x0000, 0x0010, 0x0010,
+ "\xBB\x01\x0C\xE5\x82\x29\xF5\x82\xE5\x83\x3A\xF5\x83\xE0\x22\x50"},
+ {0x40, 0xA0, 0x125B, 0x0000, 0x0010, 0x0010,
+ "\x06\xE9\x25\x82\xF8\xE6\x22\xBB\xFE\x06\xE9\x25\x82\xF8\xE2\x22"},
+ {0x40, 0xA0, 0x126B, 0x0000, 0x000D, 0x000D,
+ "\xE5\x82\x29\xF5\x82\xE5\x83\x3A\xF5\x83\xE4\x93\x22"},
+ {0x40, 0xA0, 0x1278, 0x0000, 0x0010, 0x0010,
+ "\xF8\xBB\x01\x0D\xE5\x82\x29\xF5\x82\xE5\x83\x3A\xF5\x83\xE8\xF0"},
+ {0x40, 0xA0, 0x1288, 0x0000, 0x0010, 0x0010,
+ "\x22\x50\x06\xE9\x25\x82\xC8\xF6\x22\xBB\xFE\x05\xE9\x25\x82\xC8"},
+ {0x40, 0xA0, 0x1298, 0x0000, 0x0002, 0x0002, "\xF2\x22"},
+ {0x40, 0xA0, 0x129A, 0x0000, 0x0010, 0x0010,
+ "\xE7\x09\xF6\x08\xDF\xFA\x80\x46\xE7\x09\xF2\x08\xDF\xFA\x80\x3E"},
+ {0x40, 0xA0, 0x12AA, 0x0000, 0x0010, 0x0010,
+ "\x88\x82\x8C\x83\xE7\x09\xF0\xA3\xDF\xFA\x80\x32\xE3\x09\xF6\x08"},
+ {0x40, 0xA0, 0x12BA, 0x0000, 0x0010, 0x0010,
+ "\xDF\xFA\x80\x6E\xE3\x09\xF2\x08\xDF\xFA\x80\x66\x88\x82\x8C\x83"},
+ {0x40, 0xA0, 0x12CA, 0x0000, 0x0010, 0x0010,
+ "\xE3\x09\xF0\xA3\xDF\xFA\x80\x5A\x89\x82\x8A\x83\xE0\xA3\xF6\x08"},
+ {0x40, 0xA0, 0x12DA, 0x0000, 0x0010, 0x0010,
+ "\xDF\xFA\x80\x4E\x89\x82\x8A\x83\xE0\xA3\xF2\x08\xDF\xFA\x80\x42"},
+ {0x40, 0xA0, 0x12EA, 0x0000, 0x0010, 0x0010,
+ "\x80\xD2\x80\xFA\x80\xC6\x80\xD4\x80\x55\x80\xF2\x80\x29\x80\x10"},
+ {0x40, 0xA0, 0x12FA, 0x0000, 0x0010, 0x0010,
+ "\x80\xA6\x80\xEA\x80\x9A\x80\xA8\x80\xDA\x80\xE2\x80\xCA\x80\x29"},
+ {0x40, 0xA0, 0x130A, 0x0000, 0x0010, 0x0010,
+ "\x88\x84\x8C\x85\x89\x82\x8A\x83\xE4\x93\xA3\x05\x86\xF0\xA3\x05"},
+ {0x40, 0xA0, 0x131A, 0x0000, 0x0010, 0x0010,
+ "\x86\xDF\xF5\xDE\xF3\x80\x0B\x89\x82\x8A\x83\xE4\x93\xA3\xF6\x08"},
+ {0x40, 0xA0, 0x132A, 0x0000, 0x0010, 0x0010,
+ "\xDF\xF9\xEC\xFA\xA9\xF0\xED\xFB\x22\x88\x84\x8C\x85\x89\x82\x8A"},
+ {0x40, 0xA0, 0x133A, 0x0000, 0x0010, 0x0010,
+ "\x83\xE0\xA3\x05\x86\xF0\xA3\x05\x86\xDF\xF6\xDE\xF4\x80\xE3\x89"},
+ {0x40, 0xA0, 0x134A, 0x0000, 0x0010, 0x0010,
+ "\x82\x8A\x83\xE4\x93\xA3\xF2\x08\xDF\xF9\x80\xD6\x88\xF0\xED\x24"},
+ {0x40, 0xA0, 0x135A, 0x0000, 0x0010, 0x0010,
+ "\x02\xB4\x04\x00\x50\xCC\xF5\x82\xEB\x24\x02\xB4\x04\x00\x50\xC2"},
+ {0x40, 0xA0, 0x136A, 0x0000, 0x0010, 0x0010,
+ "\x23\x23\x45\x82\xF5\x82\xEF\x4E\x60\xB8\xEF\x60\x01\x0E\xE5\x82"},
+ {0x40, 0xA0, 0x137A, 0x0000, 0x0005, 0x0005, "\x23\x90\x12\xEA\x73"},
+ {0x40, 0xA0, 0x7F92, 0x0000, 0x0001, 0x0001, "\x00"},
+ {0x40, 0xA0, 0x7F92, 0x0000, 0x0001, 0x0001, "\x01"},
+ {0x40, 0xA0, 0x0100, 0x0000, 0x0010, 0x0010,
+ "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x0110, 0x0000, 0x0010, 0x0010,
+ "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x0120, 0x0000, 0x0010, 0x0010,
+ "\x4D\x69\x64\x69\x6D\x61\x6E\x20\x55\x53\x42\x20\x4D\x69\x64\x69"},
+ {0x40, 0xA0, 0x0130, 0x0000, 0x0010, 0x0010,
+ "\x53\x70\x6F\x72\x74\x20\x32\x78\x32\x20\x20\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x0140, 0x0000, 0x0010, 0x0010,
+ "\x46\x69\x72\x6D\x77\x61\x72\x65\x20\x52\x65\x6C\x65\x61\x73\x65"},
+ {0x40, 0xA0, 0x0150, 0x0000, 0x0010, 0x0010,
+ "\x20\x31\x2E\x32\x31\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x0160, 0x0000, 0x0010, 0x0010,
+ "\x28\x63\x29\x20\x31\x39\x39\x39\x2D\x32\x30\x30\x31\x2C\x20\x4D"},
+ {0x40, 0xA0, 0x0170, 0x0000, 0x0010, 0x0010,
+ "\x69\x64\x69\x6D\x61\x6E\x20\x49\x6E\x63\x2E\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x0180, 0x0000, 0x0010, 0x0010,
+ "\x41\x6C\x6C\x20\x72\x69\x67\x68\x74\x73\x20\x72\x65\x73\x65\x72"},
+ {0x40, 0xA0, 0x0190, 0x0000, 0x0010, 0x0010,
+ "\x76\x65\x64\x2E\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x01A0, 0x0000, 0x0010, 0x0010,
+ "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x01B0, 0x0000, 0x0010, 0x0010,
+ "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x0962, 0x0000, 0x0003, 0x0003, "\x01\x40\x00"},
+ {0x40, 0xA0, 0x041B, 0x0000, 0x0010, 0x0010,
+ "\xC2\x01\xC2\x00\xC2\x05\xC2\x04\x12\x0A\xBA\xD2\xE8\x43\xD8\x20"},
+ {0x40, 0xA0, 0x042B, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xAB\x74\xFF\xF0\x90\x7F\xA9\xF0\x90\x7F\xAA\xF0\x53\x91"},
+ {0x40, 0xA0, 0x043B, 0x0000, 0x0010, 0x0010,
+ "\xEF\x90\x7F\x95\xE0\x44\xC0\xF0\x90\x7F\xAF\xE0\x44\x01\xF0\x90"},
+ {0x40, 0xA0, 0x044B, 0x0000, 0x0010, 0x0010,
+ "\x7F\xAE\xE0\x44\x1D\xF0\x90\x7F\x92\xE0\x44\x02\xF0\x90\x7F\x94"},
+ {0x40, 0xA0, 0x045B, 0x0000, 0x0010, 0x0010,
+ "\xE0\x44\x04\xF0\x90\x7F\x9D\xE0\x54\xFB\xF0\x90\x7F\x95\xE0\x44"},
+ {0x40, 0xA0, 0x046B, 0x0000, 0x0010, 0x0010,
+ "\x01\xF0\x90\x7F\x9E\xE0\x54\xFE\xF0\x90\x7F\x94\xE0\x44\x08\xF0"},
+ {0x40, 0xA0, 0x047B, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\x9D\xE0\x44\x08\xF0\x90\x7F\x95\xE0\x44\x02\xF0\x90\x7F"},
+ {0x40, 0xA0, 0x048B, 0x0000, 0x0010, 0x0010,
+ "\x9E\xE0\x44\x02\xF0\x90\x7F\x95\xE0\x54\x83\xF0\x90\x7F\x9E\xE0"},
+ {0x40, 0xA0, 0x049B, 0x0000, 0x0010, 0x0010,
+ "\x44\x7C\xF0\x90\x7F\x94\xE0\x54\xFE\xF0\x90\x7F\x9D\xE0\x44\x01"},
+ {0x40, 0xA0, 0x04AB, 0x0000, 0x0010, 0x0010,
+ "\xF0\x90\x7F\x9A\xE0\x44\x01\x90\x7F\x97\xF0\x43\x08\x20\x43\x08"},
+ {0x40, 0xA0, 0x04BB, 0x0000, 0x0010, 0x0010,
+ "\x08\x43\x08\x10\x43\x08\x04\x43\x08\x40\x53\x89\xF0\xE4\xF5\x8C"},
+ {0x40, 0xA0, 0x04CB, 0x0000, 0x0010, 0x0010,
+ "\xF5\x8A\xD2\x8C\xD2\xA9\x12\x00\x36\xD2\xAF\xE5\x89\x54\x0F\x24"},
+ {0x40, 0xA0, 0x04DB, 0x0000, 0x0010, 0x0010,
+ "\x20\xF5\x89\x75\x8D\xFE\x75\x8B\xFE\xD2\x8E\xC2\xAC\x75\x98\x50"},
+ {0x40, 0xA0, 0x04EB, 0x0000, 0x0010, 0x0010,
+ "\xC2\x98\xC2\x99\xD2\xAC\xC2\xAE\x75\xC0\x50\xC2\xC0\xC2\xC1\xD2"},
+ {0x40, 0xA0, 0x04FB, 0x0000, 0x0010, 0x0010,
+ "\xAE\x53\x08\xDF\x53\x08\xEF\x53\x08\xF7\x53\x08\xFB\x53\x08\xBF"},
+ {0x40, 0xA0, 0x050B, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\x9A\xE0\x54\xFE\x90\x7F\x97\xF0\x90\x7F\x98\xE5\x08\xF0"},
+ {0x40, 0xA0, 0x051B, 0x0000, 0x0010, 0x0010,
+ "\x75\x0D\x3D\xE5\x0D\x70\xFC\x43\x08\x20\x43\x08\x10\x43\x08\x08"},
+ {0x40, 0xA0, 0x052B, 0x0000, 0x0010, 0x0010,
+ "\x43\x08\x04\x43\x08\x40\x90\x7F\x98\xE5\x08\xF0\x20\x01\x11\x75"},
+ {0x40, 0xA0, 0x053B, 0x0000, 0x0010, 0x0010,
+ "\x0D\xF4\xE5\x0D\x70\xFC\x20\x01\xF3\xD2\x07\x12\x0C\x21\x80\xEC"},
+ {0x40, 0xA0, 0x054B, 0x0000, 0x0010, 0x0010,
+ "\x30\x01\x0C\x12\x02\x0D\xC2\x01\x90\x7F\xAE\xE0\x44\x02\xF0\x30"},
+ {0x40, 0xA0, 0x055B, 0x0000, 0x0010, 0x0010,
+ "\x05\x1A\x12\x0A\xF4\x50\x13\x12\x0C\x46\x20\x04\x07\x90\x7F\xD6"},
+ {0x40, 0xA0, 0x056B, 0x0000, 0x0010, 0x0010,
+ "\xE0\x20\xE7\xF3\x12\x0C\x67\x12\x00\x41\xC2\x05\x05\x40\xE5\x40"},
+ {0x40, 0xA0, 0x057B, 0x0000, 0x0010, 0x0010,
+ "\xC3\x94\x08\x40\x03\xE4\xF5\x40\xE5\x40\x75\xF0\x03\xA4\x24\x23"},
+ {0x40, 0xA0, 0x058B, 0x0000, 0x000C, 0x000C,
+ "\xF8\x08\xE6\xFA\x08\xE6\xF9\x12\x07\xEC\x80\xB4"},
+ {0x40, 0xA0, 0x0597, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0033, 0x0000, 0x0003, 0x0003, "\x02\x00\x1F"},
+ {0x40, 0xA0, 0x001F, 0x0000, 0x0004, 0x0004, "\x53\xD8\xEF\x32"},
+ {0x40, 0xA0, 0x0023, 0x0000, 0x0003, 0x0003, "\x02\x08\x6E"},
+ {0x40, 0xA0, 0x086E, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\xC0"},
+ {0x40, 0xA0, 0x087E, 0x0000, 0x000C, 0x000C,
+ "\xD0\x75\xD0\x00\xC0\x00\xC0\x05\xC0\x06\xC0\x07"},
+ {0x40, 0xA0, 0x088A, 0x0000, 0x0010, 0x0010,
+ "\x30\x99\x23\xC2\x99\xE5\x14\x60\x1B\xAF\x11\x05\x11\x74\x00\x2F"},
+ {0x40, 0xA0, 0x089A, 0x0000, 0x0010, 0x0010,
+ "\xF5\x82\xE4\x34\x0E\xF5\x83\xE0\xF5\x99\x15\x14\x53\x08\xEF\x75"},
+ {0x40, 0xA0, 0x08AA, 0x0000, 0x0010, 0x0010,
+ "\x0B\x0C\x80\x02\xD2\x02\x30\x98\x1E\xC2\x98\xAF\x99\xE5\x10\x04"},
+ {0x40, 0xA0, 0x08BA, 0x0000, 0x0010, 0x0010,
+ "\x54\x3F\xFE\x65\x0E\x60\x0A\xAD\x10\x74\x42\x2D\xF8\xA6\x07\x8E"},
+ {0x40, 0xA0, 0x08CA, 0x0000, 0x0007, 0x0007,
+ "\x10\x53\x08\xDF\x75\x09\x0C"},
+ {0x40, 0xA0, 0x08D1, 0x0000, 0x0010, 0x0010,
+ "\xD0\x07\xD0\x06\xD0\x05\xD0\x00\xD0\xD0\xD0\x86\xD0\x84\xD0\x85"},
+ {0x40, 0xA0, 0x08E1, 0x0000, 0x0007, 0x0007,
+ "\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x003B, 0x0000, 0x0003, 0x0003, "\x02\x08\xE8"},
+ {0x40, 0xA0, 0x08E8, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\xC0"},
+ {0x40, 0xA0, 0x08F8, 0x0000, 0x000C, 0x000C,
+ "\xD0\x75\xD0\x00\xC0\x00\xC0\x05\xC0\x06\xC0\x07"},
+ {0x40, 0xA0, 0x0904, 0x0000, 0x0010, 0x0010,
+ "\x30\xC1\x23\xC2\xC1\xE5\x15\x60\x1B\xAF\x13\x05\x13\x74\x00\x2F"},
+ {0x40, 0xA0, 0x0914, 0x0000, 0x0010, 0x0010,
+ "\xF5\x82\xE4\x34\x0F\xF5\x83\xE0\xF5\xC1\x15\x15\x53\x08\xFB\x75"},
+ {0x40, 0xA0, 0x0924, 0x0000, 0x0010, 0x0010,
+ "\x0C\x0C\x80\x02\xD2\x03\x30\xC0\x1E\xC2\xC0\xAF\xC1\xE5\x12\x04"},
+ {0x40, 0xA0, 0x0934, 0x0000, 0x0010, 0x0010,
+ "\x54\x3F\xFE\x65\x0F\x60\x0A\xAD\x12\x74\x82\x2D\xF8\xA6\x07\x8E"},
+ {0x40, 0xA0, 0x0944, 0x0000, 0x0007, 0x0007,
+ "\x12\x53\x08\xF7\x75\x0A\x0C"},
+ {0x40, 0xA0, 0x094B, 0x0000, 0x0010, 0x0010,
+ "\xD0\x07\xD0\x06\xD0\x05\xD0\x00\xD0\xD0\xD0\x86\xD0\x84\xD0\x85"},
+ {0x40, 0xA0, 0x095B, 0x0000, 0x0007, 0x0007,
+ "\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x00D2, 0x0000, 0x0010, 0x0010,
+ "\xA2\xAC\x92\x07\xC2\xAC\x30\x02\x0C\xC2\x02\x8F\x99\x53\x08\xEF"},
+ {0x40, 0xA0, 0x00E2, 0x0000, 0x0010, 0x0010,
+ "\x75\x0B\x0C\x80\x12\xAE\x16\x05\x16\x74\x00\x2E\xF5\x82\xE4\x34"},
+ {0x40, 0xA0, 0x00F2, 0x0000, 0x000B, 0x000B,
+ "\x0E\xF5\x83\xEF\xF0\x05\x14\xA2\x07\x92\xAC"},
+ {0x40, 0xA0, 0x00FD, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0B58, 0x0000, 0x0010, 0x0010,
+ "\xA2\xAE\x92\x07\xC2\xAE\x30\x03\x0C\xC2\x03\x8F\xC1\x53\x08\xFB"},
+ {0x40, 0xA0, 0x0B68, 0x0000, 0x0010, 0x0010,
+ "\x75\x0C\x0C\x80\x12\xAE\x17\x05\x17\x74\x00\x2E\xF5\x82\xE4\x34"},
+ {0x40, 0xA0, 0x0B78, 0x0000, 0x000B, 0x000B,
+ "\x0F\xF5\x83\xEF\xF0\x05\x15\xA2\x07\x92\xAE"},
+ {0x40, 0xA0, 0x0B83, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x01C0, 0x0000, 0x0010, 0x0010,
+ "\x12\x01\x00\x01\x00\x00\x00\x40\x63\x07\x02\x10\x21\x01\x00\x00"},
+ {0x40, 0xA0, 0x01D0, 0x0000, 0x0010, 0x0010,
+ "\x00\x01\x09\x02\x35\x00\x01\x01\x00\xA0\x00\x09\x04\x00\x00\x05"},
+ {0x40, 0xA0, 0x01E0, 0x0000, 0x0010, 0x0010,
+ "\xFF\x00\x00\x00\x07\x05\x81\x03\x20\x00\x01\x07\x05\x82\x02\x20"},
+ {0x40, 0xA0, 0x01F0, 0x0000, 0x0010, 0x0010,
+ "\x00\x00\x07\x05\x02\x02\x20\x00\x00\x07\x05\x84\x02\x20\x00\x00"},
+ {0x40, 0xA0, 0x0200, 0x0000, 0x000D, 0x000D,
+ "\x07\x05\x04\x02\x20\x00\x00\x04\x03\x09\x04\x00\x00"},
+ {0x40, 0xA0, 0x0965, 0x0000, 0x0010, 0x0010,
+ "\x01\x0D\x00\xC1\x01\x01\x09\x00\x01\x0A\x00\x01\x08\xFF\x01\x0B"},
+ {0x40, 0xA0, 0x0975, 0x0000, 0x0010, 0x0010,
+ "\x00\x01\x0C\x00\xC1\x82\xC1\x83\x01\x0E\x00\x01\x10\x00\x01\x0F"},
+ {0x40, 0xA0, 0x0985, 0x0000, 0x0010, 0x0010,
+ "\x00\x01\x12\x00\x01\x11\x00\x01\x16\x00\x01\x14\x00\x01\x13\x00"},
+ {0x40, 0xA0, 0x0995, 0x0000, 0x0006, 0x0006, "\x01\x17\x00\x01\x15\x00"},
+ {0x40, 0xA0, 0x0043, 0x0000, 0x0003, 0x0003, "\x02\x0B\x00"},
+ {0x40, 0xA0, 0x0B00, 0x0000, 0x0010, 0x0010,
+ "\x02\x0B\xAE\x00\x02\x09\xCA\x00\x02\x0B\x84\x00\x02\x0B\xD5\x00"},
+ {0x40, 0xA0, 0x0B10, 0x0000, 0x0010, 0x0010,
+ "\x02\x0B\xFC\x00\x02\x00\x3A\x00\x02\x0A\xFF\x00\x02\x0C\xC2\x00"},
+ {0x40, 0xA0, 0x0B20, 0x0000, 0x0010, 0x0010,
+ "\x02\x0C\xC3\x00\x02\x0C\xC4\x00\x02\x0C\xC5\x00\x02\x0C\xC6\x00"},
+ {0x40, 0xA0, 0x0B30, 0x0000, 0x0010, 0x0010,
+ "\x02\x0C\xC7\x00\x02\x0C\xC8\x00\x02\x0C\xC9\x00\x02\x0C\xCA\x00"},
+ {0x40, 0xA0, 0x0B40, 0x0000, 0x0010, 0x0010,
+ "\x02\x0C\xCB\x00\x02\x0C\xCC\x00\x02\x0C\xCD\x00\x02\x0C\xCE\x00"},
+ {0x40, 0xA0, 0x0B50, 0x0000, 0x0008, 0x0008,
+ "\x02\x0C\xCF\x00\x02\x0C\xD0\x00"},
+ {0x40, 0xA0, 0x099B, 0x0000, 0x0010, 0x0010,
+ "\x18\x23\xFF\x05\x98\xFF\x06\x58\xFF\x06\xE3\xFF\x07\xF2\xFF\x05"},
+ {0x40, 0xA0, 0x09AB, 0x0000, 0x0010, 0x0010,
+ "\x98\xFF\x06\x58\xFF\x06\xE3\xFF\x00\x0E\x01\x21\xFF\x01\x22\x00"},
+ {0x40, 0xA0, 0x0598, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xB6\xE0\x30\xE1\x03\x02\x06\x57\x7A\x7E\x79\x80\x7E\x7E"},
+ {0x40, 0xA0, 0x05A8, 0x0000, 0x0010, 0x0010,
+ "\x7F\x80\x74\x7E\x90\x7F\xE3\xF0\x74\x80\x90\x7F\xE4\xF0\xE4\xFF"},
+ {0x40, 0xA0, 0x05B8, 0x0000, 0x0010, 0x0010,
+ "\xE5\x10\x65\x0E\x60\x43\xEF\xC3\x94\x04\x50\x3D\xE4\xFD\xE5\x10"},
+ {0x40, 0xA0, 0x05C8, 0x0000, 0x0010, 0x0010,
+ "\x65\x0E\x60\x1B\xED\xC3\x94\x03\x50\x15\x74\x42\x25\x0E\xF8\xE6"},
+ {0x40, 0xA0, 0x05D8, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xE5\xF0\x05\x0E\xE5\x0E\x54\x3F\xF5\x0E\x0D\x80\xDF\xED"},
+ {0x40, 0xA0, 0x05E8, 0x0000, 0x0010, 0x0010,
+ "\x60\xCE\xFC\xEC\xC3\x94\x03\x50\x08\xE4\x90\x7F\xE5\xF0\x0C\x80"},
+ {0x40, 0xA0, 0x05F8, 0x0000, 0x0010, 0x0010,
+ "\xF2\x90\x7F\xE5\xED\xF0\x0F\x80\xB7\xE5\x12\x65\x0F\x60\x45\xEF"},
+ {0x40, 0xA0, 0x0608, 0x0000, 0x0010, 0x0010,
+ "\xC3\x94\x08\x50\x3F\xE4\xFD\xE5\x12\x65\x0F\x60\x1B\xED\xC3\x94"},
+ {0x40, 0xA0, 0x0618, 0x0000, 0x0010, 0x0010,
+ "\x03\x50\x15\x74\x82\x25\x0F\xF8\xE6\x90\x7F\xE5\xF0\x05\x0F\xE5"},
+ {0x40, 0xA0, 0x0628, 0x0000, 0x0010, 0x0010,
+ "\x0F\x54\x3F\xF5\x0F\x0D\x80\xDF\xED\x60\xCE\xFC\xEC\xC3\x94\x03"},
+ {0x40, 0xA0, 0x0638, 0x0000, 0x0010, 0x0010,
+ "\x50\x08\xE4\x90\x7F\xE5\xF0\x0C\x80\xF2\xED\x24\x10\x90\x7F\xE5"},
+ {0x40, 0xA0, 0x0648, 0x0000, 0x000F, 0x000F,
+ "\xF0\x0F\x80\xB5\xEF\x60\x08\x25\xE0\x25\xE0\x90\x7F\xB7\xF0"},
+ {0x40, 0xA0, 0x0657, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x07F2, 0x0000, 0x0010, 0x0010,
+ "\xE5\x21\x60\x1C\x14\x60\x30\x14\x60\x44\x14\x60\x58\x80\x00\x12"},
+ {0x40, 0xA0, 0x0802, 0x0000, 0x0010, 0x0010,
+ "\x00\x3E\xEF\x65\x22\x60\x64\x12\x00\x3E\x8F\x22\xE4\xF5\x21\x22"},
+ {0x40, 0xA0, 0x0812, 0x0000, 0x0010, 0x0010,
+ "\xE5\x09\x60\x10\xD5\x09\x0D\xA2\xAF\x92\x07\xC2\xAF\x43\x08\x20"},
+ {0x40, 0xA0, 0x0822, 0x0000, 0x0010, 0x0010,
+ "\xA2\x07\x92\xAF\x05\x21\x22\xE5\x0A\x60\x10\xD5\x0A\x0D\xA2\xAF"},
+ {0x40, 0xA0, 0x0832, 0x0000, 0x0010, 0x0010,
+ "\x92\x07\xC2\xAF\x43\x08\x08\xA2\x07\x92\xAF\x05\x21\x22\xE5\x0B"},
+ {0x40, 0xA0, 0x0842, 0x0000, 0x0010, 0x0010,
+ "\x60\x10\xD5\x0B\x0D\xA2\xAF\x92\x07\xC2\xAF\x43\x08\x10\xA2\x07"},
+ {0x40, 0xA0, 0x0852, 0x0000, 0x0010, 0x0010,
+ "\x92\xAF\x05\x21\x22\xE5\x0C\x60\x10\xD5\x0C\x0D\xA2\xAF\x92\x07"},
+ {0x40, 0xA0, 0x0862, 0x0000, 0x000B, 0x000B,
+ "\xC2\xAF\x43\x08\x04\xA2\x07\x92\xAF\x05\x21"},
+ {0x40, 0xA0, 0x086D, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x000E, 0x0000, 0x0010, 0x0010,
+ "\xA2\xAF\x92\x07\xC2\xAF\x90\x7F\x98\xE5\x08\xF0\xA2\x07\x92\xAF"},
+ {0x40, 0xA0, 0x001E, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0658, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xC8\xE0\x30\xE1\x03\x02\x06\xE2\x90\x7F\xC9\xE0\xF5\x18"},
+ {0x40, 0xA0, 0x0668, 0x0000, 0x0010, 0x0010,
+ "\xC3\xE4\x95\x14\xFF\x74\x01\x94\x00\xFE\xC3\xE5\x18\x9F\xE4\x9E"},
+ {0x40, 0xA0, 0x0678, 0x0000, 0x0010, 0x0010,
+ "\x50\x68\xE4\xF5\x19\xE5\x19\xC3\x95\x18\x50\x59\x74\xC3\x25\x19"},
+ {0x40, 0xA0, 0x0688, 0x0000, 0x0010, 0x0010,
+ "\xF5\x82\xE4\x34\x7D\xF5\x83\xE0\x54\x0F\xFD\x60\x48\x74\xC0\x25"},
+ {0x40, 0xA0, 0x0698, 0x0000, 0x0010, 0x0010,
+ "\x19\xF5\x82\xE4\x34\x7D\x90\x7F\xE3\xF0\x74\xC0\x25\x19\xF5\x82"},
+ {0x40, 0xA0, 0x06A8, 0x0000, 0x0010, 0x0010,
+ "\xE4\x34\x7D\xE5\x82\x90\x7F\xE4\xF0\xAF\x05\xED\x14\x60\x16\x14"},
+ {0x40, 0xA0, 0x06B8, 0x0000, 0x0010, 0x0010,
+ "\x60\x0B\x14\x70\x18\x90\x7F\xE5\xE0\xFF\x12\x00\xD2\x90\x7F\xE5"},
+ {0x40, 0xA0, 0x06C8, 0x0000, 0x0010, 0x0010,
+ "\xE0\xFF\x12\x00\xD2\x90\x7F\xE5\xE0\xFF\x12\x00\xD2\x74\x04\x25"},
+ {0x40, 0xA0, 0x06D8, 0x0000, 0x000A, 0x000A,
+ "\x19\xF5\x19\x80\xA0\xE4\x90\x7F\xC9\xF0"},
+ {0x40, 0xA0, 0x06E2, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x06E3, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xCC\xE0\x30\xE1\x03\x02\x07\x6D\x90\x7F\xCD\xE0\xF5\x18"},
+ {0x40, 0xA0, 0x06F3, 0x0000, 0x0010, 0x0010,
+ "\xC3\xE4\x95\x15\xFF\x74\x01\x94\x00\xFE\xC3\xE5\x18\x9F\xE4\x9E"},
+ {0x40, 0xA0, 0x0703, 0x0000, 0x0010, 0x0010,
+ "\x50\x68\xE4\xF5\x19\xE5\x19\xC3\x95\x18\x50\x59\x74\xC3\x25\x19"},
+ {0x40, 0xA0, 0x0713, 0x0000, 0x0010, 0x0010,
+ "\xF5\x82\xE4\x34\x7C\xF5\x83\xE0\x54\x0F\xFD\x60\x48\x74\xC0\x25"},
+ {0x40, 0xA0, 0x0723, 0x0000, 0x0010, 0x0010,
+ "\x19\xF5\x82\xE4\x34\x7C\x90\x7F\xE3\xF0\x74\xC0\x25\x19\xF5\x82"},
+ {0x40, 0xA0, 0x0733, 0x0000, 0x0010, 0x0010,
+ "\xE4\x34\x7C\xE5\x82\x90\x7F\xE4\xF0\xAF\x05\xED\x14\x60\x16\x14"},
+ {0x40, 0xA0, 0x0743, 0x0000, 0x0010, 0x0010,
+ "\x60\x0B\x14\x70\x18\x90\x7F\xE5\xE0\xFF\x12\x0B\x58\x90\x7F\xE5"},
+ {0x40, 0xA0, 0x0753, 0x0000, 0x0010, 0x0010,
+ "\xE0\xFF\x12\x0B\x58\x90\x7F\xE5\xE0\xFF\x12\x0B\x58\x74\x04\x25"},
+ {0x40, 0xA0, 0x0763, 0x0000, 0x000A, 0x000A,
+ "\x19\xF5\x19\x80\xA0\xE4\x90\x7F\xCD\xF0"},
+ {0x40, 0xA0, 0x076D, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x09BB, 0x0000, 0x0003, 0x0003, "\x01\x41\x00"},
+ {0x40, 0xA0, 0x000B, 0x0000, 0x0003, 0x0003, "\x02\x00\x26"},
+ {0x40, 0xA0, 0x0026, 0x0000, 0x000D, 0x000D,
+ "\xC0\xE0\x05\x41\xE5\x0D\x60\x02\x15\x0D\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x003E, 0x0000, 0x0003, 0x0003, "\xAF\x41\x22"},
+ {0x40, 0xA0, 0x0036, 0x0000, 0x0004, 0x0004, "\xE4\xF5\x41\x22"},
+ {0x40, 0xA0, 0x09BE, 0x0000, 0x000B, 0x000B,
+ "\x01\x3B\x01\x01\x3C\x01\xC1\x86\x01\x3D\x03"},
+ {0x40, 0xA0, 0x020D, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xE9\xE0\x70\x03\x02\x02\xE2\x14\x70\x03\x02\x03\x5D\x24"},
+ {0x40, 0xA0, 0x021D, 0x0000, 0x0010, 0x0010,
+ "\xFE\x70\x03\x02\x03\xB6\x24\xFB\x70\x03\x02\x02\xDC\x14\x70\x03"},
+ {0x40, 0xA0, 0x022D, 0x0000, 0x0010, 0x0010,
+ "\x02\x02\xD6\x14\x70\x03\x02\x02\xCA\x14\x70\x03\x02\x02\xD0\x24"},
+ {0x40, 0xA0, 0x023D, 0x0000, 0x0010, 0x0010,
+ "\x05\x60\x03\x02\x04\x08\x12\x00\xFE\x40\x03\x02\x04\x13\x90\x7F"},
+ {0x40, 0xA0, 0x024D, 0x0000, 0x0010, 0x0010,
+ "\xEB\xE0\x24\xFE\x60\x16\x14\x60\x3F\x24\x02\x70\x67\x74\x01\x90"},
+ {0x40, 0xA0, 0x025D, 0x0000, 0x0010, 0x0010,
+ "\x7F\xD4\xF0\x74\xC0\x90\x7F\xD5\xF0\x02\x04\x13\x90\x7F\xEA\xE0"},
+ {0x40, 0xA0, 0x026D, 0x0000, 0x0010, 0x0010,
+ "\xFF\x12\x0A\x2A\x8B\x18\x8A\x19\x89\x1A\xEA\x49\x60\x11\xAE\x02"},
+ {0x40, 0xA0, 0x027D, 0x0000, 0x0010, 0x0010,
+ "\xEE\x90\x7F\xD4\xF0\xAF\x01\xEF\x90\x7F\xD5\xF0\x02\x04\x13\x90"},
+ {0x40, 0xA0, 0x028D, 0x0000, 0x0010, 0x0010,
+ "\x7F\xC4\x74\x01\xF0\x02\x04\x13\x90\x7F\xEA\xE0\xFF\x12\x0A\x79"},
+ {0x40, 0xA0, 0x029D, 0x0000, 0x0010, 0x0010,
+ "\x8B\x18\x8A\x19\x89\x1A\xEA\x49\x60\x11\xAE\x02\xEE\x90\x7F\xD4"},
+ {0x40, 0xA0, 0x02AD, 0x0000, 0x0010, 0x0010,
+ "\xF0\xAF\x01\xEF\x90\x7F\xD5\xF0\x02\x04\x13\x90\x7F\xC4\x74\x01"},
+ {0x40, 0xA0, 0x02BD, 0x0000, 0x0010, 0x0010,
+ "\xF0\x02\x04\x13\x90\x7F\xC4\x74\x01\xF0\x02\x04\x13\x12\x0C\xA6"},
+ {0x40, 0xA0, 0x02CD, 0x0000, 0x0010, 0x0010,
+ "\x02\x04\x13\x12\x0C\xB4\x02\x04\x13\x12\x00\x03\x02\x04\x13\x12"},
+ {0x40, 0xA0, 0x02DD, 0x0000, 0x0010, 0x0010,
+ "\x0C\x98\x02\x04\x13\x12\x0A\xFD\x40\x03\x02\x04\x13\x90\x7F\xE8"},
+ {0x40, 0xA0, 0x02ED, 0x0000, 0x0010, 0x0010,
+ "\xE0\x24\x7F\x60\x24\x14\x60\x31\x24\x02\x70\x5B\xA2\x04\xE4\x33"},
+ {0x40, 0xA0, 0x02FD, 0x0000, 0x0010, 0x0010,
+ "\xFF\x25\xE0\xFF\xA2\x00\xE4\x33\x4F\x90\x7F\x00\xF0\xE4\xA3\xF0"},
+ {0x40, 0xA0, 0x030D, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xB5\x74\x02\xF0\x02\x04\x13\xE4\x90\x7F\x00\xF0\xA3\xF0"},
+ {0x40, 0xA0, 0x031D, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xB5\x74\x02\xF0\x02\x04\x13\x90\x7F\xEC\xE0\xF4\x54\x80"},
+ {0x40, 0xA0, 0x032D, 0x0000, 0x0010, 0x0010,
+ "\xFF\xC4\x54\x0F\xFF\xE0\x54\x07\x2F\x25\xE0\x24\xB4\xF5\x82\xE4"},
+ {0x40, 0xA0, 0x033D, 0x0000, 0x0010, 0x0010,
+ "\x34\x7F\xF5\x83\xE0\x54\xFD\x90\x7F\x00\xF0\xE4\xA3\xF0\x90\x7F"},
+ {0x40, 0xA0, 0x034D, 0x0000, 0x0010, 0x0010,
+ "\xB5\x74\x02\xF0\x02\x04\x13\x90\x7F\xC4\x74\x01\xF0\x02\x04\x13"},
+ {0x40, 0xA0, 0x035D, 0x0000, 0x0010, 0x0010,
+ "\x12\x0C\xBC\x40\x03\x02\x04\x13\x90\x7F\xE8\xE0\x24\xFE\x60\x1C"},
+ {0x40, 0xA0, 0x036D, 0x0000, 0x0010, 0x0010,
+ "\x24\x02\x60\x03\x02\x04\x13\x90\x7F\xEA\xE0\xB4\x01\x05\xC2\x04"},
+ {0x40, 0xA0, 0x037D, 0x0000, 0x0010, 0x0010,
+ "\x02\x04\x13\x90\x7F\xC4\x74\x01\xF0\x02\x04\x13\x90\x7F\xEA\xE0"},
+ {0x40, 0xA0, 0x038D, 0x0000, 0x0010, 0x0010,
+ "\x70\x1F\x90\x7F\xEC\xE0\xF4\x54\x80\xFF\xC4\x54\x0F\xFF\xE0\x54"},
+ {0x40, 0xA0, 0x039D, 0x0000, 0x0010, 0x0010,
+ "\x07\x2F\x25\xE0\x24\xB4\xF5\x82\xE4\x34\x7F\xF5\x83\xE4\xF0\x80"},
+ {0x40, 0xA0, 0x03AD, 0x0000, 0x0010, 0x0010,
+ "\x65\x90\x7F\xC4\x74\x01\xF0\x80\x5D\x12\x0C\xBE\x50\x58\x90\x7F"},
+ {0x40, 0xA0, 0x03BD, 0x0000, 0x0010, 0x0010,
+ "\xE8\xE0\x24\xFE\x60\x17\x24\x02\x70\x4C\x90\x7F\xEA\xE0\xB4\x01"},
+ {0x40, 0xA0, 0x03CD, 0x0000, 0x0010, 0x0010,
+ "\x04\xD2\x04\x80\x41\x90\x7F\xC4\x74\x01\xF0\x80\x39\x90\x7F\xEA"},
+ {0x40, 0xA0, 0x03DD, 0x0000, 0x0010, 0x0010,
+ "\xE0\x70\x20\x90\x7F\xEC\xE0\xF4\x54\x80\xFF\xC4\x54\x0F\xFF\xE0"},
+ {0x40, 0xA0, 0x03ED, 0x0000, 0x0010, 0x0010,
+ "\x54\x07\x2F\x25\xE0\x24\xB4\xF5\x82\xE4\x34\x7F\xF5\x83\x74\x01"},
+ {0x40, 0xA0, 0x03FD, 0x0000, 0x0010, 0x0010,
+ "\xF0\x80\x13\x90\x7F\xC4\x74\x01\xF0\x80\x0B\x12\x0C\xC0\x50\x06"},
+ {0x40, 0xA0, 0x040D, 0x0000, 0x000D, 0x000D,
+ "\x90\x7F\xC4\x74\x01\xF0\x90\x7F\xB4\xE0\x44\x02\xF0"},
+ {0x40, 0xA0, 0x041A, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0ABA, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xDE\x74\x16\xF0\x90\x7F\xDF\x74\x14\xF0\x90\x7F\xDD\x74"},
+ {0x40, 0xA0, 0x0ACA, 0x0000, 0x0010, 0x0010,
+ "\x18\xF0\x90\x7F\xB6\x74\x02\xF0\x90\x7F\xB8\xF0\x90\x7F\xBA\xF0"},
+ {0x40, 0xA0, 0x0ADA, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xBC\xF0\x90\x7F\xBE\xF0\x90\x7F\xC0\xF0\x90\x7F\xC2\xF0"},
+ {0x40, 0xA0, 0x0AEA, 0x0000, 0x000A, 0x000A,
+ "\xE4\x90\x7F\xC9\xF0\x90\x7F\xCD\xF0\x22"},
+ {0x40, 0xA0, 0x0AF4, 0x0000, 0x0009, 0x0009,
+ "\x90\x7F\xAF\xE0\x44\x08\xF0\xD3\x22"},
+ {0x40, 0xA0, 0x0041, 0x0000, 0x0002, 0x0002, "\xD3\x22"},
+ {0x40, 0xA0, 0x00FE, 0x0000, 0x0002, 0x0002, "\xD3\x22"},
+ {0x40, 0xA0, 0x0003, 0x0000, 0x0008, 0x0008,
+ "\x90\x7F\xEA\xE0\xF5\x3F\xD3\x22"},
+ {0x40, 0xA0, 0x0C98, 0x0000, 0x000E, 0x000E,
+ "\x90\x7F\x00\xE5\x3F\xF0\x90\x7F\xB5\x74\x01\xF0\xD3\x22"},
+ {0x40, 0xA0, 0x0CB4, 0x0000, 0x0008, 0x0008,
+ "\x90\x7F\xEA\xE0\xF5\x3E\xD3\x22"},
+ {0x40, 0xA0, 0x0CA6, 0x0000, 0x000E, 0x000E,
+ "\x90\x7F\x00\xE5\x3E\xF0\x90\x7F\xB5\x74\x01\xF0\xD3\x22"},
+ {0x40, 0xA0, 0x0AFD, 0x0000, 0x0002, 0x0002, "\xD3\x22"},
+ {0x40, 0xA0, 0x0CBC, 0x0000, 0x0002, 0x0002, "\xD3\x22"},
+ {0x40, 0xA0, 0x0CBE, 0x0000, 0x0002, 0x0002, "\xD3\x22"},
+ {0x40, 0xA0, 0x0CC0, 0x0000, 0x0002, 0x0002, "\xD3\x22"},
+ {0x40, 0xA0, 0x0BAE, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\xD2"},
+ {0x40, 0xA0, 0x0BBE, 0x0000, 0x0010, 0x0010,
+ "\x01\x53\x91\xEF\x90\x7F\xAB\x74\x01\xF0\xD0\x86\xD0\x84\xD0\x85"},
+ {0x40, 0xA0, 0x0BCE, 0x0000, 0x0007, 0x0007,
+ "\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x0B84, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\x90"},
+ {0x40, 0xA0, 0x0B94, 0x0000, 0x0010, 0x0010,
+ "\x7F\xC4\xE4\xF0\x53\x91\xEF\x90\x7F\xAB\x74\x04\xF0\xD0\x86\xD0"},
+ {0x40, 0xA0, 0x0BA4, 0x0000, 0x000A, 0x000A,
+ "\x84\xD0\x85\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x09CA, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\xC0"},
+ {0x40, 0xA0, 0x09DA, 0x0000, 0x0001, 0x0001, "\xD0"},
+ {0x40, 0xA0, 0x09DB, 0x0000, 0x0010, 0x0010,
+ "\x53\x91\xEF\x90\x7F\xAB\x74\x02\xF0\x30\x06\x14\x15\x3B\xE5\x3B"},
+ {0x40, 0xA0, 0x09EB, 0x0000, 0x0010, 0x0010,
+ "\x70\x2E\x43\x08\x40\xC2\x06\xC3\x74\x1E\x95\x3D\xF5\x3B\x80\x20"},
+ {0x40, 0xA0, 0x09FB, 0x0000, 0x0010, 0x0010,
+ "\xD5\x3B\x1D\x53\x08\xBF\xD2\x06\xE5\x3C\x25\x3D\xF5\x3D\x64\x03"},
+ {0x40, 0xA0, 0x0A0B, 0x0000, 0x0010, 0x0010,
+ "\x60\x05\xE5\x3D\xB4\x1C\x06\xE5\x3C\xF4\x04\xF5\x3C\x85\x3D\x3B"},
+ {0x40, 0xA0, 0x0A1B, 0x0000, 0x000F, 0x000F,
+ "\xD0\xD0\xD0\x86\xD0\x84\xD0\x85\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x0BFC, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\x53"},
+ {0x40, 0xA0, 0x0C0C, 0x0000, 0x0010, 0x0010,
+ "\x91\xEF\x90\x7F\xAB\x74\x10\xF0\xD0\x86\xD0\x84\xD0\x85\xD0\x82"},
+ {0x40, 0xA0, 0x0C1C, 0x0000, 0x0005, 0x0005, "\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x003A, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BD5, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\xD2"},
+ {0x40, 0xA0, 0x0BE5, 0x0000, 0x0010, 0x0010,
+ "\x05\x53\x91\xEF\x90\x7F\xAB\x74\x08\xF0\xD0\x86\xD0\x84\xD0\x85"},
+ {0x40, 0xA0, 0x0BF5, 0x0000, 0x0007, 0x0007,
+ "\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x0AFF, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0CC2, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0CC3, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0CC4, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0CC5, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0CC6, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0CC7, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0CC8, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0CC9, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0CCA, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0CCB, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0CCC, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0CCD, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0CCE, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0CCF, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0CD0, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0C67, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xD6\xE0\x30\xE7\x12\xE0\x44\x01\xF0\x7F\x14\x7E\x00\x12"},
+ {0x40, 0xA0, 0x0C77, 0x0000, 0x000A, 0x000A,
+ "\x0C\x81\x90\x7F\xD6\xE0\x54\xFE\xF0\x22"},
+ {0x40, 0xA0, 0x0C46, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xD6\xE0\x44\x80\xF0\x43\x87\x01\x00\x00\x00\x00\x00\x22"},
+ {0x40, 0xA0, 0x0C21, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xD6\xE0\x54\xFB\xF0\xE0\x44\x08\xF0\x30\x07\x04\xE0\x44"},
+ {0x40, 0xA0, 0x0C31, 0x0000, 0x0010, 0x0010,
+ "\x02\xF0\x7F\xF4\x7E\x01\x12\x0C\x81\x90\x7F\xD6\xE0\x54\xF7\xF0"},
+ {0x40, 0xA0, 0x0C41, 0x0000, 0x0005, 0x0005, "\xE0\x44\x04\xF0\x22"},
+ {0x40, 0xA0, 0x0A79, 0x0000, 0x0002, 0x0002, "\x8F\x1B"},
+ {0x40, 0xA0, 0x0A7B, 0x0000, 0x0010, 0x0010,
+ "\xE4\xF5\x1C\x75\x1D\xFF\x75\x1E\x02\x75\x1F\x07\xAB\x1D\xAA\x1E"},
+ {0x40, 0xA0, 0x0A8B, 0x0000, 0x0010, 0x0010,
+ "\xA9\x1F\x90\x00\x01\x12\x07\x87\xB4\x03\x1D\xAF\x1C\x05\x1C\xEF"},
+ {0x40, 0xA0, 0x0A9B, 0x0000, 0x0010, 0x0010,
+ "\xB5\x1B\x01\x22\x12\x07\x6E\x7E\x00\x29\xFF\xEE\x3A\xA9\x07\x75"},
+ {0x40, 0xA0, 0x0AAB, 0x0000, 0x000E, 0x000E,
+ "\x1D\xFF\xF5\x1E\x89\x1F\x80\xD4\x7B\x00\x7A\x00\x79\x00"},
+ {0x40, 0xA0, 0x0AB9, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0A2A, 0x0000, 0x0010, 0x0010,
+ "\xE4\xFE\x75\x1D\xFF\x75\x1E\x01\x75\x1F\xD2\xAB\x1D\xAA\x1E\xA9"},
+ {0x40, 0xA0, 0x0A3A, 0x0000, 0x0010, 0x0010,
+ "\x1F\x90\x00\x01\x12\x07\x87\x64\x02\x70\x2D\xAD\x06\x0E\xED\xB5"},
+ {0x40, 0xA0, 0x0A4A, 0x0000, 0x0010, 0x0010,
+ "\x07\x01\x22\x90\x00\x02\x12\x07\xB4\x85\xF0\x1B\xF5\x1C\x62\x1B"},
+ {0x40, 0xA0, 0x0A5A, 0x0000, 0x0010, 0x0010,
+ "\xE5\x1B\x62\x1C\xE5\x1C\x62\x1B\x29\xFD\xE5\x1B\x3A\xA9\x05\x75"},
+ {0x40, 0xA0, 0x0A6A, 0x0000, 0x000E, 0x000E,
+ "\x1D\xFF\xF5\x1E\x89\x1F\x80\xC3\x7B\x00\x7A\x00\x79\x00"},
+ {0x40, 0xA0, 0x0A78, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0C81, 0x0000, 0x0010, 0x0010,
+ "\x8E\x18\x8F\x19\xE5\x19\x15\x19\xAE\x18\x70\x02\x15\x18\x4E\x60"},
+ {0x40, 0xA0, 0x0C91, 0x0000, 0x0007, 0x0007,
+ "\x05\x12\x0C\x56\x80\xEE\x22"},
+ {0x40, 0xA0, 0x0C56, 0x0000, 0x0010, 0x0010,
+ "\x74\x00\xF5\x86\x90\xFD\xA5\x7C\x05\xA3\xE5\x82\x45\x83\x70\xF9"},
+ {0x40, 0xA0, 0x0C66, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0000, 0x0000, 0x0003, 0x0003, "\x02\x00\x46"},
+ {0x40, 0xA0, 0x0046, 0x0000, 0x000C, 0x000C,
+ "\x78\x7F\xE4\xF6\xD8\xFD\x75\x81\xC1\x02\x00\x8D"},
+ {0x40, 0xA0, 0x076E, 0x0000, 0x0010, 0x0010,
+ "\xBB\x01\x06\x89\x82\x8A\x83\xE0\x22\x50\x02\xE7\x22\xBB\xFE\x02"},
+ {0x40, 0xA0, 0x077E, 0x0000, 0x0009, 0x0009,
+ "\xE3\x22\x89\x82\x8A\x83\xE4\x93\x22"},
+ {0x40, 0xA0, 0x0787, 0x0000, 0x0010, 0x0010,
+ "\xBB\x01\x0C\xE5\x82\x29\xF5\x82\xE5\x83\x3A\xF5\x83\xE0\x22\x50"},
+ {0x40, 0xA0, 0x0797, 0x0000, 0x0010, 0x0010,
+ "\x06\xE9\x25\x82\xF8\xE6\x22\xBB\xFE\x06\xE9\x25\x82\xF8\xE2\x22"},
+ {0x40, 0xA0, 0x07A7, 0x0000, 0x000D, 0x000D,
+ "\xE5\x82\x29\xF5\x82\xE5\x83\x3A\xF5\x83\xE4\x93\x22"},
+ {0x40, 0xA0, 0x07B4, 0x0000, 0x0010, 0x0010,
+ "\xBB\x01\x10\xE5\x82\x29\xF5\x82\xE5\x83\x3A\xF5\x83\xE0\xF5\xF0"},
+ {0x40, 0xA0, 0x07C4, 0x0000, 0x0010, 0x0010,
+ "\xA3\xE0\x22\x50\x09\xE9\x25\x82\xF8\x86\xF0\x08\xE6\x22\xBB\xFE"},
+ {0x40, 0xA0, 0x07D4, 0x0000, 0x0010, 0x0010,
+ "\x0A\xE9\x25\x82\xF8\xE2\xF5\xF0\x08\xE2\x22\xE5\x83\x2A\xF5\x83"},
+ {0x40, 0xA0, 0x07E4, 0x0000, 0x0008, 0x0008,
+ "\xE9\x93\xF5\xF0\xA3\xE9\x93\x22"},
+ {0x40, 0xA0, 0x07EC, 0x0000, 0x0006, 0x0006, "\x8A\x83\x89\x82\xE4\x73"},
+ {0x40, 0xA0, 0x0052, 0x0000, 0x0010, 0x0010,
+ "\x02\x04\x1B\xE4\x93\xA3\xF8\xE4\x93\xA3\x40\x03\xF6\x80\x01\xF2"},
+ {0x40, 0xA0, 0x0062, 0x0000, 0x0010, 0x0010,
+ "\x08\xDF\xF4\x80\x29\xE4\x93\xA3\xF8\x54\x07\x24\x0C\xC8\xC3\x33"},
+ {0x40, 0xA0, 0x0072, 0x0000, 0x0010, 0x0010,
+ "\xC4\x54\x0F\x44\x20\xC8\x83\x40\x04\xF4\x56\x80\x01\x46\xF6\xDF"},
+ {0x40, 0xA0, 0x0082, 0x0000, 0x0010, 0x0010,
+ "\xE4\x80\x0B\x01\x02\x04\x08\x10\x20\x40\x80\x90\x09\x62\xE4\x7E"},
+ {0x40, 0xA0, 0x0092, 0x0000, 0x0010, 0x0010,
+ "\x01\x93\x60\xBC\xA3\xFF\x54\x3F\x30\xE5\x09\x54\x1F\xFE\xE4\x93"},
+ {0x40, 0xA0, 0x00A2, 0x0000, 0x0010, 0x0010,
+ "\xA3\x60\x01\x0E\xCF\x54\xC0\x25\xE0\x60\xA8\x40\xB8\xE4\x93\xA3"},
+ {0x40, 0xA0, 0x00B2, 0x0000, 0x0010, 0x0010,
+ "\xFA\xE4\x93\xA3\xF8\xE4\x93\xA3\xC8\xC5\x82\xC8\xCA\xC5\x83\xCA"},
+ {0x40, 0xA0, 0x00C2, 0x0000, 0x0010, 0x0010,
+ "\xF0\xA3\xC8\xC5\x82\xC8\xCA\xC5\x83\xCA\xDF\xE9\xDE\xE7\x80\xBE"},
+ {0x40, 0xA0, 0x09C9, 0x0000, 0x0001, 0x0001, "\x00"},
+ {0x40, 0xA0, 0x7F92, 0x0000, 0x0001, 0x0001, "\x01"},
+ {0x40, 0xA0, 0x7F92, 0x0000, 0x0001, 0x0001, "\x00"},
+ {0x00, 0x05, 0x0002, 0x0000, 0x0000, 0x0000, ""},
+ {0x00, 0x09, 0x0001, 0x0000, 0x0000, 0x0000, ""},
+ {0x00, 0x00, 0x0000, 0x0000, 0x0000, 0x0000, NULL}
+};
diff --git a/kernel/drv/oss_usb/oss_usb.c b/kernel/drv/oss_usb/oss_usb.c
new file mode 100644
index 0000000..2b5f119
--- /dev/null
+++ b/kernel/drv/oss_usb/oss_usb.c
@@ -0,0 +1,2505 @@
+/*
+ * Purpose: Top level USB audio class initialization and mixer functions
+ */
+
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This this source file is released under GPL v2 license (no other versions).
+ * See the COPYING file included in the main directory of this source
+ * distribution for the license terms and conditions.
+ *
+ */
+
+#define KBUILD_MODNAME oss_usb
+#include "oss_config.h"
+#include "ossusb.h"
+
+
+static const udi_usb_devinfo known_devices[] = {
+ {0x763, 0x2002, "M Audio USB AudioSport Duo",
+ {
+ {"OFF 24bit_hispeed 16bit_hispeed 24bit_lowspeed 16bit_lowspeed", 2,
+ 0x0014},
+ {"OFF 24bit_hispeed 16bit_hispeed 24bit_lowspeed 16bit_lowspeed", 2,
+ 0x0014}
+ }
+ },
+ {0x763, 0x2001, "M Audio USB AudioSport Quatro"},
+ {0x763, 0x2805, "M Audio Sonica"},
+ {0x763, 0x2007, "M Audio Sonica Theatre",
+ {
+ {"OFF 24bit_hispeed 16bit_hispeed 16bit_hispeed 24bit_lowspeed 24bit24bit 16bit 16bit OFF OFF", 3},
+ {"OFF 24bit_hispeed 16bit_hispeed 24bit 16bit_lowspeed", 2}
+ }
+ },
+ {0x763, 0x200d, "M Audio OmniStudio USB"},
+ {0x41e, 0x3000, "Creative Sound Blaster Extigy"},
+ {0x41e, 0x3010, "Creative Sound Blaster MP3+"},
+ {0x41e, 0x3020, "Creative Audigy2 NX USB",
+ {
+ {"OFF 16bit22kHz 16bit44kHz " /* 0-2 */
+ "24bit44kHz 16bit48kHz 24bit48kHz " /* 3-5 */
+ "16bit96kHz 24bit96kHz 16bit22kHz " /* 6-8 */
+ "16bit48kHz 24bit48kHz 16bit5.1ch22kHz " /* 9-11 */
+ "16bit5.1ch48kHz 24bit5.1ch48kHz 16bit7.1ch22kHz " /* 12-14 */
+ "16bit7.1ch48kHz" /* 15 */ , 4},
+
+ {"OFF 16bit32kHz 24bit32kHz " /* 0-2 */
+ "16bit44kHz 24bit44kHz 16bit48kHz " /* 3-5 */
+ "24bit48kHzin 24bit96kHz 24bit96kHz ", /* 6-8 */
+ 5}
+ }
+ },
+ {0x46d, 0x8b2, "Logitec Quickcam Pro 4000 (mic)"},
+ {0x46d, 0xa01, "Logitec USB Headset"},
+ {0x0471, 0x0311, "Philips ToUcam Pro (mic)"},
+ {0x672, 0x1041, "Labtec LCS1040 Speaker System"},
+ {0x6f8, 0xc000, "Hercules Gamesurround MUSE Pocket"},
+ {0x0d8c, 0x000c, "C-Media USB audio"},
+ {0x0d8c, 0x0102, "C-Media 2/4/6/8ch USB audio",
+ {
+ {"OFF 7.1 2.0 3.1 5.1 digital", 2},
+ {"OFF stereo"}
+ }
+ },
+ {0x0d8c, 0x0103, "C-Media USB audio"},
+ {-1, -1, "USB sound device"}
+};
+
+typedef struct
+{
+ unsigned int devid;
+ special_driver_t driver;
+}
+special_table_t;
+
+extern int usb_mixerstyle;
+
+#define MAX_DEVC 10
+static ossusb_devc *devc_list[MAX_DEVC];
+static int ndevs = 0;
+int usb_quiet = 0;
+
+
+void
+ossusb_dump_desc (unsigned char *desc, int cfg_len)
+{
+ int i;
+
+ for (i = 0; i < cfg_len; i++)
+ {
+ if (!(i % 16))
+ cmn_err (CE_CONT, "\n%04x: ", i);
+ cmn_err (CE_CONT, "%02x ", desc[i]);
+ }
+ cmn_err (CE_CONT, "\n");
+}
+
+unsigned int
+ossusb_get_int (unsigned char *p, int nbytes)
+{
+ unsigned int v = 0;
+ int i;
+
+ for (i = 0; i < nbytes; i++)
+ {
+ v |= (*p++) << (i * 8);
+ }
+
+ return v;
+}
+
+/*
+ * Mixer stuff
+ */
+
+static int
+decode_vol (usb_control_t * c, unsigned char *buf, int l)
+{
+ int value, range;
+
+ if (l == 1)
+ value = (signed char) buf[0];
+ else
+ value = (signed short) (buf[0] | (buf[1] << 8));
+
+ range = c->max - c->min;
+
+ value -= c->min;
+ value = (value * c->scale + range / 2) / range;
+
+ if (value < 0)
+ value = 0;
+ if (value > 255)
+ value = 255;
+ return value;
+}
+
+static void
+encode_vol (usb_control_t * c, unsigned char *buf, int l, int value)
+{
+ int range;
+
+ range = c->max - c->min;
+
+ value = (value * range + c->scale / 2) / c->scale;
+
+ value += c->min;
+
+ if (l == 1)
+ buf[0] = value;
+ else
+ {
+ buf[0] = value & 0xff;
+ buf[1] = (value >> 8) & 0xff;
+ }
+
+}
+
+static int
+read_feature_value (ossusb_devc * devc, usb_control_t * c, int rq, int *v)
+{
+ int len, value = 0, l;
+ int nch, ch;
+ unsigned char buf[2];
+
+/*
+ * Volume controls use two message bytes while the others use just one.
+ */
+ l = (c->index == 1) ? 2 : 1;
+
+ ch = c->min_ch + 1;
+ if (c->global)
+ ch = 0;
+
+ if (rq != GET_CUR)
+ {
+ buf[0] = buf[1] = 0;
+ len = udi_usb_rcv_control_msg (devc->mixer_usbdev, 0, // endpoint
+ rq, USB_RECIP_INTERFACE | USB_TYPE_CLASS, // rqtype
+ ((c->index + 1) << 8) | (ch), // value
+ (c->unit->num << 8), // index
+ buf, // buffer
+ l, // buflen
+ OSS_HZ * 2);
+ if (len < 0)
+ return 0;
+
+ value =
+ (len ==
+ 1) ? (signed char) buf[0] : (signed short) (buf[0] | (buf[1] << 8));
+ *v = value;
+ return 1;
+ }
+
+ nch = c->max_ch - c->min_ch + 1;
+
+ buf[0] = buf[1] = 0;
+ len = udi_usb_rcv_control_msg (devc->mixer_usbdev, 0, // endpoint
+ GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS, // rqtype
+ ((c->index + 1) << 8) | (ch), // value
+ (c->unit->num << 8), // index
+ buf, // buffer
+ l, // buflen
+ OSS_HZ * 2);
+ if (len < 0)
+ {
+ // cmn_err(CE_CONT, "feature (%s/%d) read error %d\n", c->unit->name, c->index, len);
+ *v = 0;
+ return 0;
+ }
+
+ value = decode_vol (c, buf, len);
+
+ if (!c->global)
+ if (nch == 2) /* Read the right channel */
+ {
+ len = udi_usb_rcv_control_msg (devc->mixer_usbdev, 0, // endpoint
+ GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS, // rqtype
+ ((c->index + 1) << 8) | (ch + 1), // value
+ (c->unit->num << 8), // index
+ buf, // buffer
+ l, // buflen
+ OSS_HZ * 2);
+ if (len < 0)
+ value |= (value & 0xff) << 8;
+ else
+ value |= (decode_vol (c, buf, len)) << 8;
+ }
+
+ *v = value;
+ return 1;
+}
+
+static int
+write_feature_value (ossusb_devc * devc, usb_control_t * c, int value)
+{
+ int len, l;
+ int left, right;
+ int ch, nch;
+ unsigned char buf[2];
+
+ ch = c->min_ch + 1;
+ if (c->global)
+ ch = 0;
+
+ left = value & 0xff;
+ right = (value >> 8) & 0xff;
+
+ if (left > (c->max - c->min))
+ left = c->max - c->min;
+ if (right > (c->max - c->min))
+ right = c->max - c->min;
+
+ l = (c->index == 1) ? 2 : 1;
+
+ nch = c->max_ch - c->min_ch + 1;
+ buf[0] = buf[1] = 0;
+ encode_vol (c, buf, l, left);
+
+ len = udi_usb_snd_control_msg (devc->mixer_usbdev, 0, // endpoint
+ SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS, // rqtype
+ ((c->index + 1) << 8) | ch, // value
+ (c->unit->num << 8), // index
+ buf, // buffer
+ l, // buflen
+ OSS_HZ * 2);
+ if (len < 0)
+ {
+ cmn_err (CE_CONT, "feature write error %d\n", len);
+ return len;
+ }
+
+ if (nch == 2) /* Write the right channel */
+ {
+ buf[0] = buf[1] = 0;
+ encode_vol (c, buf, l, right);
+
+ len = udi_usb_snd_control_msg (devc->mixer_usbdev, 0, // endpoint
+ SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS, // rqtype
+ ((c->index + 1) << 8) | (ch + 1), // value
+ (c->unit->num << 8), // index
+ buf, // buffer
+ l, // buflen
+ OSS_HZ * 2);
+ }
+ else
+ right = left;
+
+ value = left | (right << 8);
+ return value;
+}
+
+static int
+read_mixer_value (ossusb_devc * devc, usb_control_t * c, int rq, int *v)
+{
+ int len, value = 0;
+ unsigned char buf[2];
+
+ if (rq != GET_CUR)
+ {
+ len = udi_usb_rcv_control_msg (devc->mixer_usbdev, 0, // endpoint
+ rq, USB_RECIP_INTERFACE | USB_TYPE_CLASS, // rqtype
+ (c->index << 8) | c->min_ch, // value
+ (c->unit->num << 8) | 1, // index
+ buf, // buffer
+ 2, // buflen
+ OSS_HZ * 2);
+ if (len < 0)
+ return 0;
+
+ *v = (signed char) buf[1];
+ return 1;
+ }
+
+ len = udi_usb_rcv_control_msg (devc->mixer_usbdev, 0, // endpoint
+ rq, USB_RECIP_INTERFACE | USB_TYPE_CLASS, // rqtype
+ (c->index << 8) | c->min_ch, // value
+ (c->unit->num << 8) | 1, // index
+ buf, // buffer
+ 2, // buflen
+ OSS_HZ * 2);
+ if (len < 0)
+ {
+ cmn_err (CE_CONT, "mixer read error %d\n", len);
+ return 0;
+ }
+
+ value = buf[1] - c->min;
+
+ *v = value;
+ return 1;
+}
+
+static int
+write_mixer_value (ossusb_devc * devc, usb_control_t * c, int value)
+{
+ int len;
+ unsigned char buf[2];
+
+ value &= 0xff;
+
+ buf[0] = 0;
+ buf[1] = value + c->min;
+ len = udi_usb_snd_control_msg (devc->mixer_usbdev, 0, // endpoint
+ SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS, // rqtype
+ (c->index << 8) | c->min_ch, // value
+ (c->unit->num << 8) | 1, // index
+ buf, // buffer
+ 2, // buflen
+ OSS_HZ * 2);
+ if (len < 0)
+ {
+ cmn_err (CE_CONT, "mixer write error %d\n", len);
+ return 0;
+ }
+
+ return value;
+}
+
+static int
+read_unit (ossusb_devc * devc, usb_control_t * c, int rq, int *v)
+{
+ int err, value;
+ unsigned char buf[2];
+
+ *v = value = 0;
+
+ switch (c->unit->typ)
+ {
+ case TY_FEAT:
+ return read_feature_value (devc, c, rq, v);
+ break;
+
+ case TY_MIXER:
+ return read_mixer_value (devc, c, rq, v);
+ break;
+
+ case TY_SELECT:
+ err = udi_usb_rcv_control_msg (devc->mixer_usbdev, 0, // endpoint
+ rq, USB_RECIP_INTERFACE | USB_TYPE_CLASS, // rqtype
+ 0, // value
+ (c->unit->num << 8), // index
+ buf, // buffer
+ 1, // buflen
+ OSS_HZ * 2);
+ if (err < 0)
+ {
+ cmn_err (CE_CONT, "USB mixer unit read error %d\n", err);
+ return 0;
+ }
+ value = buf[0] - 1;
+ break;
+
+ } /* switch */
+
+ *v = value;
+ return 1;
+}
+
+static int
+read_current_value (ossusb_devc * devc, usb_control_t * c)
+{
+ int v;
+
+ if (!read_unit (devc, c, GET_CUR, &v))
+ return 0;
+
+ c->value = v;
+
+ return 1;
+}
+
+static int
+write_current_value (ossusb_devc * devc, usb_control_t * c, int value)
+{
+ unsigned char buf[2];
+ int err;
+
+ switch (c->unit->typ)
+ {
+ case TY_SELECT:
+ if (value > c->max)
+ value = c->max;
+ buf[0] = value + 1;
+ err = udi_usb_snd_control_msg (devc->mixer_usbdev, 0, // endpoint
+ SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS, // rqtype
+ 0, // value
+ (c->unit->num << 8), // index
+ buf, // buffer
+ 1, // buflen
+ OSS_HZ * 2);
+ if (err < 0)
+ {
+ cmn_err (CE_CONT, "Selector write error %d\n", err);
+ return 0;
+ }
+ break;
+
+ case TY_FEAT:
+ value = write_feature_value (devc, c, value);
+ break;
+
+ case TY_MIXER:
+ value = write_mixer_value (devc, c, value);
+ break;
+
+ default:
+ return OSS_EIO;
+ }
+
+ return value;
+}
+
+static int
+new_ctl (ossusb_devc * devc, usb_audio_unit_t * un, int index, int exttype,
+ int chmask)
+{
+ int n, min, max;
+ usb_control_t *c;
+ int i, min_ch = 0, max_ch = 0;
+
+ if (devc->ncontrols >= MAX_CONTROLS)
+ {
+ cmn_err (CE_CONT, "Too many mixer features.\n");
+ return OSS_EIO;
+ }
+
+ n = devc->ncontrols++;
+
+ c = &devc->controls[n];
+
+ if (chmask)
+ {
+ min_ch = -1;
+
+ for (i = 0; i < 32; i++)
+ if (chmask & (1 << i))
+ {
+ if (min_ch == -1)
+ min_ch = i;
+ max_ch = i;
+ }
+ }
+
+ c->unit = un;
+ c->index = index;
+ c->exttype = exttype;
+ c->min_ch = min_ch;
+ c->global = (chmask == 0) ? 1 : 0;
+ c->max_ch = max_ch;
+ c->min = 0;
+ c->max = 255;
+ c->chmask = chmask;
+ c->value = 0;
+
+ if (index != 1) /* Not volume control */
+ {
+ c->max = 1;
+ }
+ else
+ {
+ if (read_unit (devc, c, GET_MAX, &max))
+ {
+ c->max = max;
+ if (read_unit (devc, c, GET_MIN, &min))
+ {
+ c->min = min;
+ }
+ }
+ }
+
+ if (c->max <= c->min)
+ {
+/*
+ * The device reported bad limits. Try to fix the situation.
+ */
+ if (c->min < 0)
+ c->max = 0;
+ else
+ c->min = 0;
+ if (c->max <= c->min)
+ {
+ c->min = 0;
+ c->max = 255;
+ }
+ }
+
+ c->scale = 255;
+ if (c->max - c->min < 255)
+ c->scale = c->max - c->min;
+
+
+ read_current_value (devc, c);
+
+ if (usb_trace)
+ {
+ cmn_err (CE_CONT, "Ctl %2d: %d/%s %d ", n, c->unit->num, c->unit->name,
+ c->index);
+ cmn_err (CE_CONT, "Min %d, max %d, scale %d\n", c->min, c->max,
+ c->scale);
+ cmn_err (CE_CONT, "ch=%x ", c->chmask);
+ cmn_err (CE_CONT, "Value %04x, (%d - %d, %d)\n", c->value, c->min,
+ c->max, c->scale);
+ }
+
+ return n;
+}
+
+static int
+mixer_func (int dev, int ctrl, unsigned int cmd, int value)
+{
+ ossusb_devc *devc = mixer_devs[dev]->devc;
+ usb_control_t *c;
+
+ if (devc->disabled)
+ return OSS_EPIPE;
+
+ if (ctrl < 0 || ctrl >= devc->ncontrols)
+ return OSS_EIO;
+
+ c = &devc->controls[ctrl];
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ return c->value;
+ }
+
+ if (cmd != SNDCTL_MIX_WRITE)
+ return OSS_EINVAL;
+
+ value = c->value = write_current_value (devc, c, value);
+
+ return value;
+}
+
+static char *
+get_feature_name (int n)
+{
+ switch (n)
+ {
+ case 0:
+ return "mute";
+ case 1:
+ return "vol";
+ case 2:
+ return "bass";
+ case 3:
+ return "mid";
+ case 4:
+ return "treble";
+ case 5:
+ return "eq";
+ case 6:
+ return "agc";
+ case 7:
+ return "delay";
+ case 8:
+ return "boost";
+ case 9:
+ return "loud";
+ case 10:
+ return "igain";
+ case 11:
+ return "igainpad";
+ case 12:
+ return "phaseinv";
+ case 13:
+ return "underflow";
+ case 14:
+ return "overflow";
+ default:
+ return "misc";
+ }
+}
+
+static int
+get_feature_type (int n)
+{
+ switch (n)
+ {
+ case 0:
+ return MIXT_ONOFF;
+ case 1:
+ return MIXT_SLIDER;
+ case 2:
+ return MIXT_SLIDER;
+ case 3:
+ return MIXT_SLIDER;
+ case 4:
+ return MIXT_SLIDER;
+ case 5:
+ return MIXT_SLIDER;
+ case 6:
+ return MIXT_ONOFF;
+ case 7:
+ return MIXT_SLIDER;
+ case 8:
+ return MIXT_ONOFF;
+ case 9:
+ return MIXT_ONOFF;
+ default:
+ return MIXT_ONOFF;
+ }
+}
+
+struct chmasks
+{
+ unsigned int mask;
+ char *name;
+ char type;
+ char channels;
+};
+
+static const struct chmasks chmasks[] = {
+ {0x00000003, "front", MIXT_STEREOSLIDER, 2},
+ {0x00000001, "L", MIXT_MONOSLIDER, 1},
+ {0x00000002, "R", MIXT_MONOSLIDER, 1},
+ {0x00000030, "surr", MIXT_STEREOSLIDER, 2},
+ {0x00000010, "LS", MIXT_MONOSLIDER, 1},
+ {0x00000020, "RS", MIXT_MONOSLIDER, 1},
+ {0x0000000c, "C/L", MIXT_STEREOSLIDER, 2},
+ {0x00000004, "C", MIXT_MONOSLIDER, 1},
+ {0x00000008, "LFE", MIXT_MONOSLIDER, 1},
+ {0x000000c0, "center", MIXT_STEREOSLIDER, 2},
+ {0x00000040, "LC", MIXT_MONOSLIDER, 1},
+ {0x00000080, "RC", MIXT_MONOSLIDER, 1},
+ {0x00000100, "surr", MIXT_STEREOSLIDER, 2},
+ {0x00000600, "side", MIXT_STEREOSLIDER, 2},
+ {0x00000200, "SL", MIXT_MONOSLIDER, 1},
+ {0x00000400, "SR", MIXT_MONOSLIDER, 1},
+ {0x00000800, "TC", MIXT_MONOSLIDER, 1},
+ {0x00001000, "TFL", MIXT_MONOSLIDER, 1},
+ {0x00002000, "TFC", MIXT_MONOSLIDER, 1},
+ {0x00004000, "TFR", MIXT_MONOSLIDER, 1},
+ {0x00008000, "TBL", MIXT_MONOSLIDER, 1},
+ {0x00010000, "TBC", MIXT_MONOSLIDER, 1},
+ {0x00020000, "TBR", MIXT_MONOSLIDER, 1},
+ {0x00040000, "TFLC", MIXT_MONOSLIDER, 1},
+ {0x00080000, "TFRC", MIXT_MONOSLIDER, 1},
+ {0x00100000, "LLFE", MIXT_MONOSLIDER, 1},
+ {0x00200000, "RLFE", MIXT_MONOSLIDER, 1},
+ {0x00400000, "TSL", MIXT_MONOSLIDER, 1},
+ {0x00800000, "TSR", MIXT_MONOSLIDER, 1},
+ {0x01000000, "BC", MIXT_MONOSLIDER, 1},
+ {0x02000000, "BLC", MIXT_MONOSLIDER, 1},
+ {0x04000000, "BRC", MIXT_MONOSLIDER, 1},
+ {0x80000000, "RD", MIXT_MONOSLIDER, 1},
+ {0, NULL}
+};
+
+static int
+count_source_controls (ossusb_devc * devc, int unit)
+{
+ int n = 0, nn, i;
+ usb_audio_unit_t *un;
+ unsigned char *d;
+
+ if (unit <= 0 || unit >= devc->nunits)
+ return 0;
+
+ un = &devc->units[unit];
+ d = un->desc;
+
+ if (un == NULL)
+ return 0;
+
+ switch (un->typ)
+ {
+ case TY_MIXER:
+ case TY_SELECT:
+ nn = d[4];
+ d += 5;
+ for (i = 0; i < nn; i++)
+ {
+ n += count_source_controls (devc, *d);
+ d++;
+ }
+ break;
+
+ case TY_PROC:
+ case TY_EXT:
+ nn = d[6];
+ d += 7;
+ for (i = 0; i < nn; i++)
+ {
+ n += count_source_controls (devc, *d);
+ d++;
+ }
+ break;
+
+ default:
+ if (un->source <= 0 && un->source < devc->nunits)
+ {
+ n = count_source_controls (devc, un->source);
+ }
+ }
+
+ if (!un->ctl_avail)
+ return n;
+
+ return n + un->control_count;
+}
+
+static int
+count_target_controls (ossusb_devc * devc, int unit)
+{
+ int n = 0;
+ usb_audio_unit_t *un;
+
+ if (unit <= 0 || unit >= devc->nunits)
+ return 0;
+
+ un = &devc->units[unit];
+
+ if (un == NULL)
+ return 0;
+
+ if (un->typ == TY_SELECT || un->typ == TY_MIXER)
+ {
+ n = 0;
+ }
+ else if (un->target <= 0 && un->target < devc->nunits)
+ {
+ n = count_target_controls (devc, un->target);
+ }
+
+ if (!un->ctl_avail)
+ return n;
+
+ return n + un->control_count;
+}
+
+static int
+follow_source_links (ossusb_devc * devc, usb_audio_unit_t * un)
+{
+ while (un->source > 0 && un->source < devc->nunits)
+ un = &devc->units[un->source];
+
+ return un->num;
+}
+
+static int
+follow_target_links (ossusb_devc * devc, usb_audio_unit_t * un)
+{
+ while (un->target > 0 && un->target < devc->nunits)
+ un = &devc->units[un->target];
+
+ return un->num;
+}
+
+static void
+add_controls_for_mixer (ossusb_devc * devc, usb_audio_unit_t * un, int group)
+{
+ int i, n;
+ unsigned char *d = un->desc;
+
+ if (!un->ctl_avail)
+ return;
+
+ n = d[4];
+ d += 5;
+
+ for (i = 0; i < n; i++)
+ if (*d > 0 && *d < devc->nunits)
+ {
+ int ref = follow_source_links (devc, &devc->units[*d]);
+
+ {
+
+ int ctl = new_ctl (devc, un, i, MIXT_MONOSLIDER, un->chmask);
+ UDB (cmn_err
+ (CE_CONT, "Add mixer control %d/%s\n", un->num,
+ devc->units[ref].name));
+ if (mixer_ext_create_control (devc->mixer_dev, group, ctl,
+ mixer_func, MIXT_MONOSLIDER,
+ devc->units[ref].name, 255,
+ MIXF_READABLE | MIXF_WRITEABLE) < 0)
+ return;
+ }
+ d++;
+ }
+
+ un->ctl_avail = 0;
+}
+
+/*ARGSUSED*/
+static void
+add_controls_for_proc (ossusb_devc * devc, usb_audio_unit_t * un, int group)
+{
+ int i, n;
+ unsigned char *d = un->desc;
+
+ if (!un->ctl_avail)
+ return;
+
+ n = d[6];
+ d += 7;
+
+ for (i = 0; i < n; i++)
+ if (*d > 0 && *d < devc->nunits)
+ {
+ d++;
+ }
+
+ un->ctl_avail = 0;
+}
+
+static void
+add_controls_for_selector (ossusb_devc * devc, usb_audio_unit_t * un,
+ int group)
+{
+ static oss_mixer_enuminfo ent;
+ char *s;
+ int i, n, err;
+ unsigned char *d = un->desc;
+ int ctl = new_ctl (devc, un, 0, MIXT_ENUM, 0);
+
+ if (!un->ctl_avail)
+ return;
+
+ n = d[4];
+ d += 5;
+ UDB (cmn_err (CE_CONT, "Add selector control %d/%s\n", un->num, un->name));
+ if ((err = mixer_ext_create_control (devc->mixer_dev, group,
+ ctl, mixer_func,
+ MIXT_ENUM,
+ un->name, n,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return;
+
+ memset (&ent, 0, sizeof (ent));
+
+ s = ent.strings;
+
+ for (i = 0; i < n; i++)
+ if (*d > 0 && *d < devc->nunits)
+ {
+ int ref = follow_source_links (devc, &devc->units[*d]);
+ d++;
+
+ if (s > ent.strings)
+ *s++ = '|';
+ strcpy (s, devc->units[ref].name);
+ s += strlen (s);
+ }
+
+ s = ent.strings;
+ for (i = 0; i < strlen (s); i++)
+ {
+ if (s[i] == ' ')
+ s[i] = '_';
+ if (s[i] == '|')
+ s[i] = ' ';
+ }
+
+ ent.dev = devc->mixer_dev;
+ ent.ctrl = err;
+ ent.nvalues = 0;
+
+ mixer_ext_set_enum (&ent);
+
+ un->ctl_avail = 0;
+}
+
+/*ARGSUSED*/
+static void
+add_multich_volumes (ossusb_devc * devc, usb_audio_unit_t * un, int group,
+ int fea, int mask, unsigned int *feature_mask)
+{
+ int i;
+
+ for (i = 0; mask != 0 && chmasks[i].mask != 0; i++)
+ {
+ int m = chmasks[i].mask;
+ int ctl;
+ usb_control_t *c;
+
+ if (!(mask & m))
+ continue;
+
+ ctl = new_ctl (devc, un, fea, chmasks[i].type, chmasks[i].mask);
+ c = &devc->controls[ctl];
+
+ UDB (cmn_err
+ (CE_CONT, "Add multich feature control %d/%s\n", un->num,
+ chmasks[i].name));
+ if (mixer_ext_create_control (devc->mixer_dev, group, ctl, mixer_func,
+ chmasks[i].type, chmasks[i].name,
+ c->scale,
+ MIXF_READABLE | MIXF_WRITEABLE) < 0)
+ return;
+
+ mask &= ~m;
+ }
+
+ if (mask)
+ cmn_err (CE_CONT, "Warning! Unsupported channels (%02x)\n", mask);
+}
+
+static void
+translate_feature_mask_usb2 (ossusb_devc *devc, usb_audio_unit_t * un, unsigned int *feature_mask)
+{
+ int i, n, c;
+ unsigned char *d = un->desc;
+
+ n = 4;
+ d = d + 5 + n; // Skip the global mask
+
+/*
+ * USB 2.0 uses 2 bits for each control
+ * 01b means that the control is read only and 11b means it's RW
+ */
+ for (c = 0; c < un->channels; c++)
+ {
+ unsigned int mask;
+ unsigned char *p = d + c * n;
+
+ mask = p[3] |
+ (p[2] << 8) |
+ (p[1] << 16) |
+ (p[0] << 24);
+
+ for (i = 0; i < n * 4; i++)
+ if ((mask & (3 << 2*i)) && (un->ctl_avail & (1 << i)))
+ {
+ feature_mask[i] |= 1 << c;
+ }
+ }
+}
+
+static void
+translate_feature_mask (ossusb_devc *devc, usb_audio_unit_t * un, unsigned int *feature_mask)
+{
+ int i, n, c;
+ unsigned char *d = un->desc;
+
+ if (devc->usb_version > 1)
+ {
+ translate_feature_mask_usb2(devc, un, feature_mask);
+ return;
+ }
+
+ n = d[5];
+ if (n < 1 || n > 2)
+ {
+ cmn_err (CE_CONT, "Bad feature mask size %d\n", n);
+ return;
+ }
+
+ d = d + 6 + n; // Skip the global mask
+
+ for (c = 0; c < un->channels; c++)
+ {
+ int mask = d[c * n];
+ if (n > 1)
+ mask |= d[c * n + 1];
+
+ for (i = 0; i < n * 8; i++)
+ if ((mask & (1 << i)) && (un->ctl_avail & (1 << i)))
+ {
+ feature_mask[i] |= 1 << c;
+ }
+ }
+}
+
+static void
+add_controls_for_feature (ossusb_devc * devc, usb_audio_unit_t * un,
+ int group)
+{
+ int i;
+ unsigned int feature_mask[16], global_mask;
+
+ if (!un->ctl_avail)
+ return;
+
+// Handle the global controls first
+
+ global_mask = un->desc[6];
+ if (un->desc[5] > 0)
+ global_mask |= un->desc[7] << 8;
+
+ for (i = 0; i < 11; i++)
+ if (un->ctl_avail & (1 << i) && (global_mask & (1 << i)))
+ {
+ char *name = get_feature_name (i);
+ int type = get_feature_type (i);
+ int max;
+ char tmp[16];
+ int ctl;
+
+ ctl = new_ctl (devc, un, i, type, 0);
+ strcpy (tmp, name);
+ if (type == MIXT_SLIDER)
+ max = devc->controls[ctl].max - devc->controls[ctl].min;
+ else
+ max = 1;
+
+ if (max > 255)
+ max = 255;
+
+ UDB (cmn_err
+ (CE_CONT, "Add (global) feature control %d:%s, max=%d\n",
+ un->num, name, max));
+ if (mixer_ext_create_control (devc->mixer_dev, group, ctl,
+ mixer_func, type, tmp, max,
+ MIXF_READABLE | MIXF_WRITEABLE) < 0)
+ return;
+ //un->ctl_avail &= ~(1 << i);
+ }
+
+// Handle the channelized controls
+
+ if (un->ctl_avail == 0) /* Nothing left */
+ return;
+
+ // Translate the channel/feature availability matrix
+
+ memset (feature_mask, 0, sizeof (feature_mask));
+ translate_feature_mask (devc, un, feature_mask);
+
+ for (i = 0; i < 16; i++)
+ if (feature_mask[i])
+ {
+ char *name = get_feature_name (i);
+ int type = get_feature_type (i);
+ int max, instances = 0;
+
+ int nc = 0, j;
+
+ for (j = 0; j < 16; j++)
+ if (feature_mask[i] & (1 << j))
+ nc = j + 1;
+
+ if (type == MIXT_SLIDER)
+ {
+ if (nc == 1)
+ {
+ type = MIXT_MONOSLIDER;
+ instances = 1;
+ }
+ else if (nc == 2)
+ {
+ type = MIXT_STEREOSLIDER;
+ instances = 1;
+ }
+ else
+ {
+ type = MIXT_MONOSLIDER;
+ if (i == 1) /* "volume" */
+ instances = nc;
+ else
+ {
+ instances = 0;
+ type = MIXT_MONOSLIDER;
+ }
+ }
+ max = 255;
+ }
+ else
+ max = 2;
+
+ if (instances && (instances > 1 || feature_mask[i] > 0x0003))
+ {
+ int g;
+ char tmp[16];
+ strcpy (tmp, name);
+ UDB (cmn_err (CE_CONT, "Add feature group %s\n", tmp));
+ if ((g =
+ mixer_ext_create_group (devc->mixer_dev, group, tmp)) < 0)
+ return;
+
+ add_multich_volumes (devc, un, g, i, feature_mask[i],
+ feature_mask);
+ }
+ else
+ {
+ char tmp[16];
+ int ctl = new_ctl (devc, un, i, type, un->chmask);
+ strcpy (tmp, name);
+ max = devc->controls[ctl].max - devc->controls[ctl].min;
+ if (max > 255)
+ max = 255;
+
+ UDB (cmn_err
+ (CE_CONT, "Add feature control %d:%s\n", un->num, name));
+ if (mixer_ext_create_control (devc->mixer_dev, group, ctl,
+ mixer_func, type, tmp, max,
+ MIXF_READABLE | MIXF_WRITEABLE) < 0)
+ return;
+ }
+ }
+
+ un->ctl_avail = 0; // All done (hope so)
+}
+
+static void
+traverse_source_controls (ossusb_devc * devc, usb_audio_unit_t * un,
+ int group)
+{
+ unsigned char *d;
+
+ d = un->desc;
+
+ if (un->typ == TY_MIXER)
+ {
+ add_controls_for_mixer (devc, un, group);
+ return;
+ }
+
+ if (un->typ == TY_PROC)
+ {
+ add_controls_for_proc (devc, un, group);
+
+ if (d[6] > 1) /* More than 1 sources */
+ return;
+ }
+
+ if (un->typ == TY_SELECT)
+ {
+ add_controls_for_selector (devc, un, group);
+ return;
+ }
+
+ if (un->source > 0 && un->source < devc->nunits)
+ {
+ traverse_source_controls (devc, &devc->units[un->source], group);
+ }
+
+ if (un->typ == TY_FEAT)
+ {
+ add_controls_for_feature (devc, un, group);
+ }
+}
+
+static void
+traverse_target_controls (ossusb_devc * devc, usb_audio_unit_t * un,
+ int group)
+{
+ unsigned char *d;
+
+
+ d = un->desc;
+
+ if (un->typ == TY_SELECT)
+ {
+ add_controls_for_selector (devc, un, group);
+ }
+
+ if (un->typ == TY_PROC || un->typ == TY_EXT)
+ if (d[6] > 1) // More than 1 input pins
+ return;
+
+ if (un->typ == TY_MIXER)
+ {
+#if 1
+ add_controls_for_mixer (devc, un, group);
+#endif
+ }
+
+ if (un->target > 0 && un->target < devc->nunits)
+ traverse_target_controls (devc, &devc->units[un->target], group);
+
+ if (un->typ == TY_FEAT)
+ {
+ add_controls_for_feature (devc, un, group);
+ }
+}
+
+void
+ossusb_create_altset_control (int dev, int portc_num, int nalt, char *name)
+{
+ int ctl;
+ ossusb_devc *devc = mixer_devs[dev]->devc;
+ char *as = NULL;
+ int default_altsetting;
+ unsigned int altsetting_mask;
+
+ if (nalt < 3) /* Only one alternative setting (plus "OFF") available */
+ return;
+ if ((as =
+ udi_usbdev_get_altsetting_labels (devc->mixer_usbdev, portc_num,
+ &default_altsetting,
+ &altsetting_mask)) != NULL)
+ {
+ if (altsetting_mask != 0)
+ {
+ /*
+ * Check if more than one of them are enabled.
+ */
+
+ int i, n = 0;
+
+ for (i = 1; i < nalt; i++)
+ if (altsetting_mask & (1 << i))
+ n++;
+
+ if (n < 2) /* No */
+ return;
+ }
+ }
+
+ if ((ctl = mixer_ext_create_control (dev, 0,
+ portc_num, ossusb_change_altsetting,
+ MIXT_ENUM,
+ name, nalt,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return;
+
+ if (as != NULL) /* Use custom labels */
+ {
+ mixer_ext_set_strings (dev, ctl, as, 0);
+ if (altsetting_mask != 0)
+ {
+ oss_mixext *ext;
+ int i;
+
+ ext = mixer_find_ext (dev, ctl);
+
+ memset (ext->enum_present, 0, sizeof (ext->enum_present));
+ for (i = 0; i < nalt; i++)
+ if (altsetting_mask & (1 << i))
+ ext->enum_present[i / 8] |= (1 << (i % 8));
+ }
+
+ if (default_altsetting > 0)
+ ossusb_change_altsetting (dev, portc_num, SNDCTL_MIX_WRITE,
+ default_altsetting);
+ }
+ else
+ mixer_ext_set_strings (dev, ctl,
+ "OFF 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19",
+ 0);
+
+}
+
+static int
+usb_mix_init (int dev)
+{
+ ossusb_devc *devc;
+ int i, group;
+
+ devc = mixer_devs[dev]->devc;
+
+ for (i = 0; i < devc->nunits; i++)
+ {
+ usb_audio_unit_t *un = &devc->units[i];
+
+ if (un->typ == TY_OUTPUT)
+ {
+ if (count_source_controls (devc, un->source) == 0)
+ {
+ continue;
+ }
+
+ if ((group = mixer_ext_create_group (dev, 0, un->name)) < 0)
+ return group;
+
+ traverse_source_controls (devc, un, group);
+ continue;
+ }
+ }
+
+ for (i = 0; i < devc->nunits; i++)
+ {
+ usb_audio_unit_t *un = &devc->units[i];
+
+ if (un->typ == TY_INPUT)
+ {
+ if (count_target_controls (devc, un->target) == 0)
+ {
+ continue;
+ }
+
+ if ((group = mixer_ext_create_group (dev, 0, un->name)) < 0)
+ return group;
+
+ traverse_target_controls (devc, un, group);
+ un->ctl_avail = 0;
+ continue;
+ }
+ }
+
+ return 0;
+}
+
+static char *
+check_feature (usb_audio_unit_t * un, unsigned char *mask, int n)
+{
+ if (mask[n / 8] & (1 << (n % 8)))
+ {
+ un->control_count++;
+
+ return get_feature_name (n);
+ }
+
+ return NULL;
+}
+
+/*ARGSUSED*/
+static int
+usb_mixer_ioctl (int dev, int audiodev, unsigned int cmd, ioctl_arg arg)
+{
+ ossusb_devc *devc = mixer_devs[dev]->hw_devc;
+
+ if (devc->disabled)
+ return OSS_EPIPE;
+
+ switch (cmd)
+ {
+ case SOUND_MIXER_READ_DEVMASK:
+ return *arg = devc->devmask | devc->recmask;
+ case SOUND_MIXER_READ_RECMASK:
+ return *arg = devc->recmask;
+ case SOUND_MIXER_READ_RECSRC:
+ return *arg = devc->recsrc;
+ case SOUND_MIXER_READ_STEREODEVS:
+ return *arg = devc->stereodevs;
+ }
+
+ return *arg = 0;
+}
+
+static mixer_driver_t usb_mixer_driver = {
+ usb_mixer_ioctl
+};
+
+static int
+init_mixer (ossusb_devc * devc)
+{
+ if ((devc->mixer_dev = oss_install_mixer (OSS_MIXER_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ devc->dev_name,
+ &usb_mixer_driver,
+ sizeof (mixer_driver_t),
+ devc)) >= 0)
+ {
+ char mxname[20];
+
+ sprintf (mxname, "USB_%d", ndevs);
+
+ devc->levels = load_mixer_volumes (mxname, NULL, 1);
+ mixer_devs[devc->mixer_dev]->hw_devc = devc;
+ mixer_ext_set_init_fn (devc->mixer_dev, usb_mix_init, MAX_CONTROLS);
+ }
+
+ return 1;
+}
+
+static usb_audio_unit_t *
+setup_unit (ossusb_devc * devc, int unit, char *name, unsigned char *desc,
+ int desclen, int typ)
+{
+ usb_audio_unit_t *un;
+
+ if (unit < 0 || unit >= MAX_UNIT)
+ {
+ cmn_err (CE_WARN, "Bad unit number %d\n", unit);
+ return NULL;
+ }
+
+ if (typ >= sizeof (devc->unit_counters))
+ {
+ cmn_err (CE_WARN, "Bad unit type %d\n", typ);
+ return NULL;
+ }
+
+ devc->unit_counters[typ]++;
+
+ if (unit >= devc->nunits)
+ devc->nunits = unit + 1;
+
+ un = &devc->units[unit];
+
+ un->num = unit;
+ un->typ = typ;
+ un->desc = desc;
+ un->desclen = desclen;
+ un->mixnum = -1;
+ un->channels = 2;
+ un->chmask = 0x03;
+ strcpy (un->name, name);
+
+ return un;
+}
+
+static char *
+get_terminal_id (int type, char *def, int typ, int *mn)
+{
+ int dummy, *mixnum;
+
+ if (mn != NULL)
+ mixnum = mn;
+ else
+ mixnum = &dummy;
+ switch (type)
+ {
+ case 0x0101:
+ if (typ == TY_INPUT)
+ {
+ *mixnum = SOUND_MIXER_PCM;
+ return "play";
+ }
+ if (typ == TY_OUTPUT)
+ {
+ *mixnum = SOUND_MIXER_RECLEV;
+ return "rec";
+ }
+ break;
+ case 0x0301:
+ *mixnum = SOUND_MIXER_VOLUME;
+ return "output";
+ case 0x0302:
+ *mixnum = SOUND_MIXER_VOLUME;
+ return "headph";
+ case 0x0307:
+ return "LFE";
+
+ case 0x0401:
+ return "handset";
+ case 0x0402:
+ return "headset";
+
+ case 0x0403:
+ case 0x0404:
+ case 0x0405:
+ case 0x0500:
+ case 0x0501:
+ case 0x0502:
+ case 0x0504:
+ return "phone";
+ break;
+
+ case 0x0600:
+ *mixnum = SOUND_MIXER_LINE1;
+ return "aux";
+ case 0x0601:
+ *mixnum = SOUND_MIXER_LINE2;
+ return "aux";
+ case 0x0602:
+ return "digital";
+ case 0x0603:
+ *mixnum = SOUND_MIXER_LINE;
+ return "line";
+ case 0x0604:
+ *mixnum = SOUND_MIXER_SPEAKER;
+ return "pc_in";
+ case 0x0605:
+ *mixnum = SOUND_MIXER_DIGITAL1;
+ if (typ == TY_INPUT)
+ return "spdin";
+ else
+ return "spdout";
+ case 0x0606:
+ return "da_stream";
+ case 0x0607:
+ return "DV_audio";
+
+ case 0x0701:
+ return "noise";
+ case 0x0702:
+ return "eq_noise";
+ case 0x0703:
+ *mixnum = SOUND_MIXER_CD;
+ return "cd";
+ case 0x0704:
+ return "dat";
+ case 0x0706:
+ return "md";
+ case 0x0707:
+ return "tape";
+ case 0x0708:
+ return "phono";
+ case 0x0709:
+ *mixnum = SOUND_MIXER_VIDEO;
+ return "vcr";
+ case 0x070b:
+ return "dvd";
+ case 0x070c:
+ return "tv";
+ case 0x070d:
+ return "sat";
+ case 0x070e:
+ return "cable";
+ case 0x0710:
+ *mixnum = SOUND_MIXER_RADIO;
+ return "radio";
+ case 0x0711:
+ *mixnum = SOUND_MIXER_RADIO;
+ return "xmitter";
+ case 0x0712:
+ return "mtrack";
+ case 0x0713:
+ *mixnum = SOUND_MIXER_SYNTH;
+ return "synth";
+ }
+
+ if (type < 0x201) // Unknown type
+ return def;
+
+ if (type < 0x300)
+ {
+ *mixnum = SOUND_MIXER_MIC;
+ return "mic";
+ }
+
+ return def;
+}
+
+static void
+setup_legacy_mixer (ossusb_devc * devc)
+{
+ int x;
+
+// Set up the recording selector
+
+ for (x = 1; x < devc->nunits; x++)
+ {
+ usb_audio_unit_t *un = &devc->units[x];
+ int i, n;
+ unsigned char *d = un->desc;
+
+ if (un->typ != TY_SELECT || strcmp (un->name, "rec.src") != 0)
+ continue;
+
+ if (!un->ctl_avail)
+ continue;
+
+ devc->rec_unit = x;
+ un->ctl_avail = 0;
+
+ devc->num_recdevs = n = d[4];
+ d += 5;
+ for (i = 0; i < n; i++)
+ {
+ int ref = follow_source_links (devc, &devc->units[*d]);
+ int mask;
+
+ d++;
+
+ if (ref < 1 || ref >= devc->nunits || devc->units[ref].mixnum == -1)
+ continue;
+
+ mask = (1 << devc->units[ref].mixnum);
+ if (devc->recmask & mask) // Duplicate
+ continue;
+ UDB (cmn_err
+ (CE_CONT, "Recsrc %d, num=%d, mask %x\n", i, ref, mask));
+
+ devc->recdevs[i] = mask;
+
+ devc->recmask |= mask;
+ if (devc->recsrc == 0)
+ devc->recsrc = mask;
+ }
+
+ break;
+ }
+
+// Set up the legacy mixer controls
+
+ for (x = 1; x < devc->nunits; x++)
+ {
+ usb_audio_unit_t *un = &devc->units[x];
+ int mixnum;
+ unsigned char *d = un->desc;
+
+ if (!(un->ctl_avail & 0x02))
+ continue;
+
+ if (un->typ == TY_FEAT && d[6] & 0x02) // Volume control
+ {
+ int t;
+ mixnum = un->mixnum;
+
+ if (mixnum == -1)
+ {
+ t = follow_target_links (devc, un);
+ if (t && devc->units[t].mixnum != -1)
+ mixnum = devc->units[t].mixnum;
+ else
+ {
+ t = follow_source_links (devc, un);
+ if (t && devc->units[t].mixnum != -1)
+ mixnum = devc->units[t].mixnum;
+ }
+ }
+
+ if (mixnum == -1 || un->channels > 2)
+ continue;
+ UDB (cmn_err (CE_CONT, "Unit %d is volume %d\n", x, mixnum));
+ un->ctl_avail &= ~0x02; // Reserve the volume slider
+
+ devc->devmask |= (1 << mixnum);
+ if (un->channels == 2)
+ devc->stereodevs |= (1 << mixnum);
+
+ continue;
+ }
+ }
+
+}
+
+static char *
+get_processor_type (int t)
+{
+ switch (t)
+ {
+ case 0x01:
+ return "upmix";
+ case 0x02:
+ return "prologic";
+ case 0x03:
+ return "3D";
+ case 0x04:
+ return "reverb";
+ case 0x05:
+ return "chorus";
+ case 0x06:
+ return "compress";
+ default:
+ return "proc";
+ }
+}
+
+static void
+parse_processing_unit (ossusb_devc * devc, unsigned char *d, int l)
+{
+ usb_audio_unit_t *un;
+ char *name;
+
+ name = get_processor_type (d[4]);
+
+ if ((un = setup_unit (devc, d[3], name, d, l, TY_PROC)) == NULL)
+ return;
+ un->subtyp = d[4];
+ un->ctl_avail = 1;
+
+ if (un->subtyp == 1) // Upmix/downmix unit
+ {
+ un->channels = d[8];
+ un->chmask = ossusb_get_int (&d[9], 2);
+ }
+}
+
+static int
+get_feature_mask (unsigned char *d, int channels)
+{
+ int i, n, mask = 0, v;
+ n = d[5];
+
+ for (i = 0; i <= channels; i++)
+ {
+ v = d[6 + i * n];
+ if (n > 1)
+ v |= d[6 + i * n + 1] << 8;
+
+ mask |= v;
+ }
+
+ return mask;
+}
+
+#if 1
+static void
+mixer_dump (ossusb_devc * devc)
+{
+ int i, j, c;
+ usb_audio_unit_t *un;
+
+ for (i = 1; i < devc->nunits; i++)
+ {
+ un = &devc->units[i];
+
+ if (un->typ == TY_FEAT)
+ {
+ cmn_err (CE_CONT, "Unit %d\n", un->num);
+
+ for (j = 0; j < 8; j++)
+ {
+ for (c = 0; c < 7; c++)
+ {
+ unsigned char buf[2];
+ int len;
+
+ buf[0] = buf[1] = 0;
+ len = udi_usb_rcv_control_msg (devc->mixer_usbdev, 0, // endpoint
+ GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS, // rqtype
+ ((j) << 8) | (c), // value
+ (un->num << 8), // index
+ buf, // buffer
+ 2, // buflen
+ OSS_HZ * 2);
+
+ if (len < 0)
+ continue;
+ cmn_err (CE_CONT, " Feature %d/%d, ch %d: ", un->num, j,
+ c);
+ cmn_err (CE_CONT, "%02x%02x ", buf[0], buf[1]);
+
+ if (len == 1)
+ cmn_err (CE_CONT, "(%d) ", (signed char) buf[0]);
+ else
+ cmn_err (CE_CONT, "(%d) ",
+ (signed short) (buf[0] | (buf[1] << 8)));
+
+ buf[0] = buf[1] = 0;
+ len = udi_usb_rcv_control_msg (devc->mixer_usbdev, 0, // endpoint
+ GET_MIN, USB_RECIP_INTERFACE | USB_TYPE_CLASS, // rqtype
+ ((j) << 8) | (c), // value
+ (un->num << 8), // index
+ buf, // buffer
+ 2, // buflen
+ OSS_HZ * 2);
+
+ if (len >= 0)
+ cmn_err (CE_CONT, "Min=%02x%02x ", buf[0], buf[1]);
+ if (len == 1)
+ cmn_err (CE_CONT, "(%d) ", (signed char) buf[0]);
+ else if (len == 2)
+ cmn_err (CE_CONT, "(%d) ",
+ (signed short) (buf[0] | (buf[1] << 8)));
+
+ buf[0] = buf[1] = 0;
+ len = udi_usb_rcv_control_msg (devc->mixer_usbdev, 0, // endpoint
+ GET_MAX, USB_RECIP_INTERFACE | USB_TYPE_CLASS, // rqtype
+ ((j) << 8) | (c), // value
+ (un->num << 8), // index
+ buf, // buffer
+ 2, // buflen
+ OSS_HZ * 2);
+
+ if (len >= 0)
+ cmn_err (CE_CONT, "max=%02x%02x ", buf[0], buf[1]);
+ if (len == 1)
+ cmn_err (CE_CONT, "(%d) ", (signed char) buf[0]);
+ else if (len == 2)
+ cmn_err (CE_CONT, "(%d) ",
+ (signed short) (buf[0] | (buf[1] << 8)));
+
+ cmn_err (CE_CONT, "\n");
+ }
+ }
+ }
+ }
+}
+#endif
+
+/*ARGSUSED*/
+static ossusb_devc *
+ossusb_init_audioctl (ossusb_devc * devc, udi_usb_devc * usbdev, int inum,
+ int reinit)
+{
+ int desc_len;
+ unsigned char *desc, *d;
+ int i, l, n = 0, p, x, mixnum = -1;
+ char *name;
+ usb_audio_unit_t *un;
+
+ /* nsettings = udi_usbdev_get_num_altsettings (usbdev); */
+ devc->mixer_usbdev = usbdev;
+
+ if (!init_mixer (devc))
+ return NULL;
+
+ desc = udi_usbdev_get_altsetting (usbdev, 0, &desc_len);
+
+ if (desc == NULL)
+ {
+ cmn_err (CE_CONT, "Can't read interface descriptors\n");
+ return NULL;
+ }
+
+ p = 0;
+ while (p < desc_len)
+ {
+ d = desc + p;
+
+ l = *d;
+ if (usb_trace > 1)
+ {
+ char str[256], *s = str;
+ sprintf (s, "Control desc(%d): ", p);
+ s += strlen (s);
+ for (i = 0; i < l; i++)
+ {
+ sprintf (s, "%02x ", d[i]);
+ s += strlen (s);
+ }
+ cmn_err (CE_CONT, "%s\n", str);
+ }
+
+#define CASE(x) case x:cmn_err(CE_CONT, #x "\n"); break;
+
+ if (d[1] == CS_INTERFACE)
+ switch (d[2])
+ {
+ case AC_HEADER:
+ if (usb_trace)
+ {
+ cmn_err (CE_CONT, " Audio control interface header\n");
+ n = d[7];
+ cmn_err (CE_CONT, " %d related streaming interfaces: ",
+ n);
+ for (i = 0; i < n; i++)
+ {
+ cmn_err (CE_CONT, "%d ", d[8 + i]);
+ }
+ cmn_err (CE_CONT, "\n");
+ }
+ break;
+
+ case AC_INPUT_TERMINAL:
+ name =
+ get_terminal_id (ossusb_get_int (&d[4], 2), "in", TY_INPUT,
+ &mixnum);
+ if ((un = setup_unit (devc, d[3], name, d, l, TY_INPUT)) == NULL)
+ return NULL;
+ un->mixnum = mixnum;
+ un->channels = d[7];
+ un->chmask = ossusb_get_int (&d[8], 2);
+ break;
+
+ case AC_OUTPUT_TERMINAL:
+ name =
+ get_terminal_id (ossusb_get_int (&d[4], 2), "out", TY_OUTPUT,
+ &mixnum);
+ if ((un = setup_unit (devc, d[3], name, d, l, TY_OUTPUT)) == NULL)
+ return NULL;
+ un->mixnum = mixnum;
+ break;
+
+ case AC_MIXER_UNIT:
+ if ((un = setup_unit (devc, d[3], "mix", d, l, TY_MIXER)) == NULL)
+ return NULL;
+ {
+ // Check if there are any visible controls
+
+ int mask = 0, nn;
+
+ n = d[4]; // # of input pins
+ d += 5 + n;
+ nn = *d; // # of channels
+ d += 4; // Seek to bmControls
+
+ n = (n * nn + 7) / 8;
+
+ for (i = 0; i < n; i++)
+ mask |= d[i];
+
+ un->ctl_avail = mask;
+ }
+ break;
+
+ case AC_SELECTOR_UNIT:
+ if ((un =
+ setup_unit (devc, d[3], "src", d, l, TY_SELECT)) == NULL)
+ return NULL;
+ un->ctl_avail = 1;
+ break;
+
+ case AC_FEATURE_UNIT:
+ if ((un = setup_unit (devc, d[3], "fea", d, l, TY_FEAT)) == NULL)
+ return NULL;
+ un->ctl_avail = get_feature_mask (d, 2); /* For now */
+ break;
+
+ case AC_PROCESSING_UNIT:
+ parse_processing_unit (devc, d, l);
+ break;
+
+ case AC_EXTENSION_UNIT:
+ if ((un = setup_unit (devc, d[3], "ext", d, l, TY_EXT)) == NULL)
+ return NULL;
+ un->ctl_avail = 1;
+
+ break;
+
+ }
+
+ p += l;
+ }
+
+// Make sure the unit names are unique */
+
+ for (x = 1; x < devc->nunits; x++)
+ {
+ usb_audio_unit_t *un = &devc->units[x];
+ int n = 0;
+
+ if (un->typ != TY_SELECT)
+ for (i = x + 1; i < devc->nunits; i++)
+ if (strcmp (devc->units[i].name, un->name) == 0)
+ n++;
+
+ if (n > 0)
+ {
+ char tmpname[16];
+ strcpy (tmpname, un->name);
+ n = 1;
+
+ for (i = x; i < devc->nunits; i++)
+ if (strcmp (devc->units[i].name, tmpname) == 0)
+ {
+ if (n > 1)
+ sprintf (devc->units[i].name, "%s%d", tmpname, n);
+ n++;
+ }
+ }
+
+// Make sure the mixer control numbers are unique too
+
+ n = 0;
+ if (un->mixnum != -1)
+ for (i = x + 1; i < devc->nunits; i++)
+ if (devc->units[i].mixnum == un->mixnum)
+ n++;
+
+ if (n > 0)
+ for (i = x + 1; i < devc->nunits; i++)
+ if (devc->units[i].mixnum == un->mixnum)
+ {
+ usb_audio_unit_t *uu = &devc->units[i];
+
+ switch (uu->mixnum)
+ {
+ case SOUND_MIXER_PCM:
+ uu->mixnum = SOUND_MIXER_ALTPCM;
+ break;
+ case SOUND_MIXER_LINE:
+ uu->mixnum = SOUND_MIXER_LINE1;
+ break;
+ case SOUND_MIXER_LINE1:
+ uu->mixnum = SOUND_MIXER_LINE2;
+ break;
+ case SOUND_MIXER_LINE2:
+ uu->mixnum = SOUND_MIXER_LINE3;
+ break;
+ case SOUND_MIXER_DIGITAL1:
+ uu->mixnum = SOUND_MIXER_DIGITAL2;
+ break;
+ case SOUND_MIXER_DIGITAL2:
+ uu->mixnum = SOUND_MIXER_DIGITAL3;
+ break;
+ default:
+ uu->mixnum = -1;
+ }
+ }
+
+ }
+
+// Handle output selector names
+
+
+ for (x = 1; x < devc->nunits; x++)
+ {
+ usb_audio_unit_t *un = &devc->units[x];
+ int n;
+
+ if (un->typ != TY_OUTPUT)
+ continue;
+
+ n = un->desc[7]; // Source ID
+ if (n < 0 || n >= devc->nunits)
+ continue;
+
+ if (devc->units[n].target == 0)
+ devc->units[n].target = x;
+
+ if (devc->units[n].typ == TY_SELECT && usb_mixerstyle == 0)
+ sprintf (devc->units[n].name, "%s.src", un->name);
+ }
+
+// Find out the sources
+ for (x = 1; x < devc->nunits; x++)
+ {
+ usb_audio_unit_t *un = &devc->units[x];
+
+ d = un->desc;
+ l = un->desclen;
+
+ switch (un->typ)
+ {
+ case TY_INPUT:
+ break;
+
+ case TY_OUTPUT:
+ un->source = d[7];
+ break;
+
+ case TY_SELECT:
+ un->source = d[5];
+ n = d[4];
+ for (i = 0; i < n; i++)
+ if (d[i + 5] > 0 && d[i + 5] <= devc->nunits)
+ if (devc->units[d[i + 5]].target == 0)
+ devc->units[d[i + 5]].target = x;
+ break;
+
+ case TY_MIXER:
+ n = d[4];
+ un->control_count = n;
+ un->source = d[5];
+ for (i = 0; i < n; i++)
+ if (d[i + 5] > 0 && d[i + 5] <= devc->nunits)
+ if (devc->units[d[i + 5]].target == 0)
+ devc->units[d[i + 5]].target = x;
+
+ d += n + 5;
+ un->channels = *d++;
+ un->chmask = ossusb_get_int (d, 2);
+ break;
+
+ case TY_FEAT:
+ un->source = d[4];
+ if (d[4] > 0 && d[4] <= devc->nunits)
+ if (devc->units[d[4]].target == 0)
+ devc->units[d[4]].target = x;
+ break;
+
+ //case TY_EXT:
+ case TY_PROC:
+ n = d[6];
+ un->source = d[7];
+ for (i = 0; i < n; i++)
+ if (d[i + 7] > 0 && d[i + 7] <= devc->nunits)
+ if (devc->units[d[i + 7]].target == 0)
+ devc->units[d[i + 7]].target = x;
+ break;
+ }
+ }
+
+// Trace the channel config
+
+ for (x = 1; x < devc->nunits; x++)
+ {
+ usb_audio_unit_t *un = &devc->units[x], *uu;
+ int ref;
+
+ if (un->typ == TY_INPUT || un->typ == TY_MIXER)
+ continue;
+
+ if (un->typ == TY_PROC && un->subtyp == 1) // Upmix/downmix unit
+ continue;
+
+ ref = follow_source_links (devc, un);
+ uu = &devc->units[ref];
+
+ un->channels = uu->channels;
+ un->chmask = uu->chmask;
+ }
+
+// Handle feature channels
+ for (x = 1; x < devc->nunits; x++)
+ {
+ usb_audio_unit_t *un = &devc->units[x];
+
+ if (un->num == 0 || un->typ != TY_FEAT)
+ continue;
+
+ d = un->desc;
+ l = un->desclen;
+
+ un->ctl_avail = get_feature_mask (d, un->channels);
+ }
+
+// Final checks
+ for (x = 1; x < devc->nunits; x++)
+ {
+ usb_audio_unit_t *un = &devc->units[x];
+ int j;
+
+ if (un->num == 0)
+ {
+ //cmn_err(CE_CONT, "Skipped undefined control %d\n", x);
+ continue;
+ }
+ d = un->desc;
+ l = un->desclen;
+
+ switch (un->typ)
+ {
+ case TY_SELECT:
+ n = d[4];
+ un->control_count = n;
+ d += 5;
+ break;
+
+ case TY_MIXER:
+ n = d[4];
+ un->control_count = n;
+ d += 5;
+ break;
+
+ case TY_FEAT:
+ n = d[5];
+ d += 6;
+ for (i = 0; i < n * 8; i++)
+ name = check_feature (un, d, i);
+ for (j = 1; j <= un->channels; j++)
+ {
+ for (i = 0; i < n * 8; i++)
+ name = check_feature (un, d + j * n, i);
+ }
+ break;
+
+ }
+ }
+
+#if 0
+// Debugging
+ if (usb_trace)
+ for (x = 1; x < devc->nunits; x++)
+ {
+ usb_audio_unit_t *un = &devc->units[x];
+ int j;
+ int ref = 0;
+
+ if (un->num == 0)
+ {
+ //cmn_err(CE_CONT, "Skipped undefined control %d\n", x);
+ continue;
+ }
+ d = un->desc;
+ l = un->desclen;
+ // ossusb_dump_desc (d, l);
+ cmn_err (CE_CONT, "%2d: %s ", un->num, un->name);
+ if (un->mixnum != -1)
+ cmn_err (CE_CONT, "mix=%d ", un->mixnum);
+ if (un->source)
+ cmn_err (CE_CONT, "source=%d ", un->source);
+ if (un->target)
+ cmn_err (CE_CONT, "target=%d ", un->target);
+ cmn_err (CE_CONT, "ch=%d/%x ", un->channels, un->chmask);
+
+ switch (un->typ)
+ {
+ case TY_INPUT:
+ cmn_err (CE_CONT, "Input terminal type: %04x ",
+ ossusb_get_int (&d[4], 2));
+ cmn_err (CE_CONT, "Associated output 0x%02x ", d[6]);
+ cmn_err (CE_CONT, "#chn %d ", d[7]);
+ cmn_err (CE_CONT, "chconf %04x ", ossusb_get_int (&d[8], 2));
+ if (d[10])
+ cmn_err (CE_CONT, "chname# %d ", d[10]);
+ if (d[11])
+ cmn_err (CE_CONT, "terminalname# %d (%s) ", d[11],
+ udi_usbdev_get_string (usbdev, d[11]));
+ break;
+
+ case TY_OUTPUT:
+ cmn_err (CE_CONT, "Output terminal type: %04x ",
+ ossusb_get_int (&d[4], 2));
+ cmn_err (CE_CONT, "Associated input 0x%02x ", d[6]);
+ cmn_err (CE_CONT, "sourceid %d ", d[7]);
+ if (d[8])
+ cmn_err (CE_CONT, "terminalname# %d ", d[8]);
+ break;
+
+ case TY_SELECT:
+ n = d[4];
+ d += 5;
+ cmn_err (CE_CONT, "%d input pins (", n);
+ for (i = 0; i < n; i++)
+ {
+ ref = follow_source_links (devc, &devc->units[*d]);
+ cmn_err (CE_CONT, "%d/%s ", *d, devc->units[ref].name);
+ d++;
+ }
+ cmn_err (CE_CONT, ") ");
+ break;
+
+ case TY_MIXER:
+ n = d[4];
+ d += 5;
+ cmn_err (CE_CONT, "%d inputs (", n);
+ for (i = 0; i < n; i++)
+ {
+ ref = follow_source_links (devc, &devc->units[*d]);
+ cmn_err (CE_CONT, "%d/%s ", *d, devc->units[ref].name);
+ d++;
+ }
+ cmn_err (CE_CONT, ") ");
+ break;
+
+ case TY_FEAT:
+ //ossusb_dump_desc(d, l);
+ cmn_err (CE_CONT, "Source %d:%s ", d[4], devc->units[d[4]].name);
+ n = d[5];
+ d += 6;
+ cmn_err (CE_CONT, "main (", n);
+ for (i = 0; i < n * 8; i++)
+ if ((name = check_feature (un, d, i)) != NULL)
+ cmn_err (CE_CONT, "%s ", name);
+ cmn_err (CE_CONT, ") ");
+ for (j = 1; j <= un->channels; j++)
+ {
+ cmn_err (CE_CONT, "ch %d (", j);
+ for (i = 0; i < n * 8; i++)
+ if ((name = check_feature (un, d + j * n, i)) != NULL)
+ cmn_err (CE_CONT, "%s ", name);
+ cmn_err (CE_CONT, ") ");
+ }
+ break;
+
+ case TY_PROC:
+ cmn_err (CE_CONT, "subtype %x Sources/%d) (", un->subtyp, n);
+ n = d[6];
+ d += 7;
+ cmn_err (CE_CONT, "%d ", *d);
+ d++;
+ cmn_err (CE_CONT, ") ");
+ break;
+
+ case TY_EXT:
+ cmn_err (CE_CONT, "Extension unit %02x%02x ", d[5], d[4]);
+ break;
+
+ }
+
+ cmn_err (CE_CONT, "\n");
+ }
+#endif
+
+ if (usb_mixerstyle == 0)
+ setup_legacy_mixer (devc);
+ touch_mixer (devc->mixer_dev);
+
+ if (usb_trace)
+ mixer_dump (devc);
+
+ return devc;
+}
+
+static ossusb_devc *
+find_devc (char *devpath, int vendor, int product)
+{
+ int i;
+
+ for (i = 0; i < ndevs; i++)
+ {
+ if (devc_list[i]->vendor == vendor && devc_list[i]->product == product)
+ if (strcmp (devc_list[i]->devpath, devpath) == 0)
+ {
+ UDB (cmn_err (CE_CONT, "Another instance of '%s'\n", devpath));
+ return devc_list[i];
+ }
+ }
+
+ return NULL;
+}
+
+static void
+ossusb_device_disconnect (void *d)
+{
+ ossusb_devc *devc = d;
+ int i;
+
+ if (devc == NULL)
+ {
+ cmn_err (CE_WARN, "oss_usb_device_disconnect: devc==NULL\n");
+ return;
+ }
+
+ if (devc->unload_func)
+ {
+ devc->unload_func (devc);
+ return;
+ }
+
+ devc->disabled = 1;
+
+ for (i = 0; i < devc->num_audio_engines; i++)
+ {
+ int dev;
+
+ dev = devc->portc[i].audio_dev;
+
+ if (dev < 0 || dev >= num_audio_engines)
+ continue;
+
+ audio_engines[dev]->enabled = 0;
+
+ if (devc->mixer_dev >= 0)
+ mixer_devs[devc->mixer_dev]->enabled = 0;
+ }
+
+}
+
+static void *
+ossusb_device_attach (udi_usb_devc * usbdev, oss_device_t * osdev)
+{
+ ossusb_devc *devc;
+ char *devpath;
+ int inum;
+ int old = 1;
+ int i;
+ int class, subclass;
+ int vendor, product, version;
+
+ devpath = udi_usbdev_get_devpath (usbdev);
+ inum = udi_usbdev_get_inum (usbdev);
+ class = udi_usbdev_get_class (usbdev);
+ subclass = udi_usbdev_get_subclass (usbdev);
+ vendor = udi_usbdev_get_vendor (usbdev);
+ product = udi_usbdev_get_product (usbdev);
+ version = udi_usbdev_get_usb_version (usbdev);
+
+ if ((devc = find_devc (devpath, vendor, product)) == NULL)
+ {
+ old = 0;
+
+ if (ndevs >= MAX_DEVC)
+ {
+ cmn_err (CE_CONT, "Too many USB audio devices\n");
+ return NULL;
+ }
+
+ if ((devc = PMALLOC (osdev, sizeof (*devc))) == NULL)
+ {
+ cmn_err (CE_CONT, "Out of memory\n");
+ return NULL;
+ }
+ memset (devc, 0, sizeof (*devc));
+ devc->mixer_dev = -1;
+
+ devc->osdev = osdev;
+ osdev->devc = devc;
+
+ MUTEX_INIT (devc->osdev, devc->mutex, MH_DRV);
+
+ devc->vendor = vendor;
+ devc->product = product;
+ devc->usb_version = version;
+ devc->dev_name = udi_usbdev_get_name (usbdev);
+
+ strcpy (devc->devpath, udi_usbdev_get_devpath (usbdev));
+
+ devc_list[ndevs++] = devc;
+ }
+ else
+ {
+ devc->osdev = osdev;
+ osdev->devc = devc;
+ }
+
+ if (devc->dev_name == NULL)
+ devc->dev_name = "Generic USB device";
+ oss_register_device (osdev, devc->dev_name);
+
+ devc->disabled = 0;
+
+ if (old)
+ {
+ /* Check if this interface number is already seen */
+ old = 0;
+ for (i = 0; !old && i < devc->num_interfaces; i++)
+ if (devc->inum[i] == inum)
+ old = 1;
+ }
+
+ if (!old)
+ {
+ if (devc->num_interfaces >= MAX_IFACE)
+ {
+ cmn_err (CE_CONT, "The device has too many interfaces\n");
+ return NULL;
+ }
+
+ devc->usbdev[devc->num_interfaces] = usbdev;
+ devc->last_usbdev = usbdev;
+ devc->inum[devc->num_interfaces] = inum;
+ devc->num_interfaces++;
+ }
+ else
+ {
+ devc->last_usbdev = usbdev;
+ }
+
+ switch (class)
+ {
+ case USBCLASS_AUDIO:
+ switch (subclass)
+ {
+ case 1: /* Audiocontrol subclass */
+ devc->main_osdev = osdev;
+ if (!usb_quiet)
+ cmn_err (CE_CONT, "%s audioctl device %s/%d - %s\n",
+ old ? "Reinsert of an" : "New",
+ devc->devpath, inum, devc->dev_name);
+ return ossusb_init_audioctl (devc, usbdev, inum, old);
+ break;
+
+ case 2: /* Audio streaming subclass */
+ if (!usb_quiet)
+ cmn_err (CE_CONT, "%s audio streaming device %s/%d - %s\n",
+ old ? "Reinsert of an" : "New",
+ devc->devpath, inum, devc->dev_name);
+ devc->osdev->first_mixer = devc->main_osdev->first_mixer;
+ return ossusb_init_audiostream (devc, usbdev, inum, old);
+ break;
+
+ case 3: /* MIDI streaming subclass */
+ return NULL;
+ break;
+
+ default:
+ cmn_err (CE_CONT,
+ "Unknown USB audio device subclass %x:%d, device=%s\n",
+ class, subclass, devc->dev_name);
+ return NULL;
+ }
+ break;
+
+#if 0
+ case USBCLASS_HID:
+ cmn_err (CE_CONT, "HID interface class %x:%d, device=%s\n",
+ class, subclass, devc->dev_name);
+ return NULL;
+ break;
+#endif
+
+ default:
+ cmn_err (CE_CONT, "Unknown USB device class %x:%d, device=%s\n",
+ class, subclass, devc->dev_name);
+ }
+
+ return devc;
+}
+
+static udi_usb_driver ossusb_driver = {
+ ossusb_device_attach,
+ ossusb_device_disconnect
+};
+
+int
+oss_usb_attach (oss_device_t * osdev)
+{
+ if (usb_trace < 0)
+ {
+ udi_usb_trace = 0;
+ usb_trace = 0;
+ usb_quiet = 1;
+ }
+ else if (usb_trace > 0)
+ udi_usb_trace = usb_trace;
+
+ return udi_attach_usbdriver (osdev, known_devices, &ossusb_driver);
+}
+
+int
+oss_usb_detach (oss_device_t * osdev)
+{
+ if (oss_disable_device (osdev) < 0)
+ return 0;
+
+ udi_unload_usbdriver (osdev);
+ oss_unregister_device (osdev);
+
+ return 1;
+}
diff --git a/kernel/drv/oss_usb/oss_usb.man b/kernel/drv/oss_usb/oss_usb.man
new file mode 100644
index 0000000..556e4de
--- /dev/null
+++ b/kernel/drv/oss_usb/oss_usb.man
@@ -0,0 +1,56 @@
+NAME
+ oss_usb - USB Audio/MIDI/Mixer driver
+
+DESCRIPTION
+ The Open Sound System driver for USB Audio and MIDI devices.
+
+ AUDIO
+ The Audio driver supports:
+
+ o 8-96Khz Playback/Recording
+ o 8 or 16 or 32 bits
+ o 2, 4, 6 or 8 channel audio.
+ o SPDIF digital output and Input
+ o AC3 passthrough
+ o Volume control and device input mixer
+
+ MIDI
+The oss_usb driver supports all MIDI devices that are compatible with the
+official USB MIDI specification. In addition the driver supports few devices
+that use their own private protocol (including some Yamaha and Midiman models).
+
+ USB MIXER
+ The USB Audio mixer is a new type of mixer that doesn't have
+ the normal volume controls found on AC97 or Legacy SB devices.
+ The USB audio mixer provides control for selecting the Alternate
+ device setting - this usually allows the device to be switched
+ into a Professional audio mode (eg 24bit or 96Khz mode)
+
+ ALTERNATIVE SETTINGS
+ Some USB audio devices use a feature called as alternative settings for
+ bandwidth management. Typically such devices have multiple high speed
+ inputs and outputs that may require more bandwidth than provided by the USB
+ bus. The alternative settings feature is used to select between multiple
+ low speed devices or just few high speed devices.
+
+ When the device has multiple alternative settings an "altsetting" selector
+ will be visible in the control panel for the device (use ossmix(1) or
+ ossxmix(1) to change it). Alternative setting OFF means that all
+ audio devices are disabled. The other settings provide different combinations
+ of high/medium speed devices. You can use the ossinfo(1) command
+ (ossinfo -a -v3) to find out the devices supported by the currently selected
+ alternative settings and the capabilities of them.
+
+KNOWN BUGS
+ Under Linux it is necessary to run the ossdetect -d and ossdevlinks commands
+ after an USB device has been hot-plugged. Alternatively you can execute
+ soundoff and soundon to reload OSS.
+
+OPTIONS
+None
+
+FILES
+CONFIGFILEPATH/oss_usb.conf Device configuration file
+
+AUTHOR
+4Front Technologies
diff --git a/kernel/drv/oss_usb/ossusb.h b/kernel/drv/oss_usb/ossusb.h
new file mode 100644
index 0000000..df28418
--- /dev/null
+++ b/kernel/drv/oss_usb/ossusb.h
@@ -0,0 +1,246 @@
+/*
+ * Purpose: Definitions for the USB audio driver files
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This this source file is released under GPL v2 license (no other versions).
+ * See the COPYING file included in the main directory of this source
+ * distribution for the license terms and conditions.
+ *
+ */
+
+#ifndef __OSUSB_H_
+#define __OSUSB_H_
+
+#include "udi.h"
+#include "midi_core.h"
+
+#define CS_DEVICE 0x21
+#define CS_CONFIG 0x22
+#define CS_STRING 0x23
+#define CS_INTERFACE 0x24
+#define CS_ENDPOINT 0x25
+
+#define AC_HEADER 0x01
+#define AC_INPUT_TERMINAL 0x02
+#define AC_OUTPUT_TERMINAL 0x03
+#define AC_MIXER_UNIT 0x04
+#define AC_SELECTOR_UNIT 0x05
+#define AC_FEATURE_UNIT 0x06
+#define AC_PROCESSING_UNIT 0x07
+#define AC_EXTENSION_UNIT 0x08
+
+#define AS_GENERAL 0x01
+#define AS_FORMAT_TYPE 0x02
+#define AS_FORMAT_SPECIFIC 0x03
+
+#define SET_CUR 0x01
+#define SET_MEM 0x05
+#define GET_CUR 0x81
+#define GET_MIN 0x82
+#define GET_MAX 0x83
+#define GET_RES 0x84
+#define GET_MEM 0x85
+#define GET_STAT 0xff
+
+#define USB_RECIP_MASK 0x1f
+#define USB_RECIP_DEVICE 0x00
+#define USB_RECIP_INTERFACE 0x01
+#define USB_RECIP_ENDPOINT 0x02
+#define USB_RECIP_OTHER 0x03
+#define USB_VENDOR_REQUEST 0x40
+
+#define USB_TYPE_CLASS 0x20
+
+/*
+ * Unit types
+ *
+ * Note that TY_OUTPUT is actually PCM input and TY_INPUT is actually
+ * PCM output. Unit types are defined as seen as the USB control interface.
+ * Input terminals listen to the output streaming interfases and output
+ * terminals feed the input streaming interfaces. Confusing it is.
+ */
+#define TY_INPUT 0
+#define TY_OUTPUT 1
+#define TY_MIXER 2
+#define TY_SELECT 3
+#define TY_FEAT 4
+#define TY_PROC 5
+#define TY_EXT 6
+// Remember to inclease size of devc->unit_counters[] if adding more unit types
+
+#define USBCLASS_AUDIO 1
+#define USBCLASS_HID 3
+
+#define MAX_IFACE 10
+
+typedef struct
+{
+ int num;
+ int typ; // TY_*
+ int subtyp;
+ char name[16];
+ unsigned char *desc;
+ int desclen;
+ int mixnum;
+ int target;
+ int source;
+ int ctl_avail;
+ int control_count;
+ int channels;
+ int chmask;
+} usb_audio_unit_t;
+
+#define MAX_UNIT 40
+#define MAX_CONTROLS 100
+#define MAX_PORTC 8 /* Max audio streaming interfaces per device */
+#define MAX_MIDIC 16 /* Max MIDI streaming interfaces per device */
+
+typedef struct
+{
+ usb_audio_unit_t *unit;
+ int index;
+ int flags;
+ int min_ch, max_ch;
+ int global;
+ int chmask;
+ int value;
+ int min, max, scale;
+ int exttype;
+} usb_control_t;
+
+typedef struct ossusb_devc ossusb_devc;
+
+typedef struct
+{
+ ossusb_devc *devc;
+ int disabled;
+ int if_number;
+ void *endpoint_desc, *orig_endpoint_desc;
+ udi_endpoint_handle_t *endpoint_handle;
+ int audio_dev;
+ int open_mode;
+ int permitted_modes;
+ int prepared_modes;
+ int stopping;
+
+ int speed;
+ int bytes_per_sample;
+ int terminal_link;
+ udi_usb_devc *usbdev;
+ int num_settings;
+ int act_setting;
+
+#define NR_DATAPIPES 2
+ udi_usb_request_t *datapipe[NR_DATAPIPES];
+ int curr_datapipe;
+ int fragment_size; /* Bytes per (1ms) USB tick */
+ int overflow_samples, overflow_size;
+ int convert_3byte;
+ int pipeline_delay;
+ unsigned char *tmp_buf[2];
+ int use_tmpbuf;
+ oss_dma_handle_t tmpbuf_dma_handle[2];
+} ossusb_portc;
+
+typedef struct
+{
+ struct ossusb_devc *devc;
+ oss_device_t *osdev;
+ udi_usb_devc *usbdev;
+
+ void *in_endpoint_desc, *out_endpoint_desc;
+ udi_endpoint_handle_t *in_endpoint_handle, *out_endpoint_handle;
+ int portnum;
+ int midi_dev;
+ int open_mode;
+ // int output_endpoint;
+ oss_midi_inputbyte_t midi_input_intr;
+ oss_midi_outputintr_t midi_output_intr;
+} ossusb_midic;
+
+typedef void *(*special_driver_t) (ossusb_devc * devc);
+typedef void (*special_unload_t) (void *devc);
+
+struct ossusb_devc
+{
+ special_unload_t unload_func;
+ oss_device_t *osdev;
+ oss_device_t *main_osdev;
+ oss_mutex_t mutex;
+ int num_interfaces;
+ udi_usb_devc *usbdev[MAX_IFACE], *last_usbdev;
+ int inum[MAX_IFACE];
+ int vendor, product;
+ char *dev_name, devpath[32];
+ int nports;
+ int disabled;
+ int usb_version; // 1 or 2
+
+ /*
+ * Units
+ */
+
+ usb_audio_unit_t units[MAX_UNIT];
+ int nunits;
+ char unit_counters[7]; // For TY_* identifiers
+
+ /*
+ * Mixer stuff
+ */
+ int mixer_dev;
+ void *mixer_usbdev;
+ int devmask, recmask, stereodevs, recsrc;
+
+ int rec_unit;
+ int num_recdevs;
+ int recdevs[32];
+
+ int *levels;
+
+ usb_control_t controls[MAX_CONTROLS];
+ int ncontrols;
+
+/* Audio stuff */
+ int num_audio_engines, num_inputs, num_outputs;
+ ossusb_portc portc[MAX_PORTC];
+
+/* MIDI stuff */
+ int num_mididevs;
+ ossusb_midic midic[MAX_MIDIC];
+
+ unsigned char *playbuf;
+ oss_dma_handle_t playbuf_dma_handle;
+ udi_usb_request_t *output_pipe;
+ int output_busy;
+#define Q_MAX 4096
+ unsigned char queue[Q_MAX];
+ int q_nbytes;
+
+ unsigned char *recbuf;
+ oss_dma_handle_t recbuf_dma_handle;
+ udi_usb_request_t *input_pipe;
+ udi_endpoint_handle_t *input_endpoint_handle;
+};
+
+extern int usb_trace, usb_quiet;
+
+#define UDB(x) {if (usb_trace) x;}
+
+extern ossusb_devc *ossusb_init_audiostream (ossusb_devc * devc,
+ udi_usb_devc * usbdev, int inum,
+ int reinit);
+extern ossusb_devc *ossusb_init_midistream (ossusb_devc * devc,
+ udi_usb_devc * usbdev, int inum,
+ int reinit);
+extern void ossusb_disconnect_midistream (ossusb_devc * devc);
+extern void ossusb_dump_desc (unsigned char *desc, int cfg_len);
+extern unsigned int ossusb_get_int (unsigned char *p, int nbytes);
+extern int ossusb_change_altsetting (int dev, int ctrl, unsigned int cmd,
+ int value);
+extern void ossusb_create_altset_control(int dev, int portc_num, int nalt, char *name);
+#endif
diff --git a/kernel/drv/oss_usb/ossusb_audio.c b/kernel/drv/oss_usb/ossusb_audio.c
new file mode 100644
index 0000000..8135d62
--- /dev/null
+++ b/kernel/drv/oss_usb/ossusb_audio.c
@@ -0,0 +1,1425 @@
+/*
+ * Purpose: USB audio streaming interface support
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This this source file is released under GPL v2 license (no other versions).
+ * See the COPYING file included in the main directory of this source
+ * distribution for the license terms and conditions.
+ *
+ */
+
+#include "oss_config.h"
+#include "ossusb.h"
+
+#define SAMPLING_FREQ_CONTROL 0x01
+#define PITCH_CONTROL 0x02
+
+#define FORMAT_II_UNDEFINED 0x1000
+#define FORMAT_II_MPEG 0x1001
+#define FORMAT_II_AC3 0x1002
+
+#define TMPBUF_SIZE 4096
+
+#if 0
+static int
+read_control_value (ossusb_devc * devc, int endpoint, int ctl, int l)
+{
+ unsigned char buf[4];
+ int len, i, v;
+
+ memset (buf, 0, sizeof (buf));
+
+ len = udi_usb_rcv_control_msg (devc->mixer_usbdev, 0, // endpoint
+ GET_CUR, USB_RECIP_ENDPOINT | USB_TYPE_CLASS, // rqtype
+ ctl << 8, // value
+ endpoint, // index
+ buf, // buffer
+ l, // buflen
+ OSS_HZ);
+ if (len < 0)
+ {
+ cmn_err (CE_WARN, "Endpoint read error %d\n", len);
+ return 0;
+ }
+
+ cmn_err (CE_CONT, "Read len %d (%d): ", len, l);
+ for (i = 0; i < len; i++)
+ cmn_err (CE_CONT, "%02x ", buf[i]);
+
+ switch (len)
+ {
+ case 3:
+ v = buf[0] | (buf[1] << 8) | (buf[2] << 16);
+ break;
+
+ default:
+ cmn_err (CE_CONT, "oss usbaudio: Bad control read (%d)\n", l);
+ }
+
+ cmn_err (CE_CONT, "= %d\n", v);
+
+ return v;
+}
+#endif
+
+static int
+write_control_value (ossusb_devc * devc, udi_endpoint_handle_t * endpoint,
+ int ctl, int l, unsigned int v)
+{
+ unsigned char buf[4];
+ int len;
+
+ memset (buf, 0, sizeof (buf));
+
+ switch (l)
+ {
+ case 3:
+ buf[0] = (v) & 0xff;
+ buf[1] = (v >> 8) & 0xff;
+ buf[2] = (v >> 16) & 0xff;
+ break;
+
+ default:
+ cmn_err (CE_CONT, "oss usbaudio: Bad control size %d\n", l);
+ return OSS_EIO;
+ }
+
+ len = udi_usb_snd_control_msg (devc->mixer_usbdev, 0, // endpoint
+ SET_CUR, USB_RECIP_ENDPOINT | USB_TYPE_CLASS, // rqtype
+ ctl << 8, // value
+ udi_endpoint_get_num (endpoint), // index
+ buf, // buffer
+ l, // buflen
+ OSS_HZ);
+ if (len < 0)
+ {
+ cmn_err (CE_WARN, "Endpoint control write error %d\n", len);
+ return OSS_EIO;
+ }
+
+ return len;
+}
+
+static void
+set_fraglimits (adev_t * adev, ossusb_portc * portc)
+{
+ int l, m;
+
+ if (portc->bytes_per_sample < 1)
+ portc->bytes_per_sample = 1;
+
+ l = portc->bytes_per_sample * adev->min_channels * portc->speed / 1000;
+ l = (l / portc->bytes_per_sample) * portc->bytes_per_sample;
+
+ m = 2;
+
+ while (m < l)
+ m *= 2;
+
+ adev->min_block = m;
+ adev->max_block = TMPBUF_SIZE / 2;
+ portc->fragment_size = l;
+}
+
+static int
+usbaudio_set_rate (int dev, int arg)
+{
+ adev_p adev = audio_engines[dev];
+ ossusb_portc *portc = adev->portc;
+ ossusb_devc *devc = adev->devc;
+
+ int i, x, diff, bestdiff;
+
+ if (devc->disabled)
+ return OSS_EPIPE;
+
+ if (arg == 0)
+ return portc->speed;
+
+ if (arg < adev->min_rate)
+ arg = adev->min_rate;
+ if (arg > adev->max_rate)
+ arg = adev->max_rate;
+
+ if (!(adev->caps & PCM_CAP_FREERATE))
+ {
+ /* Search for the nearest supported rate */
+ bestdiff = 0x7fffffff;
+ x = -1;
+
+ for (i = 0; i < adev->nrates; i++)
+ {
+ diff = arg - adev->rates[i];
+
+ if (diff < 0)
+ diff = -diff; /* ABS */
+ if (diff < bestdiff)
+ {
+ x = i;
+ bestdiff = diff;
+ }
+ }
+
+ if (x > -1)
+ arg = adev->rates[x];
+ }
+
+ portc->speed = arg;
+ set_fraglimits (adev, portc);
+
+ return portc->speed;
+}
+
+/*ARGSUSED*/
+static short
+usbaudio_set_channels (int dev, short arg)
+{
+ adev_p adev = audio_engines[dev];
+ ossusb_devc *devc = adev->devc;
+
+ if (devc->disabled)
+ return OSS_EPIPE;
+
+ return adev->min_channels; /* max_channels should be the same too */
+}
+
+/*ARGSUSED*/
+static unsigned int
+usbaudio_set_format (int dev, unsigned int arg)
+{
+ adev_p adev = audio_engines[dev];
+ ossusb_devc *devc = adev->devc;
+
+ if (devc->disabled)
+ return adev->oformat_mask;
+
+ return adev->oformat_mask; /* iformat_mask should be the same too */
+}
+
+/*ARGSUSED*/
+static int
+usbaudio_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
+{
+ ossusb_devc *devc = audio_engines[dev]->devc;
+ if (devc->disabled)
+ return OSS_EPIPE;
+
+ return OSS_EINVAL;
+}
+
+/*ARGSUSED*/
+static int
+setup_format_I (ossusb_devc * devc, ossusb_portc * portc, adev_p adev,
+ unsigned char *d, int l)
+{
+ int min_rate = 0, max_rate = 0;
+ int i, n;
+ int frame_size, bits, channels;
+ unsigned int fmt = 0;
+
+ if (usb_trace > 1)
+ {
+ cmn_err (CE_CONT,
+ "AS_FORMAT_TYPE: FORMAT_TYPE_I, #ch %d, framesize %d, bits %d, freq_type %02x, freq=",
+ d[4], d[5], d[6], d[7]);
+ if (d[7] == 0)
+ cmn_err (CE_CONT, "%d-%d ", ossusb_get_int (&d[8], 3),
+ ossusb_get_int (&d[11], 3));
+ {
+ for (i = 0; i < d[7]; i++)
+ cmn_err (CE_CONT, "%d ", ossusb_get_int (&d[8 + i * 3], 3));
+ cmn_err (CE_CONT, " ");
+ }
+
+ switch (d[3])
+ {
+ case 0x00:
+ cmn_err (CE_CONT, "Undefined ");
+ break;
+ case 0x01:
+ cmn_err (CE_CONT, "PCM ");
+ break;
+ case 0x02:
+ cmn_err (CE_CONT, "PCM8 ");
+ break;
+ case 0x03:
+ cmn_err (CE_CONT, "float ");
+ break;
+ case 0x04:
+ cmn_err (CE_CONT, "A-Law ");
+ break;
+ case 0x05:
+ cmn_err (CE_CONT, "u-Law ");
+ break;
+ }
+ cmn_err (CE_CONT, "\n");
+ }
+
+ channels = d[4];
+ frame_size = d[5];
+ bits = d[6];
+ UDB (cmn_err (CE_CONT, "Channels %d, bits %d (%d bytes)\n", channels, bits,
+ frame_size));
+
+ adev->min_channels = adev->max_channels = channels;
+ portc->convert_3byte = 0;
+
+ switch (d[3])
+ {
+ case 0x01:
+ fmt = AFMT_S16_LE;
+ break;
+ case 0x02:
+ fmt = AFMT_U8;
+ break;
+ case 0x03:
+ fmt = AFMT_FLOAT;
+ break;
+ case 0x04:
+ fmt = AFMT_A_LAW;
+ break;
+ case 0x05:
+ fmt = AFMT_MU_LAW;
+ break;
+ }
+
+ if (fmt == AFMT_S16_LE) /* Have to check the frame size too */
+ {
+ switch (frame_size)
+ {
+ case 1:
+ fmt = AFMT_S8;
+ break;
+ case 2:
+ fmt = AFMT_S16_LE;
+ break;
+ case 3:
+ fmt = AFMT_S32_LE;
+ frame_size = 4;
+ portc->convert_3byte = 1;
+ break;
+ case 4:
+ fmt = AFMT_S32_LE;
+ break;
+ }
+ }
+
+ portc->bytes_per_sample = frame_size;
+ adev->oformat_mask = adev->iformat_mask = fmt;
+ UDB (cmn_err (CE_CONT, "Format mask %08x\n", fmt));
+
+ adev->caps &= ~PCM_CAP_FREERATE;
+ n = d[7];
+ if (n < 1) /* Free rate selection between min (0) and max (1) */
+ {
+ n = 2;
+ adev->caps |= PCM_CAP_FREERATE;
+ }
+
+ min_rate = 0x7fffffff;
+ max_rate = 0;
+
+ if (n > 20)
+ {
+ cmn_err (CE_WARN, "The device supports too many sample rates\n");
+ n = 20;
+ }
+
+ adev->nrates = 0;
+
+ for (i = 0; i < n; i++)
+ {
+ int rate = ossusb_get_int (&d[8 + i * 3], 3);
+
+#if 0
+ /* Skip rates that are not multiples of 1000 Hz */
+ if (rate % 1000)
+ continue;
+#endif
+
+ if (rate < min_rate)
+ min_rate = rate;
+ if (rate > max_rate)
+ max_rate = rate;
+ adev->rates[adev->nrates++] = rate;
+ }
+
+ adev->min_rate = min_rate;
+ adev->max_rate = max_rate;
+ UDB (cmn_err (CE_CONT, "Min rate %d, max rate %d\n", min_rate, max_rate));
+
+ adev->caps &= ~DSP_CH_MASK;
+
+ switch (channels)
+ {
+ case 1:
+ adev->caps |= DSP_CH_MONO;
+ break;
+ case 2:
+ adev->caps |= DSP_CH_STEREO;
+ break;
+ default:
+ adev->caps |= DSP_CH_MULTI;
+ break;
+ }
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+setup_format_II (ossusb_devc * devc, ossusb_portc * portc, adev_p adev,
+ unsigned char *d, int l)
+{
+ int min_rate = 0, max_rate = 0;
+ int i;
+
+ if (usb_trace > 1)
+ {
+ cmn_err (CE_CONT, "MaxBitRate %d ", d[4]);
+ cmn_err (CE_CONT, "SamplesPerFrame %d ", d[5]);
+
+ if (d[8] == 0)
+ cmn_err (CE_CONT, "Sample Rates %d-%d ", ossusb_get_int (&d[9], 3),
+ ossusb_get_int (&d[12], 3));
+ else
+ {
+ int n;
+ int min_rate = 0x7fffffff;
+ int max_rate = 0;
+
+ n = d[8];
+
+ if (n > 20)
+ {
+ cmn_err (CE_CONT, "oss usbaudio: Too many sample rates (%d)\n",
+ n);
+ n = 20;
+ }
+
+ adev->nrates = 0;
+ cmn_err (CE_CONT, "Possible sample rates: ");
+ for (i = 0; i < d[8]; i++)
+ {
+ int rate = ossusb_get_int (&d[9 + i * 3], 3);
+
+#if 0
+ /* Skip rates that are not multiples of 1000 Hz */
+ if (rate % 1000)
+ continue;
+#endif
+
+ if (rate < min_rate)
+ min_rate = rate;
+ if (rate > max_rate)
+ max_rate = rate;
+ cmn_err (CE_CONT, "%d ", rate);
+ adev->rates[adev->nrates++] = rate;
+ }
+ adev->min_rate = min_rate;
+ adev->max_rate = max_rate;
+ }
+
+ cmn_err (CE_CONT, "\n");
+ }
+
+ adev->caps &= ~PCM_CAP_FREERATE;
+ if (d[8] == 0)
+ {
+ min_rate = ossusb_get_int (&d[9], 3);
+ max_rate = ossusb_get_int (&d[12], 3);
+ adev->caps |= PCM_CAP_FREERATE;
+ }
+ else
+ {
+ min_rate = 1 << 30;
+ max_rate = 0;
+
+ for (i = 0; i < d[8]; i++)
+ {
+ int r = ossusb_get_int (&d[9 + i * 3], 3);
+
+ if (r < min_rate)
+ min_rate = r;
+ if (r > max_rate)
+ max_rate = r;
+ }
+ }
+
+ adev->min_channels = adev->max_channels = 2;
+ adev->oformat_mask = adev->iformat_mask = AFMT_AC3;
+ adev->min_rate = min_rate;
+ adev->max_rate = max_rate;
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+setup_format_specific (ossusb_devc * devc, ossusb_portc * portc, adev_p adev,
+ unsigned char *d, int l)
+{
+ int fmt;
+
+ fmt = ossusb_get_int (&d[3], 2);
+
+ if (usb_trace > 1)
+ cmn_err (CE_CONT, "Format specific: fmt=%04x\n", fmt);
+
+ switch (fmt)
+ {
+ case FORMAT_II_MPEG:
+ if (usb_trace > 1)
+ cmn_err (CE_CONT, "MPEG format\n");
+ adev->oformat_mask = adev->iformat_mask = AFMT_MPEG;
+ break;
+
+ case FORMAT_II_AC3:
+ if (usb_trace > 1)
+ cmn_err (CE_CONT, "AC3 format\n");
+ adev->oformat_mask = adev->iformat_mask = AFMT_AC3;
+#if 0
+ cmn_err (CE_CONT, "BSID=%08x\n", ossusb_get_int (&d[5], 4));
+ cmn_err (CE_CONT, "AC3Features %02x\n", d[9]);
+#endif
+ break;
+
+ default:
+ cmn_err (CE_CONT, "oss usbaudio: Unsupported FORMAT II tag %04x\n",
+ fmt);
+ adev->enabled = 0;
+ return OSS_ENXIO;
+ }
+ return 0;
+}
+
+static int
+prepare_altsetting (ossusb_devc * devc, ossusb_portc * portc, int new_setting)
+{
+ int desc_len;
+ unsigned char *desc, *d;
+ int l, p;
+ int err;
+ adev_p adev;
+
+ adev = audio_engines[portc->audio_dev];
+ adev->enabled = 1;
+ portc->disabled = 0;
+
+ if (portc->act_setting == new_setting) /* No need to change */
+ return 0;
+
+ if (new_setting < portc->num_settings)
+ desc = udi_usbdev_get_altsetting (portc->usbdev, new_setting, &desc_len);
+ else
+ desc = NULL;
+
+ if (desc == NULL || desc_len < 3)
+ {
+ cmn_err (CE_CONT,
+ "Audio device %d not available when altsetting=%d\n",
+ audio_engines[portc->audio_dev]->real_dev, new_setting);
+ portc->disabled = 1;
+ adev->enabled = 0;
+ portc->act_setting = new_setting;
+ return OSS_ENXIO;
+ }
+
+ UDB (cmn_err
+ (CE_CONT, "Select active setting %d on interface %d (dsp%d)\n",
+ new_setting, portc->if_number, adev->engine_num));
+ portc->act_setting = new_setting;
+
+ p = 0;
+ while (p < desc_len)
+ {
+ int i;
+
+ d = desc + p;
+ l = *d;
+
+ if (usb_trace > 1)
+ {
+ cmn_err (CE_CONT, "Streaming desc: ");
+ for (i = 0; i < l; i++)
+ cmn_err (CE_CONT, "%02x ", d[i]);
+ cmn_err (CE_CONT, "\n");
+
+ }
+
+ if (d[1] != CS_INTERFACE)
+ {
+ UDB (cmn_err (CE_CONT, "Unknown descriptor type %02x\n", d[1]))}
+ else
+ switch (d[2])
+ {
+ case AS_GENERAL:
+ portc->terminal_link = d[3];
+ portc->pipeline_delay = d[4];
+
+ if (usb_trace > 1)
+ {
+ cmn_err (CE_CONT, "AS_GENERAL ");
+ cmn_err (CE_CONT, "Terminal link %d/%s ", d[3],
+ devc->units[d[3]].name);
+ cmn_err (CE_CONT, "Delay %d ", d[4]);
+ cmn_err (CE_CONT, "Format tag %02x%02x ", d[5], d[6]);
+ cmn_err (CE_CONT, "\n");
+ }
+ break;
+
+ case AS_FORMAT_TYPE:
+ if (usb_trace > 1)
+ {
+ cmn_err (CE_CONT, "AS_FORMAT_TYPE: FORMAT_TYPE_%d: ", d[3]);
+ }
+
+ switch (d[3])
+ {
+ case 1: /* FORMAT_TYPE_I */
+ if ((err = setup_format_I (devc, portc, adev, d, l)) < 0)
+ return err;
+ break;
+
+ case 2: /* FORMAT_TYPE_II */
+ if ((err = setup_format_II (devc, portc, adev, d, l)) < 0)
+ return err;
+ break;
+
+ default:
+ cmn_err (CE_CONT,
+ "\noss usbaudio: Unsupported format type %d\n",
+ d[3]);
+ adev->enabled = 0;
+ return OSS_ENXIO;
+ }
+ break;
+
+ case AS_FORMAT_SPECIFIC:
+ if ((err = setup_format_specific (devc, portc, adev, d, l)) < 0)
+ return err;
+ break;
+
+ default:
+ UDB (cmn_err
+ (CE_CONT, "Unknown descriptor subtype %02x\n", d[2]));
+ }
+
+ p += l;
+ }
+
+ desc = udi_usbdev_get_endpoint (portc->usbdev, portc->act_setting, 0, &l);
+ if (desc == NULL)
+ {
+ cmn_err (CE_CONT, "oss usbaudio: Bad endpoint\n");
+ return OSS_EIO;
+ }
+
+ portc->endpoint_desc = desc;
+
+ desc = udi_usbdev_get_endpoint (portc->usbdev, portc->act_setting, 1, &l);
+#if 0
+ if (desc != NULL)
+ {
+ /* TODO: Handle sync endpoints */
+ cmn_err (CE_CONT, "Sync Endpoint: ");
+ ossusb_dump_desc (desc, l);
+ }
+#endif
+
+ return 0;
+}
+
+static void usbaudio_close (int dev, int mode);
+
+/*ARGSUSED*/
+static int
+usbaudio_open (int dev, int mode, int open_flags)
+{
+ ossusb_devc *devc = audio_engines[dev]->devc;
+ ossusb_portc *portc = audio_engines[dev]->portc;
+ oss_native_word flags, phaddr;
+ int err;
+ int i;
+
+ if (devc->disabled)
+ return OSS_EPIPE;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (portc->open_mode != 0)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+ portc->open_mode = mode;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ if ((err = prepare_altsetting (devc, portc, portc->act_setting)) < 0)
+ {
+ portc->open_mode = 0;
+ return err;
+ }
+
+ {
+ int i;
+
+ for (i = 0; i < 2; i++)
+ portc->tmp_buf[i] =
+ CONTIG_MALLOC (devc->osdev, TMPBUF_SIZE, MEMLIMIT_32BITS, &phaddr, portc->tmpbuf_dma_handle[i]);
+ }
+
+ if ((err =
+ udi_usbdev_set_interface (portc->usbdev, portc->if_number,
+ portc->act_setting)) < 0)
+ {
+ cmn_err (CE_NOTE,
+ "oss usbaudio: Failed to set interface mode, error %d - ignored\n",
+ err);
+ // portc->open_mode = 0;
+ //return err;
+ }
+
+ portc->curr_datapipe = 0;
+
+ if ((portc->endpoint_handle =
+ udi_open_endpoint (portc->usbdev, portc->endpoint_desc)) == NULL)
+ {
+ usbaudio_close (dev, mode);
+ cmn_err (CE_WARN, "Cannot open audio pipe\n");
+ return OSS_ENOMEM;
+ }
+
+ for (i = 0; i < 2; i++)
+ {
+ if ((portc->datapipe[i] =
+ udi_usb_alloc_request (portc->usbdev, portc->endpoint_handle, 1,
+ UDI_USBXFER_ISO_WRITE)) == NULL)
+ {
+ usbaudio_close (dev, mode);
+ cmn_err (CE_WARN, "Cannot alloc isoc request\n");
+ return OSS_ENOMEM;
+ }
+ }
+
+ set_fraglimits (audio_engines[dev], portc);
+ return 0;
+}
+
+static void usbaudio_reset (int dev);
+
+/*ARGSUSED*/
+static void
+usbaudio_close (int dev, int mode)
+{
+ ossusb_devc *devc = audio_engines[dev]->devc;
+ ossusb_portc *portc = audio_engines[dev]->portc;
+ int i;
+
+ usbaudio_reset (dev);
+
+ for (i = 0; i < 2; i++)
+ {
+ if (portc->datapipe[i] != NULL)
+ {
+ udi_usb_free_request (portc->datapipe[i]);
+ portc->datapipe[i] = NULL;
+ }
+
+ if (portc->tmp_buf[i] != NULL)
+ {
+ CONTIG_FREE (devc->osdev, portc->tmp_buf[i], TMPBUF_SIZE, portc->tmpbuf_dma_handle[i]);
+ portc->tmp_buf[i] = NULL;
+ }
+ }
+
+ if (portc->endpoint_handle != NULL)
+ udi_close_endpoint (portc->endpoint_handle);
+
+ udi_usbdev_set_interface (portc->usbdev, portc->if_number, 0);
+ portc->open_mode = 0;
+}
+
+/*ARGSUSED*/
+static void
+usbaudio_output_block (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+ ossusb_devc *devc = audio_engines[dev]->devc;
+ if (devc->disabled)
+ return;
+}
+
+/*ARGSUSED*/
+static void
+usbaudio_start_input (int dev, oss_native_word buf, int count, int fragsize,
+ int intrflag)
+{
+ ossusb_devc *devc = audio_engines[dev]->devc;
+ if (devc->disabled)
+ return;
+}
+
+static int feed_output (int dev, ossusb_devc * devc, ossusb_portc * portc);
+static void start_input (int dev, ossusb_devc * devc, ossusb_portc * portc);
+
+static int
+copy_input (ossusb_portc * portc, dmap_t * dmap, unsigned char *buf, int len)
+{
+ int outlen = 0;
+ int offs;
+
+ offs = (int) (dmap->byte_counter % dmap->bytes_in_use);
+
+ while (len > 0)
+ {
+ int l;
+ l = len;
+
+ if (portc->convert_3byte)
+ {
+ int i, n;
+ int *dmabuf;
+
+ l = (l * 4) / 3;
+ /* Check for buffer wraparound */
+ if (offs + l > dmap->bytes_in_use)
+ l = dmap->bytes_in_use - offs;
+
+ n = (l / 4);
+
+ if (dmap == NULL || dmap->dmabuf == NULL)
+ return outlen;
+
+ dmabuf = (int *) (dmap->dmabuf + offs);
+
+ for (i = 0; i < n; i++)
+ {
+ int v;
+
+ v = buf[2] | (buf[1] << 8) | (buf[0] << 16);
+ *dmabuf++ = v;
+ buf += 3;
+ }
+
+ outlen += l;
+ }
+ else
+ {
+ unsigned char *dmabuf;
+ dmabuf = dmap->dmabuf;
+
+ if (dmap == NULL || dmap->dmabuf == NULL)
+ return outlen;
+
+ /* Check for buffer wraparound */
+ if (offs + l > dmap->bytes_in_use)
+ l = dmap->bytes_in_use - offs;
+
+ memcpy (dmabuf + offs, buf, l);
+ outlen += l;
+ buf += l;
+ }
+
+ len -= l;
+ offs = 0;
+ }
+
+ return outlen;
+}
+
+/*ARGSUSED*/
+static void
+play_callback (udi_usb_request_t * request, void *arg)
+{
+ ossusb_portc *portc = arg;
+
+ feed_output (portc->audio_dev, portc->devc, portc);
+ oss_audio_outputintr (portc->audio_dev,
+ AINTR_NO_POINTER_UPDATES | AINTR_LOCALQUEUE);
+}
+
+static void
+rec_callback (udi_usb_request_t * request, void *arg)
+{
+ ossusb_portc *portc = arg;
+ dmap_t *dmap;
+ int len;
+
+ if (portc == NULL || (unsigned long) arg < 4096)
+ {
+ cmn_err (CE_WARN, "Bad portc\n");
+ return;
+ }
+
+ dmap = audio_engines[portc->audio_dev]->dmap_in;
+ len = udi_usb_request_actlen (request);
+
+ if (len == 0)
+ return; /* No data so it looks like we are closing down */
+
+ if ((len =
+ copy_input (portc, dmap, udi_usb_request_actdata (request), len)) < 1)
+ {
+ cmn_err (CE_WARN, "Saving recorded data failed (%d)\n", len);
+ return;
+ }
+
+ oss_audio_inc_byte_counter (dmap, len);
+ oss_audio_inputintr (portc->audio_dev, AINTR_NO_POINTER_UPDATES);
+#ifdef linux
+ start_input (portc->audio_dev, portc->devc, portc);
+#endif
+}
+
+#if 0
+/*
+ * Testing stuff only
+ */
+static int
+sin_gen (void)
+{
+
+ static int phase = 0, v;
+
+ static short sinebuf[48] = {
+ 0, 4276, 8480, 12539, 16383, 19947, 23169, 25995,
+ 28377, 30272, 31650, 32486, 32767, 32486, 31650, 30272,
+ 28377, 25995, 23169, 19947, 16383, 12539, 8480, 4276,
+ 0, -4276, -8480, -12539, -16383, -19947, -23169, -25995,
+ -28377, -30272, -31650, -32486, -32767, -32486, -31650, -30272,
+ -28377, -25995, -23169, -19947, -16383, -12539, -8480, -4276
+ };
+ v = sinebuf[phase] * 256;
+ phase = (phase + 1) % 48;
+
+ return v;
+}
+#endif
+
+/*ARGSUSED*/
+static int
+output_convert (ossusb_devc * devc, ossusb_portc * portc, dmap_p dmap,
+ unsigned char *dmabuf, int pos, int pn, int total_len)
+{
+ unsigned char *tmpbuf = portc->tmp_buf[pn], *b;
+ int i, n, len, out_size = 0;
+ int err;
+
+ while (total_len > 0)
+ {
+ int l = total_len;
+
+ /* Check for buffer wraparound */
+ if (pos + l > dmap->bytes_in_use)
+ l = dmap->bytes_in_use - pos;
+
+ total_len -= l;
+
+ b = dmabuf + pos;
+
+ if (portc->convert_3byte)
+ {
+ int *buf;
+
+ n = l / sizeof (*buf);
+ buf = (int *) b;
+
+ len = n * 3;
+
+ for (i = 0; i < n; i++)
+ {
+ int val = (*buf++);
+
+ val /= 256;
+ // val=sin_gen();
+ *tmpbuf++ = (val) & 0xff;
+ *tmpbuf++ = (val >> 8) & 0xff;
+ *tmpbuf++ = (val >> 16) & 0xff;
+ }
+ }
+ else
+ {
+ len = l;
+ memcpy (tmpbuf, b, l);
+ tmpbuf += l;
+ }
+
+ pos = 0;
+ out_size += len;
+ }
+
+ if ((err =
+ udi_usb_submit_request (portc->datapipe[pn], play_callback, portc,
+ portc->endpoint_handle, UDI_USBXFER_ISO_WRITE,
+ portc->tmp_buf[pn], out_size)) < 0)
+ {
+ //cmn_err(CE_CONT, "oss usbaudio: Write transfer eror %d\n", err);
+ return err;
+ }
+
+ return 0;
+}
+
+static int
+feed_output (int dev, ossusb_devc * devc, ossusb_portc * portc)
+{
+ int pn, pos, len;
+ oss_native_word flags;
+ adev_p adev = audio_engines[dev];
+ dmap_p dmap = adev->dmap_out;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ if (portc->stopping)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+ }
+
+ pn = portc->curr_datapipe;
+ portc->curr_datapipe = (portc->curr_datapipe + 1) % NR_DATAPIPES;
+
+ pos = (int) (dmap->byte_counter % dmap->bytes_in_use);
+ len = portc->fragment_size;
+
+ portc->overflow_samples += portc->overflow_size;
+ if (portc->overflow_samples > 1000)
+ {
+ len += dmap->frame_size * (portc->overflow_samples / 1000);
+ portc->overflow_samples = portc->overflow_samples % 1000;
+ }
+
+ output_convert (devc, portc, dmap, dmap->dmabuf, pos, pn, len);
+ oss_audio_inc_byte_counter (dmap, len);
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+static void
+start_input (int dev, ossusb_devc * devc, ossusb_portc * portc)
+{
+ int frag, err;
+ oss_native_word flags;
+ adev_p adev = audio_engines[dev];
+ dmap_p dmap = adev->dmap_in;
+
+ if (portc->stopping)
+ return;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ frag = 0;
+
+ if ((err =
+ udi_usb_submit_request (portc->datapipe[0], rec_callback, portc,
+ portc->endpoint_handle, UDI_USBXFER_ISO_READ,
+ dmap->dmabuf + frag * portc->fragment_size,
+ portc->fragment_size)) < 0)
+ {
+ cmn_err (CE_WARN, "oss usbaudio: Read transfer error %d\n", err);
+ cmn_err (CE_CONT, "Endpoint %02x\n",
+ udi_endpoint_get_num (portc->endpoint_handle));
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+static void
+usbaudio_trigger (int dev, int state)
+{
+ ossusb_devc *devc = audio_engines[dev]->devc;
+ ossusb_portc *portc = audio_engines[dev]->portc;
+
+ if (devc->disabled)
+ return;
+
+ if (portc->open_mode & PCM_ENABLE_OUTPUT)
+ {
+ if ((portc->prepared_modes & PCM_ENABLE_OUTPUT)
+ && (state & PCM_ENABLE_OUTPUT))
+ {
+ portc->prepared_modes &= ~PCM_ENABLE_OUTPUT;
+ portc->curr_datapipe = 0;
+ portc->stopping = 0;
+
+ feed_output (dev, devc, portc);
+ feed_output (dev, devc, portc);
+ }
+ else if (!(state & PCM_ENABLE_OUTPUT))
+ {
+ portc->stopping = 1;
+#if 1
+ udi_usb_cancel_request (portc->datapipe[0]);
+ udi_usb_cancel_request (portc->datapipe[1]);
+#endif
+ portc->curr_datapipe = 0;
+ }
+ }
+
+ if (portc->open_mode & PCM_ENABLE_INPUT)
+ {
+ if ((portc->prepared_modes & PCM_ENABLE_INPUT)
+ && (state & PCM_ENABLE_INPUT))
+ {
+ portc->prepared_modes &= ~PCM_ENABLE_INPUT;
+ portc->stopping = 0;
+ start_input (dev, devc, portc);
+ }
+ else if (!(state & PCM_ENABLE_INPUT))
+ {
+ portc->stopping = 1;
+#if 0
+ udi_usb_cancel_request (portc->datapipe[0]);
+ udi_usb_cancel_request (portc->datapipe[1]);
+#endif
+ portc->curr_datapipe = 0;
+ }
+ }
+}
+
+static void
+usbaudio_reset (int dev)
+{
+ usbaudio_trigger (dev, 0);
+}
+
+/*ARGSUSED*/
+static int
+usbaudio_prepare_for_input (int dev, int bsize, int bcount)
+{
+ ossusb_devc *devc = audio_engines[dev]->devc;
+ ossusb_portc *portc = audio_engines[dev]->portc;
+ adev_p adev = audio_engines[dev];
+
+ if (devc->disabled)
+ return OSS_EPIPE;
+
+
+ if (adev->flags & ADEV_NOINPUT)
+ return OSS_ENOTSUP;
+
+ portc->stopping = 0;
+
+ if (write_control_value
+ (devc, portc->endpoint_handle, SAMPLING_FREQ_CONTROL, 3,
+ portc->speed) < 0)
+ {
+ cmn_err (CE_CONT, "Failed to set %d Hz sampling rate\n", portc->speed);
+ return OSS_EIO;
+ }
+
+ /*
+ * Handle fractional samples that don't fit in the 1ms period.
+ */
+ portc->overflow_size = portc->speed % 1000;
+ portc->overflow_samples = 0;
+
+ portc->prepared_modes |= PCM_ENABLE_INPUT;
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+usbaudio_prepare_for_output (int dev, int bsize, int bcount)
+{
+ ossusb_devc *devc = audio_engines[dev]->devc;
+ ossusb_portc *portc = audio_engines[dev]->portc;
+ adev_p adev = audio_engines[dev];
+
+ if (devc->disabled)
+ return OSS_EPIPE;
+
+ if (adev->flags & ADEV_NOOUTPUT)
+ return OSS_ENOTSUP;
+
+ portc->stopping = 0;
+
+ if (write_control_value
+ (devc, portc->endpoint_handle, SAMPLING_FREQ_CONTROL, 3,
+ portc->speed) < 0)
+ {
+ cmn_err (CE_CONT, "Failed to set %d Hz sampling rate\n", portc->speed);
+ return OSS_EIO;
+ }
+
+ /*
+ * Handle fractional samples that don't fit in the 1ms period.
+ */
+ portc->overflow_size = portc->speed % 1000;
+ portc->overflow_samples = 0;
+
+ portc->prepared_modes |= PCM_ENABLE_OUTPUT;
+ return 0;
+}
+
+static int
+usbaudio_check_input (int dev)
+{
+ ossusb_devc *devc = audio_engines[dev]->devc;
+ if (devc->disabled)
+ {
+ cmn_err (CE_CONT,
+ "oss usbaudio: Audio device %d removed from the system.\n",
+ dev);
+ return OSS_EPIPE;
+ }
+
+ cmn_err (CE_CONT, "oss usbaudio: Audio input timed out on device %d.\n",
+ dev);
+ return OSS_EIO;
+}
+
+static int
+usbaudio_check_output (int dev)
+{
+ ossusb_devc *devc = audio_engines[dev]->devc;
+ if (devc->disabled)
+ {
+ cmn_err (CE_CONT,
+ "oss usbaudio: Audio device %d removed from the system.\n",
+ dev);
+ return OSS_EPIPE;
+ }
+
+ cmn_err (CE_CONT, "oss usbaudio: Audio output timed out on device %d.\n",
+ dev);
+ return OSS_EIO;
+}
+
+static int
+usbaudio_local_qlen (int dev)
+{
+ ossusb_portc *portc = audio_engines[dev]->portc;
+ dmap_p dmap = audio_engines[dev]->dmap_out;
+ int delay = portc->pipeline_delay + 1; /* Pipeline delay in 1 msec ticks */
+
+ delay = delay * dmap->data_rate / 1000; /* Bytes/msec */
+
+ return delay;
+}
+
+static audiodrv_t usbaudio_driver = {
+ usbaudio_open,
+ usbaudio_close,
+ usbaudio_output_block,
+ usbaudio_start_input,
+ usbaudio_ioctl,
+ usbaudio_prepare_for_input,
+ usbaudio_prepare_for_output,
+ usbaudio_reset,
+ usbaudio_local_qlen,
+ NULL,
+ NULL,
+ NULL,
+ usbaudio_trigger,
+ usbaudio_set_rate,
+ usbaudio_set_format,
+ usbaudio_set_channels,
+ NULL,
+ NULL,
+ usbaudio_check_input,
+ usbaudio_check_output,
+ NULL, /* usbaudio_alloc_buffer */
+ NULL, /* usbaudio_free_buffer */
+ NULL,
+ NULL,
+ NULL /* usbaudio_get_buffer_pointer */
+};
+
+ossusb_devc *
+ossusb_init_audiostream (ossusb_devc * devc, udi_usb_devc * usbdev, int inum,
+ int reinit)
+{
+ int nsettings, actsetting = 0, desc_len;
+ unsigned char *desc, *d;
+ adev_p adev;
+ int i, p, l;
+ int portc_num;
+ void *endpoint_desc;
+
+ char dev_name[128];
+
+ int opts = ADEV_AUTOMODE;
+
+ ossusb_portc *portc;
+
+ if (devc->num_audio_engines >= MAX_PORTC)
+ {
+ cmn_err (CE_CONT, "usbaudio: Too many audio streaming interfaces\n");
+ return devc;
+ }
+
+ if (usbdev == NULL)
+ {
+ cmn_err (CE_CONT, "usbaudio: usbdev==NULL\n");
+ return devc;
+ }
+
+ nsettings = udi_usbdev_get_num_altsettings (usbdev);
+ desc = udi_usbdev_get_endpoint (usbdev, 1, 0, &l);
+ if (desc != NULL)
+ {
+ /* cmn_err(CE_CONT, "Endpoint: ");ossusb_dump_desc(desc, l); */
+ endpoint_desc = desc;
+ }
+ else
+ endpoint_desc = NULL;
+
+ if (reinit)
+ for (i = 0; i < devc->num_audio_engines; i++)
+ if (devc->portc[i].orig_endpoint_desc == endpoint_desc) /* Already registered this */
+ {
+ prepare_altsetting (devc, &devc->portc[i],
+ devc->portc[i].act_setting);
+ return devc;
+ }
+
+ portc = &devc->portc[devc->num_audio_engines];
+ portc_num = devc->num_audio_engines;
+ portc->if_number = inum;
+ portc->endpoint_desc = portc->orig_endpoint_desc = endpoint_desc;
+ portc->usbdev = usbdev;
+ portc->act_setting = -1; /* Set to an impossible value */
+ devc->num_audio_engines++;
+
+ memset (dev_name, 0, sizeof (dev_name));
+ strncpy (dev_name, devc->dev_name, sizeof (dev_name) - 1);
+ portc->num_settings = nsettings;
+
+#if 1
+ if (usb_trace > 2)
+ for (i = 0; i < nsettings; i++)
+ {
+ desc = udi_usbdev_get_altsetting (usbdev, i, &desc_len);
+ cmn_err (CE_CONT, "\nDumping altsetting %d (l=%d)\n", i, desc_len);
+ if (usb_trace)
+ ossusb_dump_desc (desc, desc_len);
+ }
+#endif
+
+ desc = udi_usbdev_get_altsetting (usbdev, actsetting, &desc_len);
+
+ if (desc == NULL || desc_len < 1)
+ for (i = 0; i < nsettings && (desc == NULL || desc_len < 1); i++)
+ {
+ UDB (cmn_err (CE_CONT, "Trying to read altsetting %d\n", i));
+ desc = udi_usbdev_get_altsetting (usbdev, i, &desc_len);
+ if (desc != NULL)
+ actsetting = i;
+ }
+
+ UDB (cmn_err (CE_CONT, "Altsetting %d, len %d\n", actsetting, desc_len));
+
+ if (desc == NULL)
+ {
+ cmn_err (CE_WARN, "Can't read interface descriptors\n");
+ return NULL;
+ }
+
+ if (usb_trace > 2)
+ ossusb_dump_desc (desc, desc_len);
+
+ p = 0;
+ while (p < desc_len)
+ {
+ d = desc + p;
+ l = *d;
+
+ if (d[1] != CS_INTERFACE)
+ {
+ UDB (cmn_err (CE_CONT, "Unknown descriptor type %02x\n", d[1]))}
+ else
+ switch (d[2])
+ {
+ case AS_GENERAL:
+ portc->terminal_link = d[3];
+ break;
+ }
+
+ p += l;
+ }
+
+ if (portc->terminal_link > 0 && portc->terminal_link <= devc->nunits)
+ {
+ char *s = dev_name + strlen (dev_name);
+
+ sprintf (s, " %s", devc->units[portc->terminal_link].name);
+ s += strlen (s);
+
+ if (devc->units[portc->terminal_link].typ == TY_OUTPUT) /* USB terminal type */
+ {
+ opts |= ADEV_NOOUTPUT;
+ }
+ else
+ {
+ opts |= ADEV_NOINPUT;
+ }
+ }
+
+ if ((portc->audio_dev = oss_install_audiodev (OSS_AUDIO_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ dev_name,
+ &usbaudio_driver,
+ sizeof (audiodrv_t),
+ opts,
+ AFMT_S16_NE, devc, -1)) < 0)
+ {
+ return devc;
+ }
+
+ portc->devc = devc;
+ adev = audio_engines[portc->audio_dev];
+ adev->portc = portc;
+ adev->mixer_dev = devc->mixer_dev;
+ adev->rate_source = devc->portc[0].audio_dev;
+ adev->max_block = 256;
+ adev->min_fragments = 4; /* vmix needs this */
+
+ prepare_altsetting (devc, portc, 1);
+
+ if (portc->num_settings > 2)
+ {
+ char name[128];
+
+ sprintf (name, "%s-altset", devc->units[portc->terminal_link].name);
+ ossusb_create_altset_control (devc->mixer_dev, portc_num,
+ portc->num_settings, name);
+ }
+
+#if 0
+ // TODO: This needs to be checked before vmix is enabled
+#ifdef CONFIG_OSS_VMIX
+ if (devc->units[portc->terminal_link].typ != TY_OUTPUT)
+ vmix_attach_audiodev(devc->osdev, portc->audio_dev, -1, 0);
+#endif
+#endif
+ return devc;
+}
+
+/*ARGSUSED*/
+int
+ossusb_change_altsetting (int dev, int ctrl, unsigned int cmd, int value)
+{
+ ossusb_devc *devc = mixer_devs[dev]->devc;
+ ossusb_portc *portc;
+
+ if (ctrl < 0 || ctrl >= devc->num_audio_engines)
+ return OSS_ENXIO;
+
+ portc = &devc->portc[ctrl];
+
+ if (cmd == SNDCTL_MIX_READ)
+ return portc->act_setting;
+
+ if (value >= portc->num_settings)
+ value = portc->num_settings - 1;
+
+ if (portc->act_setting != value)
+ {
+ prepare_altsetting (devc, portc, value);
+ }
+ return value;
+}
diff --git a/kernel/drv/oss_usb/ossusb_midi.c b/kernel/drv/oss_usb/ossusb_midi.c
new file mode 100644
index 0000000..f843594
--- /dev/null
+++ b/kernel/drv/oss_usb/ossusb_midi.c
@@ -0,0 +1,442 @@
+/*
+ * Purpose: USB MIDI streaming interface support
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This this source file is released under GPL v2 license (no other versions).
+ * See the COPYING file included in the main directory of this source
+ * distribution for the license terms and conditions.
+ *
+ */
+
+#include "oss_config.h"
+#include "ossusb.h"
+
+#define RECBUF_SIZE 32
+#define PLAYBUF_SIZE 32
+
+/*
+ * MS Class-Specific Interface Descriptor Subtypes
+ */
+#define MS_HEADER 0x01
+#define MIDI_IN_JACK 0x02
+#define MIDI_OUT_JACK 0x03
+#define ELEMENT 0x04
+
+/* Jack types */
+#define JT_EMBEDDED 0x01
+#define JT_EXTERNAL 0x02
+
+static int usb_midi_start_input (ossusb_devc * devc, ossusb_midic * midic);
+
+static void
+record_callback (udi_usb_request_t * request, void *arg)
+{
+ ossusb_midic *midic = arg;
+ ossusb_devc *devc = midic->devc;
+ int i, l;
+
+ l = udi_usb_request_actlen (request);
+ if (l == 0)
+ goto restart;
+
+ for (i = 0; i < l; i++)
+ cmn_err (CE_CONT, "%02x ", devc->recbuf[i]);
+ cmn_err (CE_CONT, "\n");
+
+restart:
+ usb_midi_start_input (devc, midic);
+}
+
+static int
+usb_midi_start_input (ossusb_devc * devc, ossusb_midic * midic)
+{
+ oss_native_word flags;
+ int err = 0;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ if ((err =
+ udi_usb_submit_request (devc->input_pipe, record_callback, midic,
+ midic->in_endpoint_handle,
+ UDI_USBXFER_BULK_READ, devc->recbuf,
+ RECBUF_SIZE)) < 0)
+ {
+ cmn_err (CE_WARN, "usbmidi: udi_usb_submit_request failed, err=%d\n",
+ err);
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return err;
+}
+
+static int usb_midi_start_output (ossusb_devc * devc, ossusb_midic * midic);
+
+ /*ARGSUSED*/ static void
+play_callback (udi_usb_request_t * request, void *arg)
+{
+ ossusb_midic *midic = arg;
+ ossusb_devc *devc = midic->devc;
+
+ devc->output_busy = 0;
+ usb_midi_start_output (devc, midic);
+}
+
+static int
+usb_midi_start_output (ossusb_devc * devc, ossusb_midic * midic)
+{
+ oss_native_word flags;
+ int err = 0, l = 0;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ l = devc->q_nbytes;
+ if (l > PLAYBUF_SIZE)
+ l = PLAYBUF_SIZE;
+
+ if (l == 0 || devc->output_busy)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+ }
+
+ memcpy (devc->playbuf, devc->queue, l);
+
+ if ((err =
+ udi_usb_submit_request (devc->output_pipe, play_callback, midic,
+ midic->out_endpoint_handle,
+ UDI_USBXFER_BULK_WRITE, devc->playbuf, l)) < 0)
+ {
+ cmn_err (CE_WARN, "usbmidi: udi_usb_submit_request() failed, err=%d\n",
+ err);
+ }
+ else
+ devc->output_busy = 1;
+
+ /* Remove the vbytes from the queue */
+ if (l >= devc->q_nbytes)
+ devc->q_nbytes = 0;
+ else
+ {
+ int n = devc->q_nbytes - l;
+ memcpy (devc->queue, devc->queue + l, n);
+ devc->q_nbytes -= l;
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return err;
+}
+
+static void
+usb_midi_close (int dev, int mode)
+{
+ oss_native_word flags;
+ ossusb_midic *midic;
+ ossusb_devc *devc;
+
+ midic = midi_devs[dev]->devc;
+ devc = midic->devc;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ midic->open_mode = 0;
+ midic->midi_input_intr = NULL;
+ midic->midi_output_intr = NULL;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ if (mode & OPEN_READ)
+ {
+ if (devc->input_pipe != NULL)
+ udi_usb_cancel_request (devc->input_pipe);
+ devc->input_pipe = NULL;
+
+ if (devc->recbuf != NULL)
+ CONTIG_FREE (devc->osdev, devc->recbuf, RECBUF_SIZE, devc->recbuf_dma_handle);
+ devc->recbuf = NULL;
+ if (devc->playbuf != NULL)
+ CONTIG_FREE (devc->osdev, devc->playbuf, PLAYBUF_SIZE, devc->playbuf_dma_handle);
+ devc->playbuf = NULL;
+ udi_close_endpoint (midic->in_endpoint_handle);
+ }
+
+ if (mode & OPEN_WRITE)
+ {
+ udi_usb_cancel_request (devc->output_pipe);
+ udi_close_endpoint (midic->out_endpoint_handle);
+ }
+}
+
+ /*ARGSUSED*/ static int
+usb_midi_open (int dev, int mode, oss_midi_inputbyte_t inputbyte,
+ oss_midi_inputbuf_t inputbuf, oss_midi_outputintr_t outputintr)
+{
+ oss_native_word flags, phaddr;
+ ossusb_midic *midic;
+ ossusb_devc *devc;
+
+ midic = midi_devs[dev]->devc;
+ devc = midic->devc;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (midic->open_mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ midic->open_mode = mode;
+ midic->midi_input_intr = inputbyte;
+ midic->midi_output_intr = outputintr;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ if (mode & OPEN_WRITE)
+ {
+ if ((midic->out_endpoint_handle =
+ udi_open_endpoint (midic->usbdev,
+ midic->out_endpoint_desc)) == NULL)
+ {
+ usb_midi_close (dev, mode);
+ cmn_err (CE_WARN, "Cannot open midi output pipe\n");
+ return OSS_ENOMEM;
+ }
+
+ if ((devc->output_pipe =
+ udi_usb_alloc_request (midic->usbdev, midic->out_endpoint_handle,
+ 1, UDI_USBXFER_BULK_WRITE)) == NULL)
+ {
+ cmn_err (CE_WARN, "usbmidi: Failed to allocate output pipe\n");
+ }
+
+ devc->playbuf =
+ CONTIG_MALLOC (devc->osdev, PLAYBUF_SIZE, MEMLIMIT_32BITS, &phaddr, devc->playbuf_dma_handle);
+
+ devc->output_busy = 0;
+ devc->q_nbytes = 0;
+ }
+
+ if (mode & OPEN_READ)
+ {
+ int err;
+
+ if ((midic->in_endpoint_handle =
+ udi_open_endpoint (midic->usbdev,
+ midic->in_endpoint_desc)) == NULL)
+ {
+ usb_midi_close (dev, mode);
+ cmn_err (CE_WARN, "Cannot open midi input pipe\n");
+ return OSS_ENOMEM;
+ }
+ if ((devc->input_pipe =
+ udi_usb_alloc_request (midic->usbdev, midic->in_endpoint_handle, 1,
+ UDI_USBXFER_BULK_READ)) == NULL)
+ {
+ cmn_err (CE_WARN, "usbmidi: Failed to allocate input pipe\n");
+ }
+ devc->recbuf =
+ CONTIG_MALLOC (devc->osdev, RECBUF_SIZE, MEMLIMIT_32BITS, &phaddr, devc->recbuf_dma_handle);
+
+ if ((err = usb_midi_start_input (devc, midic)) < 0)
+ {
+ cmn_err (CE_WARN, "usbmidi: Input error %d\n", err);
+ usb_midi_close (dev, mode);
+ return OSS_EIO;
+ }
+ }
+
+ return 0;
+}
+
+static int
+usb_midi_out (int dev, unsigned char data)
+{
+ ossusb_midic *midic = midi_devs[dev]->devc;
+ ossusb_devc *devc;
+ oss_native_word flags;
+ unsigned char *buf;
+
+ devc = midic->devc;
+
+ cmn_err (CE_CONT, "Send %02x\n", data);
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if ((devc->q_nbytes + 4) >= Q_MAX)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+ }
+
+ buf = devc->queue + devc->q_nbytes;
+
+ memset (buf, 0, 4);
+ buf[0] = 0x0f;
+ buf[1] = data;
+
+ devc->q_nbytes += 4;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ usb_midi_start_output (devc, midic);
+ return 1;
+}
+
+ /*ARGSUSED*/ static int
+usb_midi_ioctl (int dev, unsigned cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static midi_driver_t usb_midi_driver = {
+ usb_midi_open,
+ usb_midi_close,
+ usb_midi_ioctl,
+ usb_midi_out,
+};
+
+ /*ARGSUSED*/
+ ossusb_devc *
+ossusb_init_midistream (ossusb_devc * devc, udi_usb_devc * usbdev, int inum,
+ int reinit)
+{
+ int i, n;
+ int p, l;
+ char tmp[64];
+ unsigned char *in_endpoints[16], *out_endpoints[16];
+ void *in_endpoint_desc = NULL, *out_endpoint_desc = NULL;
+ int num_in_endpoints = 0, num_out_endpoints = 0;
+ int cin = 0, cout = 0;
+ ossusb_midic *midic;
+ unsigned char *desc, *d;
+ int desc_len;
+
+ for (i = 0; i < 32; i++)
+ if ((desc = udi_usbdev_get_endpoint (usbdev, 0, i, &desc_len)) != NULL)
+ {
+ unsigned char *ep;
+
+ if (desc_len > 100)
+ desc_len = 100;
+
+ cmn_err (CE_CONT, "Endpoint %d (%d)", i, desc_len);
+ ossusb_dump_desc (desc, desc_len);
+ ep = desc;
+
+ if (desc[2] & 0x80)
+ {
+ in_endpoints[num_in_endpoints++] = ep;
+ }
+ else
+ {
+ out_endpoints[num_out_endpoints++] = ep;
+ }
+ }
+
+ cmn_err (CE_CONT, "%d input endpoints: ", num_in_endpoints);
+ for (i = 0; i < num_in_endpoints; i++)
+ cmn_err (CE_CONT, "%02x ", in_endpoints[i][2]);
+ cmn_err (CE_CONT, "\n");
+ cmn_err (CE_CONT, "%d input endpoints: ", num_out_endpoints);
+ for (i = 0; i < num_out_endpoints; i++)
+ cmn_err (CE_CONT, "%02x ", out_endpoints[i][2]);
+ cmn_err (CE_CONT, "\n");
+
+ cmn_err (CE_CONT, "USB MIDI stream\n");
+ desc = udi_usbdev_get_altsetting (usbdev, 0, &desc_len);
+ if (desc == NULL || desc_len < 3)
+ {
+ cmn_err (CE_WARN, "usbmidi: bad altsetting\n");
+ return NULL;
+ }
+ // ossusb_dump_desc (desc, desc_len);
+ p = 0;
+ while (p < desc_len)
+ {
+ d = desc + p;
+
+ l = *d;
+ //if (usb_trace > 1)
+ {
+ cmn_err (CE_CONT, "MIDI streaming desc: ");
+ for (i = 0; i < l; i++)
+ cmn_err (CE_CONT, "%02x ", d[i]);
+ cmn_err (CE_CONT, "\n");
+ }
+
+ if (d[1] != CS_INTERFACE)
+ {
+ cmn_err (CE_WARN, "usbmidi: Unrecognized descriptor: \n");
+ ossusb_dump_desc (d, l);
+ p += l;
+ continue;
+ }
+
+ switch (d[2])
+ {
+ case MS_HEADER:
+ cmn_err (CE_CONT, "MS_HEADER: ");
+ cmn_err (CE_CONT, "v%x.%02x ", d[3], d[4]);
+ break;
+
+ case MIDI_IN_JACK:
+ cmn_err (CE_CONT, "MIDI_IN_JACK: ");
+ cmn_err (CE_CONT, "Type %d, ID %02x, iJack %d\n", d[3], d[4], d[5]);
+ in_endpoint_desc = in_endpoints[cin];
+ if (cin < num_in_endpoints - 1)
+ cin++;
+ break;
+
+ case MIDI_OUT_JACK:
+ cmn_err (CE_CONT, "MIDI_OUT_JACK: ");
+ cmn_err (CE_CONT, "Type %d, ID %02x, iJack %d\n", d[3], d[4], d[5]);
+ n = d[5];
+ cmn_err (CE_CONT, "\t%d inputs: ", n);
+ for (i = 0; i < n; i++)
+ cmn_err (CE_CONT, "%02x/%02x ", d[6 + i * 2], d[6 + i * 2 + 1]);
+ cmn_err (CE_CONT, "\n");
+ out_endpoint_desc = out_endpoints[cout];
+ if (cout < num_out_endpoints - 1)
+ cout++;
+ break;
+
+ case ELEMENT:
+ cmn_err (CE_CONT, "ELEMENT\n");
+ break;
+ }
+
+ p += l;
+ }
+
+
+#if 1
+ if (reinit)
+ for (i = 0; i < devc->num_mididevs; i++)
+ if (devc->midic[i].in_endpoint_desc == in_endpoint_desc) /* Already registered this */
+ if (devc->midic[i].out_endpoint_desc == out_endpoint_desc) /* Already registered this */
+ {
+ return devc;
+ }
+#endif
+
+ midic = &devc->midic[devc->num_mididevs];
+
+ devc->osdev = devc->osdev;
+ midic->devc = devc;
+ midic->usbdev = usbdev;
+ midic->in_endpoint_desc = in_endpoint_desc;
+ midic->out_endpoint_desc = out_endpoint_desc;
+
+ strcpy (tmp, devc->dev_name);
+
+ midic->midi_dev =
+ oss_install_mididev (OSS_MIDI_DRIVER_VERSION, "USBMIDI", tmp,
+ &usb_midi_driver, sizeof (midi_driver_t),
+ 0, midic, devc->osdev);
+ devc->num_mididevs++;
+
+ return devc;
+}
+
+ /*ARGSUSED*/ void
+ossusb_disconnect_midistream (ossusb_devc * devc)
+{
+}
diff --git a/kernel/drv/oss_usb/ossusb_midisport.c b/kernel/drv/oss_usb/ossusb_midisport.c
new file mode 100644
index 0000000..bbeee14
--- /dev/null
+++ b/kernel/drv/oss_usb/ossusb_midisport.c
@@ -0,0 +1,957 @@
+/*
+ * Purpose: Dedicated driver for M-Audio/Midiman MIDISPORT USB MIDI family
+ */
+
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This this source file is released under GPL v2 license (no other versions).
+ * See the COPYING file included in the main directory of this source
+ * distribution for the license terms and conditions.
+ *
+ */
+
+#include "oss_config.h"
+#include "midi_core.h"
+#include "ossusb.h"
+#include "midisport2x2_fw.h"
+#include "midisport1x1_fw.h"
+#include "oxygen8_fw.h"
+
+/*
+ * Audiosport Quattro also use the same packet protocol (no FW load).
+ * Out EP 2 is the output and in EP 1 is the input (check this).
+ */
+#define RECBUF_SIZE (10*4)
+#define DLBUF_SIZE 63
+#define MAX_PACK 32
+#define PLAYBUF_SIZE (MAX_PACK*4)
+#define QUEUE_ENTRIES 17
+#define QUEUE_SIZE (QUEUE_ENTRIES*PLAYBUF_SIZE)
+#define MAX_PORTS 9
+
+static int instance_num = 0;
+
+typedef struct midisport_devc midisport_devc;
+
+typedef unsigned char playbuf_t[PLAYBUF_SIZE];
+
+typedef struct
+{
+ oss_mutex_t mutex;
+ midisport_devc *devc;
+ int open_count;
+ int busy;
+ int max_out_blocks; /* Num of 4(3) byte blocks allowed in single message */
+
+ playbuf_t *playbuf; /* QUEUE_SIZE */
+ oss_dma_handle_t playbuf_dma_handle;
+ int playbuf_h, playbuf_t;
+
+ unsigned char *out_ep_desc;
+ udi_usb_request_t *output_pipe;
+ udi_endpoint_handle_t *output_endpoint_handle;
+} midisport_outqueue_t;
+
+typedef struct
+{
+ midisport_devc *devc;
+ oss_device_t *osdev;
+ oss_mutex_t mutex;
+
+ int portnum;
+ int midi_dev;
+ int open_mode;
+ oss_midi_inputbyte_t midi_input_intr;
+ playbuf_t output_buf;
+ int outbuf_p;
+
+ int outqueue_ix; /* Output queue 0 or 1 */
+ oss_midi_outputintr_t outputintr;
+} midisport_midic;
+
+static int alphabethic_numbering = 1;
+
+struct midisport_devc
+{
+ special_unload_t unload_func;
+ int is_dummy;
+ oss_device_t *osdev;
+ oss_mutex_t mutex;
+ ossusb_devc *usb_devc;
+ udi_usb_devc *usbdev;
+
+ int instance_num;
+
+ unsigned char *in_ep_desc;
+
+ int num_inputs, num_outputs;
+ int open_inputs;
+ midisport_midic in_midic[MAX_PORTS];
+ midisport_midic out_midic[MAX_PORTS];
+
+ unsigned char *recbuf;
+ oss_dma_handle_t recbuf_dma_handle;
+ udi_usb_request_t *input_pipe;
+ udi_endpoint_handle_t *input_endpoint_handle;
+
+ int num_queues;
+ midisport_outqueue_t out_queues[2];
+};
+
+static void
+load_firmware (midisport_devc * devc, const struct setup_request *setup,
+ char *name)
+{
+ int err;
+
+ if (setup == NULL)
+ {
+ cmn_err (CE_WARN, "midisport: No firmware available\n");
+ return;
+ }
+
+ while (setup->pData != NULL)
+ {
+#if 0
+ cmn_err (CE_CONT, "Load(%x, Rq=%x, Rqt=%x, Val=%x, Ix=%x, data=%x, len=%d\n", devc->usbdev, setup->bRequest, /* Request */
+ setup->bmRequestType, /* Rqtype */
+ setup->wValue, /* Value */
+ setup->wIndex, /* Index */
+ setup->pData, /* Data */
+ setup->wLength); /* Len */
+#endif
+
+ err = udi_usb_snd_control_msg (devc->usbdev, 0, /* Endpoint */
+ setup->bRequest, /* Request */
+ setup->bmRequestType, /* Rqtype */
+ setup->wValue, /* Value */
+ setup->wIndex, /* Index */
+ (void *) setup->pData, /* Data */
+ setup->wLength, /* Len */
+ OSS_HZ);
+ if (err < 0)
+ {
+ cmn_err (CE_WARN, "%s: Firmware download failed (%d)\n", name, err);
+ return;
+ }
+
+ setup++;
+ }
+}
+
+static void
+midisport_unload (void *d)
+{
+ midisport_devc *devc = d;
+
+ if (devc->is_dummy)
+ {
+ return;
+ }
+
+ MUTEX_CLEANUP (devc->mutex);
+}
+
+void *
+midisport_init (ossusb_devc * usb_devc)
+{
+ midisport_devc *devc;
+ unsigned int devid;
+ char *name = "Unknown device";
+ const struct setup_request *setup = NULL;
+
+ devid = (usb_devc->vendor << 16) | usb_devc->product;
+
+ switch (devid)
+ {
+ case 0x07631001:
+ name = "MIDISPORT 2x2";
+ setup = midisport2x2_setupRequest;
+ break;
+ case 0x07631014:
+ name = "Oxygen8";
+ setup = oxygen8_setupRequest;
+ break;
+ case 0x07631010:
+ name = "MIDISPORT 1x1";
+ setup = midisport1x1_setupRequest;
+ break;
+ }
+
+ cmn_err (CE_CONT, "%s firmware load started\n", name);
+
+ if ((devc = PMALLOC (usb_devc->osdev, sizeof (*devc))) == NULL)
+ {
+ cmn_err (CE_WARN, "midisport: Out of memory\n");
+ return NULL;
+ }
+
+ memset (devc, 0, sizeof (*devc));
+
+ devc->unload_func = midisport_unload;
+ devc->is_dummy = 1;
+ devc->osdev = usb_devc->osdev;
+ devc->usb_devc = usb_devc;
+ devc->usbdev = usb_devc->last_usbdev;
+
+ load_firmware (devc, setup, name);
+
+ cmn_err (CE_CONT, "%s firmware load completed\n", name);
+ return devc;
+}
+
+static int midisport_start_input (midisport_devc * devc);
+
+static void
+record_callback (udi_usb_request_t * request, void *arg)
+{
+ midisport_devc *devc = arg;
+ int i, l, p;
+ unsigned char *data;
+ data = udi_usb_request_actdata (request);
+
+ l = udi_usb_request_actlen (request);
+ if (l == 0)
+ goto restart;
+
+ for (p = 0; p < l - 3; p += 4)
+ {
+ unsigned char *buf, cmd;
+ int nbytes, src;
+ midisport_midic *midic;
+
+ buf = data + p;
+ cmd = buf[3];
+ nbytes = cmd & 0x0f;
+ src = (cmd >> 4) & 0x0f;
+
+ if (nbytes == 0) /* End of data */
+ break;
+
+ if (nbytes > 3 || src >= devc->num_inputs)
+ continue; /* No data or error */
+
+ midic = &devc->in_midic[src];
+
+ if (!(midic->open_mode & OPEN_READ) || midic->midi_input_intr == NULL)
+ continue; /* This device is not recording */
+
+ for (i = 0; i < nbytes; i++)
+ {
+ midic->midi_input_intr (midic->midi_dev, buf[i]);
+ }
+ }
+
+restart:
+ midisport_start_input (devc);
+}
+
+static int
+midisport_start_input (midisport_devc * devc)
+{
+ oss_native_word flags;
+ int err = 0;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ if ((err =
+ udi_usb_submit_request (devc->input_pipe, record_callback, devc,
+ devc->input_endpoint_handle,
+ UDI_USBXFER_INTR_READ, devc->recbuf,
+ RECBUF_SIZE)) < 0)
+ {
+ cmn_err (CE_WARN, "udi_usb_submit_request failed, err=%d\n", err);
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return err;
+}
+
+static void submit_output (midisport_devc * devc, midisport_outqueue_t * q);
+
+ /*ARGSUSED*/ static void
+play_callback (udi_usb_request_t * request, void *arg)
+{
+ midisport_outqueue_t *q = arg;
+ midisport_devc *devc = q->devc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (q->mutex, flags);
+ q->busy = 0;
+ submit_output (devc, q);
+ MUTEX_EXIT_IRQRESTORE (q->mutex, flags);
+}
+
+ /*ARGSUSED*/ static void
+submit_output (midisport_devc * devc, midisport_outqueue_t * q)
+{
+ int err;
+ int max_bytes;
+ unsigned char *qbuf;
+
+ if (q->busy)
+ return;
+
+ if (q->playbuf_h == q->playbuf_t) /* Queue empty */
+ return;
+
+ qbuf = q->playbuf[q->playbuf_h];
+ max_bytes = q->max_out_blocks * 4;
+
+ q->playbuf_h = (q->playbuf_h + 1) % QUEUE_ENTRIES;
+ q->busy = 1;
+
+ if ((err =
+ udi_usb_submit_request (q->output_pipe, play_callback, q,
+ q->output_endpoint_handle,
+ UDI_USBXFER_BULK_WRITE, qbuf, max_bytes)) < 0)
+ {
+ cmn_err (CE_WARN, "udi_usb_submit_request (play) failed, err=%d\n",
+ err);
+ }
+}
+
+ /*ARGSUSED*/ static void
+midisport_close_input (int dev, int mode)
+{
+ oss_native_word flags;
+ midisport_midic *midic;
+ midisport_devc *devc;
+ int do_stop = 0;
+
+ midic = midi_devs[dev]->devc;
+ devc = midic->devc;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ devc->open_inputs--;
+ if (devc->open_inputs == 0)
+ do_stop = 1;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ if (do_stop)
+ {
+ udi_usb_free_request (devc->input_pipe);
+ udi_close_endpoint (devc->input_endpoint_handle);
+ if (devc->recbuf != NULL)
+ CONTIG_FREE (midic->osdev, devc->recbuf, RECBUF_SIZE, devc->recbuf_dma_handle);
+ }
+
+ MUTEX_ENTER_IRQDISABLE (midic->mutex, flags);
+ midic->open_mode = 0;
+ midic->midi_input_intr = NULL;
+ MUTEX_EXIT_IRQRESTORE (midic->mutex, flags);
+}
+
+ /*ARGSUSED*/ static int
+midisport_open_input (int dev, int mode, oss_midi_inputbyte_t inputbyte,
+ oss_midi_inputbuf_t inputbuf,
+ oss_midi_outputintr_t outputintr)
+{
+ oss_native_word flags;
+ midisport_midic *midic;
+ midisport_devc *devc;
+ oss_native_word phaddr;
+ int do_start = 0;
+
+ midic = midi_devs[dev]->devc;
+ devc = midic->devc;
+
+ MUTEX_ENTER_IRQDISABLE (midic->mutex, flags);
+ if (midic->open_mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (midic->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ midic->open_mode = mode;
+ midic->midi_input_intr = inputbyte;
+ MUTEX_EXIT_IRQRESTORE (midic->mutex, flags);
+
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ devc->open_inputs++;
+ if (devc->open_inputs == 1)
+ do_start = 1;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ if (do_start)
+ {
+ int err;
+
+ devc->recbuf =
+ CONTIG_MALLOC (devc->osdev, RECBUF_SIZE, MEMLIMIT_32BITS, &phaddr, devc->recbuf_dma_handle);
+ if (devc->recbuf == NULL)
+ {
+ cmn_err (CE_CONT, "Failed to allocate the recording buffer\n");
+ return OSS_ENOMEM;
+ }
+
+ if ((devc->input_endpoint_handle =
+ udi_open_endpoint (devc->usbdev, devc->in_ep_desc)) == NULL)
+ {
+ midic->open_mode = 0;
+ midic->midi_input_intr = NULL;
+ cmn_err (CE_WARN, "Cannot open audio pipe\n");
+ return OSS_ENOMEM;
+ }
+ if ((devc->input_pipe =
+ udi_usb_alloc_request (devc->usbdev, devc->input_endpoint_handle,
+ 1, UDI_USBXFER_INTR_READ)) == NULL)
+ {
+ return OSS_EIO;
+ }
+
+ if ((err = midisport_start_input (devc)) < 0)
+ {
+ cmn_err (CE_WARN, "midisport: Input error %d\n", err);
+ midisport_close_input (dev, mode);
+ return OSS_EIO;
+ }
+ }
+
+ return 0;
+}
+
+static int
+open_output_queue (midisport_devc * devc, int queue_ix)
+{
+ oss_native_word flags;
+ midisport_outqueue_t *q;
+ int open_count;
+ oss_native_word phaddr;
+
+ if (queue_ix < 0 || queue_ix >= devc->num_queues)
+ {
+ cmn_err (CE_WARN, "Bad output queue index %d\n", queue_ix);
+ return OSS_EIO;
+ }
+
+ q = &devc->out_queues[queue_ix];
+
+ MUTEX_ENTER_IRQDISABLE (q->mutex, flags);
+ open_count = q->open_count++;
+
+ if (open_count == 0) /* First open */
+ {
+ q->playbuf_h = q->playbuf_t = 0;
+ q->busy = 0;
+ }
+ MUTEX_EXIT_IRQRESTORE (q->mutex, flags);
+
+ if (open_count == 0) /* First open */
+ {
+ if ((q->playbuf =
+ CONTIG_MALLOC (devc->osdev, QUEUE_SIZE, MEMLIMIT_32BITS,
+ &phaddr, q->playbuf_dma_handle)) == NULL)
+ {
+ cmn_err (CE_WARN, "Failed to allocate output buffer (%d bytes)\n",
+ QUEUE_SIZE);
+ q->open_count--;
+ return OSS_ENOMEM;
+ }
+
+ if ((q->output_endpoint_handle =
+ udi_open_endpoint (devc->usbdev, q->out_ep_desc)) == NULL)
+ {
+ cmn_err (CE_WARN, "Failed to open output endpoint\n");
+ q->open_count--;
+ return OSS_EIO;
+ }
+
+ if ((q->output_pipe =
+ udi_usb_alloc_request (devc->usbdev, q->output_endpoint_handle, 1,
+ UDI_USBXFER_BULK_WRITE)) == NULL)
+ {
+ cmn_err (CE_WARN, "Failed to allocate output request\n");
+ q->open_count--;
+ return OSS_EIO;
+ }
+
+ }
+ return 0;
+}
+
+static void
+close_output_queue (midisport_devc * devc, int queue_ix)
+{
+ oss_native_word flags;
+ midisport_outqueue_t *q;
+ int open_count;
+
+ if (queue_ix < 0 || queue_ix >= devc->num_queues)
+ {
+ cmn_err (CE_WARN, "Bad output queue index %d\n", queue_ix);
+ return;
+ }
+
+ q = &devc->out_queues[queue_ix];
+
+ if (q->open_count <= 0) /* Was not opened at all */
+ return;
+
+ MUTEX_ENTER_IRQDISABLE (q->mutex, flags);
+ open_count = q->open_count--;
+ MUTEX_EXIT_IRQRESTORE (q->mutex, flags);
+
+ if (open_count <= 1) /* Queue not needed any more */
+ {
+ udi_usb_free_request (q->output_pipe);
+ udi_close_endpoint (q->output_endpoint_handle);
+ if (q->playbuf != NULL)
+ CONTIG_FREE (devc->osdev, q->playbuf, QUEUE_SIZE, q->playbuf_dma_handle);
+ }
+}
+
+ /*ARGSUSED*/ static void
+midisport_close_output (int dev, int mode)
+{
+ oss_native_word flags;
+ midisport_midic *midic;
+ midisport_devc *devc;
+
+ midic = midi_devs[dev]->devc;
+ devc = midic->devc;
+
+ close_output_queue (devc, midic->outqueue_ix);
+
+ MUTEX_ENTER_IRQDISABLE (midic->mutex, flags);
+ midic->open_mode = 0;
+ midic->outputintr = NULL;
+ MUTEX_EXIT_IRQRESTORE (midic->mutex, flags);
+}
+
+ /*ARGSUSED*/ static int
+midisport_open_output (int dev, int mode, oss_midi_inputbyte_t inputbyte,
+ oss_midi_inputbuf_t inputbuf,
+ oss_midi_outputintr_t outputintr)
+{
+ oss_native_word flags;
+ midisport_midic *midic;
+ midisport_devc *devc;
+ int err;
+
+ midic = midi_devs[dev]->devc;
+ devc = midic->devc;
+
+ MUTEX_ENTER_IRQDISABLE (midic->mutex, flags);
+ if (midic->open_mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (midic->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ midic->open_mode = mode;
+ midic->midi_input_intr = NULL, midic->outputintr = outputintr;
+ midic->outbuf_p = 0;
+ memset (midic->output_buf, 0, sizeof (midic->output_buf));
+ MUTEX_EXIT_IRQRESTORE (midic->mutex, flags);
+
+ if ((err = open_output_queue (devc, midic->outqueue_ix)) < 0)
+ {
+ cmn_err (CE_WARN, "Failed to open the output queue (%d)\n", err);
+ midisport_close_output (dev, mode);
+ return err;
+ }
+
+ return 0;
+}
+
+static int
+do_flush (midisport_devc * devc, midisport_midic * midic,
+ midisport_outqueue_t * q)
+{
+ int next;
+ unsigned char *qbuf;
+ int max_bytes;
+
+ /*
+ * Move stuff from the intermediate buffer to the EP queue
+ */
+ max_bytes = q->max_out_blocks * 4;
+ next = (q->playbuf_t + 1) % QUEUE_ENTRIES;
+ if (next == q->playbuf_h) /* No more space in any of the buffers */
+ {
+ return 0;
+ }
+
+ qbuf = q->playbuf[q->playbuf_t];
+ memcpy (qbuf, midic->output_buf, max_bytes);
+ memset (midic->output_buf, 0, max_bytes);
+ midic->outbuf_p = 0;
+ q->playbuf_t = next;
+
+ submit_output (devc, q);
+
+ return 1;
+}
+
+#if 0
+static void
+midisport_flush_output (int dev)
+{
+ midisport_midic *midic = midi_devs[dev]->devc;
+ midisport_devc *devc = midic->devc;
+ midisport_outqueue_t *q;
+ oss_native_word flags;
+ oss_native_word qflags;
+
+ q = &devc->out_queues[midic->outqueue_ix];
+
+ MUTEX_ENTER_IRQDISABLE (midic->mutex, flags);
+ MUTEX_ENTER_IRQDISABLE (q->mutex, qflags);
+ do_flush (devc, midic, q);
+ MUTEX_EXIT_IRQRESTORE (q->mutex, qflags);
+ MUTEX_EXIT_IRQRESTORE (midic->mutex, flags);
+}
+#endif
+
+static int
+midisport_bulk_write (int dev, unsigned char *buf, int len)
+{
+ midisport_midic *midic = midi_devs[dev]->devc;
+ midisport_devc *devc = midic->devc;
+ oss_native_word flags;
+ oss_native_word qflags;
+ int i, l = 0, n = 0, p;
+ //int max_bytes;
+ midisport_outqueue_t *q;
+ unsigned char *outbuf;
+
+ if (midic->outqueue_ix < 0 || midic->outqueue_ix >= devc->num_queues)
+ {
+ cmn_err (CE_WARN, "Bad output queue index %d\n", midic->outqueue_ix);
+ return OSS_EIO;
+ }
+
+ q = &devc->out_queues[midic->outqueue_ix];
+
+ MUTEX_ENTER_IRQDISABLE (midic->mutex, flags);
+
+ //max_bytes = q->max_out_blocks * 4;
+
+ for (i = 0; i < len; i += 3)
+ {
+ l = len - i;
+ if (l > 3)
+ l = 3;
+ p = midic->outbuf_p;
+
+ if ((p + 4) >= q->max_out_blocks)
+ {
+ int next;
+ MUTEX_ENTER_IRQDISABLE (q->mutex, qflags);
+
+ next = (q->playbuf_t + 1) % QUEUE_ENTRIES;
+ if (next == q->playbuf_h) /* No more space in any of the buffers */
+ {
+ MUTEX_EXIT_IRQRESTORE (q->mutex, qflags);
+ MUTEX_EXIT_IRQRESTORE (midic->mutex, flags);
+ return n;
+ }
+
+ if (!do_flush (devc, midic, q)) /* Output FIFO full */
+ {
+ MUTEX_EXIT_IRQRESTORE (q->mutex, qflags);
+ return n;
+ }
+ p = midic->outbuf_p;
+ MUTEX_EXIT_IRQRESTORE (q->mutex, qflags);
+ }
+
+ outbuf = midic->output_buf + p;
+ memcpy (outbuf, buf, l);
+ outbuf[3] = (midic->portnum << 4) | l;
+ midic->outbuf_p += 4;
+ if (midic->outbuf_p >= q->max_out_blocks)
+ do_flush (devc, midic, q);
+ n += l;
+ }
+
+ MUTEX_EXIT_IRQRESTORE (midic->mutex, flags);
+
+ return n;
+}
+
+ /*ARGSUSED*/ static int
+midisport_ioctl (int dev, unsigned cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static midi_driver_t midisport_midi_input_driver = {
+ midisport_open_input,
+ midisport_close_input,
+ midisport_ioctl
+};
+
+static midi_driver_t midisport_midi_output_driver = {
+ midisport_open_output,
+ midisport_close_output,
+ midisport_ioctl,
+ NULL,
+ midisport_bulk_write,
+ 8 * 3 /* 8 packets of 3 bytes */
+};
+
+static void
+create_inputs (midisport_devc * devc, char *name, int ep, int ninputs)
+{
+ int desc_len;
+ int i, ix = ep;
+ char portid = 'A';
+ unsigned char *desc;
+ int flags = MFLAG_INPUT;
+
+ for (i = 0; i < 32; i++)
+ if ((desc =
+ udi_usbdev_get_endpoint (devc->usbdev, 0, i, &desc_len)) != NULL)
+ {
+ if (desc[2] == (ep | 0x80))
+ ix = i;
+ }
+
+ if (!alphabethic_numbering)
+ portid = '1';
+
+ if (ninputs > MAX_PORTS)
+ {
+ cmn_err (CE_WARN, "Too many input ports %d\n", ninputs);
+ return;
+ }
+
+ if ((devc->in_ep_desc =
+ udi_usbdev_get_endpoint (devc->usbdev, 0, ix, &desc_len)) == NULL)
+ {
+ cmn_err (CE_WARN, "Bad endpoint %d\n", ep);
+ return;
+ }
+
+ if (!(devc->in_ep_desc[2] & 0x80))
+ {
+ cmn_err (CE_WARN, "Bad endpoint %d - not input\n", ep);
+ }
+
+ for (i = 0; i < ninputs; i++)
+ {
+ midisport_midic *midic = midic = &devc->in_midic[i];
+ char tmp[128];
+
+ midic->devc = devc;
+ midic->osdev = devc->osdev;
+ MUTEX_INIT (devc->osdev, midic->mutex, MH_DRV + 1);
+ midic->portnum = i;
+ devc->num_inputs++;
+
+ if (i == 8)
+ {
+ sprintf (tmp, "%s SMPTE status", name);
+ flags = MFLAG_MTC;
+ }
+ else
+ sprintf (tmp, "%s input %c", name, portid + i);
+
+ midic->midi_dev =
+ oss_install_mididev (OSS_MIDI_DRIVER_VERSION, "MIDISPORT", tmp,
+ &midisport_midi_input_driver,
+ sizeof (midi_driver_t),
+ flags, midic, midic->osdev);
+ }
+}
+
+static void
+create_output (midisport_devc * devc, char *name, int queue_ix)
+{
+ int n;
+ midisport_midic *midic = NULL;
+ char tmp[128];
+ char portid = 'A';
+ int flags = MFLAG_OUTPUT;
+
+ if (!alphabethic_numbering)
+ portid = '1';
+
+ n = devc->num_outputs++;
+ midic = &devc->out_midic[n];
+ midic->devc = devc;
+ MUTEX_INIT (devc->osdev, midic->mutex, MH_DRV + 1);
+ midic->osdev = devc->osdev;
+ midic->portnum = n;
+ midic->outqueue_ix = queue_ix;
+
+ if (n == 8)
+ {
+ sprintf (tmp, "%s SMPTE control", name);
+ flags = MFLAG_MTC;
+ }
+ else
+ sprintf (tmp, "%s output %c", name, portid + n);
+
+ midic->midi_dev =
+ oss_install_mididev (OSS_MIDI_DRIVER_VERSION, "MIDISPORT", tmp,
+ &midisport_midi_output_driver,
+ sizeof (midi_driver_t),
+ flags, midic, midic->osdev);
+}
+
+static void
+init_outqueue (midisport_devc * devc, int ix, int ep, int max_blocks)
+{
+ int desc_len;
+ midisport_outqueue_t *q;
+ int i, epix = ep;
+
+ unsigned char *desc;
+
+ for (i = 0; i < 32; i++)
+ if ((desc =
+ udi_usbdev_get_endpoint (devc->usbdev, 0, i, &desc_len)) != NULL)
+ {
+ if (desc[2] == ep)
+ epix = i;
+ }
+
+ if (ix < 0 || ix > devc->num_queues)
+ {
+ cmn_err (CE_WARN, "Endpoint index outside bounds\n");
+ return;
+ }
+
+ q = &devc->out_queues[ix];
+ MUTEX_INIT (devc->osdev, q->mutex, MH_DRV + 2);
+ q->max_out_blocks = max_blocks;
+ q->devc = devc;
+
+ if ((q->out_ep_desc =
+ udi_usbdev_get_endpoint (devc->usbdev, 0, epix, &desc_len)) == NULL)
+ {
+ cmn_err (CE_WARN, "Bad endpoint %d\n", ep);
+ return;
+ }
+
+ if (q->out_ep_desc[2] & 0x80)
+ {
+ cmn_err (CE_WARN, "Bad endpoint %d - not output\n", ep);
+ }
+ cmn_err (CE_CONT, "Attaching output endpoint %d=%02x\n", ep,
+ q->out_ep_desc[2]);
+}
+
+void *
+midisport_driver (ossusb_devc * usb_devc)
+{
+ midisport_devc *devc;
+ char *name;
+ unsigned int devid;
+ int i;
+ unsigned char *desc;
+ int desc_len;
+
+ devid = (usb_devc->vendor << 16) | usb_devc->product;
+
+ if ((devc = PMALLOC (usb_devc->osdev, sizeof (*devc))) == NULL)
+ {
+ cmn_err (CE_WARN, "midisport: Out of memory\n");
+ return NULL;
+ }
+
+ memset (devc, 0, sizeof (*devc));
+
+ devc->unload_func = midisport_unload;
+ devc->osdev = usb_devc->osdev;
+ MUTEX_INIT (devc->osdev, devc->mutex, MH_DRV);
+
+ devc->usb_devc = usb_devc;
+ devc->usbdev = usb_devc->last_usbdev;
+ devc->instance_num = instance_num++;
+
+ for (i = 0; i < 32; i++)
+ if ((desc =
+ udi_usbdev_get_endpoint (devc->usbdev, 0, i, &desc_len)) != NULL)
+ {
+ if (desc[2] & 0x80)
+ {
+ cmn_err (CE_CONT, "Input endpoint %02x\n", desc[2]);
+ }
+ else
+ {
+ cmn_err (CE_CONT, "Output endpoint %02x\n", desc[2]);
+ }
+ }
+
+ alphabethic_numbering = 1;
+
+ devc->num_queues = 2;
+
+ switch (devid)
+ {
+ case 0x07631002:
+ name = "Midisport 2x2";
+ create_inputs (devc, name, 1, 2);
+ init_outqueue (devc, 0, 2, 8);
+ init_outqueue (devc, 1, 4, 8);
+ create_output (devc, name, 0);
+ create_output (devc, name, 1);
+ break;
+
+ case 0x07631011:
+ name = "Midisport 1x1";
+ devc->num_queues = 1;
+ init_outqueue (devc, 0, 2, 8);
+ create_inputs (devc, name, 1, 1);
+ create_output (devc, name, 0);
+ break;
+
+ case 0x07631015:
+ name = "Oxygen8";
+ devc->num_queues = 1;
+ create_inputs (devc, name, 1, 1);
+ init_outqueue (devc, 0, 2, 8);
+ create_output (devc, name, 0);
+ break;
+
+ case 0x07632001:
+ name = "Quattro";
+ devc->num_queues = 1;
+ create_inputs (devc, name, 1, 1);
+ init_outqueue (devc, 0, 2, 8);
+ create_output (devc, name, 0);
+ break;
+
+ case 0x07631031:
+ name = "Midisport 8x8";
+ alphabethic_numbering = 0;
+ create_inputs (devc, name, 2, 9);
+ init_outqueue (devc, 0, 2, 10);
+ init_outqueue (devc, 1, 4, 8);
+ create_output (devc, name, 0);
+ create_output (devc, name, 1);
+ create_output (devc, name, 0);
+ create_output (devc, name, 1);
+ create_output (devc, name, 0);
+ create_output (devc, name, 1);
+ create_output (devc, name, 0);
+ create_output (devc, name, 1);
+ create_output (devc, name, 0); /* SMPTE control */
+ break;
+
+ case 0x07631021:
+ name = "Midisport 4x4";
+ create_inputs (devc, name, 2, 4);
+ init_outqueue (devc, 0, 2, 16);
+ init_outqueue (devc, 1, 4, 16);
+ create_output (devc, name, 0);
+ create_output (devc, name, 1);
+ create_output (devc, name, 0);
+ create_output (devc, name, 1);
+ break;
+
+ default:
+ cmn_err (CE_WARN, "Unrecognized MIDI device %08x\n", devid);
+ }
+
+ return devc;
+}
diff --git a/kernel/drv/oss_usb/ossusb_ymhmidi.c b/kernel/drv/oss_usb/ossusb_ymhmidi.c
new file mode 100644
index 0000000..89f749b
--- /dev/null
+++ b/kernel/drv/oss_usb/ossusb_ymhmidi.c
@@ -0,0 +1,653 @@
+/*
+ * Purpose: Dedicated driver for Yamaha USB MIDI devices
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This this source file is released under GPL v2 license (no other versions).
+ * See the COPYING file included in the main directory of this source
+ * distribution for the license terms and conditions.
+ *
+ */
+
+#include "oss_config.h"
+#include "midi_core.h"
+#include "ossusb.h"
+#include "midiparser.h"
+
+typedef struct ymhusb_devc ymhusb_devc;
+
+#define MAX_INDEVS 1
+#define MAX_OUTDEVS 1
+#define TMPBUF_SIZE 64
+#define TMPBUF_NSLOTS 24
+
+typedef unsigned char tmpbuf_slot_t[TMPBUF_SIZE];
+#define OUTBUF_SIZE (TMPBUF_NSLOTS*TMPBUF_SIZE)
+
+typedef struct
+{
+ ymhusb_devc *devc;
+ oss_device_t *osdev;
+ udi_usb_devc *usbdev;
+ oss_mutex_t mutex;
+
+ int portnum;
+ int midi_dev;
+ int open_mode;
+
+ void *endpoint_desc;
+ udi_endpoint_handle_t *endpoint_handle;
+ udi_usb_request_t *datapipe;
+
+ oss_midi_inputbyte_t midi_input_intr;
+ unsigned char *tmpbuf;
+ oss_dma_handle_t tmpbuf_dma_handle;
+ int tmp_len;
+ midiparser_common_p parser;
+
+ volatile int output_busy;
+
+ /* Output buffer */
+ tmpbuf_slot_t *outbuf;
+ oss_dma_handle_t outbuf_dma_handle;
+ int buf_t, buf_h;
+} ymhusb_midic;
+
+struct ymhusb_devc
+{
+ special_unload_t unload_func;
+
+ oss_device_t *osdev;
+ udi_usb_devc *usbdev;
+
+ oss_mutex_t mutex;
+
+ int n_inputs, n_outputs;
+ ymhusb_midic indevs[MAX_INDEVS], outdevs[MAX_OUTDEVS];
+};
+
+static void
+ymhusb_unload (void *d)
+{
+ ymhusb_devc *devc = (ymhusb_devc *) d;
+ int i;
+
+ for (i = 0; i < devc->n_inputs; i++)
+ {
+ MUTEX_CLEANUP (devc->indevs[i].mutex);
+ }
+ for (i = 0; i < devc->n_outputs; i++)
+ {
+ MUTEX_CLEANUP (devc->outdevs[i].mutex);
+ }
+ MUTEX_CLEANUP (devc->mutex);
+}
+
+static int ymhmidi_start_input (ymhusb_devc * devc, ymhusb_midic * midic);
+
+void
+ymhmidi_record_callback (udi_usb_request_t * request, void *arg)
+{
+ ymhusb_midic *midic = arg;
+ ymhusb_devc *devc = midic->devc;
+ unsigned char *data;
+ int l;
+
+ l = udi_usb_request_actlen (request);
+ data = udi_usb_request_actdata (request);
+
+ if (l == 0)
+ goto restart;
+
+ if (midi_devs[midic->midi_dev]->event_input != NULL)
+ midi_devs[midic->midi_dev]->event_input (midic->midi_dev, data, l);
+
+restart:
+ if (midic->open_mode & OPEN_READ)
+ ymhmidi_start_input (devc, midic);
+}
+
+static int ymhmidi_submit_output (ymhusb_devc * devc, ymhusb_midic * midic);
+
+ /*ARGSUSED*/ void
+ymhmidi_play_callback (udi_usb_request_t * request, void *arg)
+{
+ ymhusb_midic *midic = arg;
+ ymhusb_devc *devc = midic->devc;
+
+ midic->output_busy = 0;
+ ymhmidi_submit_output (devc, midic);
+}
+
+ /*ARGSUSED*/ static int
+ymhmidi_start_input (ymhusb_devc * devc, ymhusb_midic * midic)
+{
+ int err;
+
+ if ((err =
+ udi_usb_submit_request (midic->datapipe, ymhmidi_record_callback,
+ midic, midic->endpoint_handle,
+ UDI_USBXFER_BULK_READ, midic->tmpbuf,
+ TMPBUF_SIZE)) < 0)
+ {
+ return err;
+ }
+
+ return 0;
+}
+
+ /*ARGSUSED*/ static int
+ymhmidi_submit_output (ymhusb_devc * devc, ymhusb_midic * midic)
+{
+ int err;
+ int n = midic->buf_t;
+
+ if (midic->buf_h == midic->buf_t)
+ return 0;
+
+ if ((err =
+ udi_usb_submit_request (midic->datapipe, ymhmidi_play_callback, midic,
+ midic->endpoint_handle, UDI_USBXFER_BULK_WRITE,
+ midic->outbuf[n], TMPBUF_SIZE)) < 0)
+ {
+ cmn_err (CE_WARN, "Submit USB MIDI request failed\n");
+ return err;
+ }
+
+ midic->buf_t = (n + 1) % TMPBUF_NSLOTS;;
+ midic->output_busy = 1;
+
+ return 0;
+}
+
+static int
+ymhmidi_put_output (ymhusb_devc * devc, ymhusb_midic * midic)
+{
+ int n = midic->buf_h;
+
+ midic->buf_h = (n + 1) % TMPBUF_NSLOTS;
+
+ memcpy (midic->outbuf[n], midic->tmpbuf, TMPBUF_SIZE);
+ midic->tmp_len = 0;
+ memset (midic->tmpbuf, 0, TMPBUF_SIZE);
+
+ if (midic->output_busy)
+ return 0;
+
+ ymhmidi_submit_output (devc, midic);
+
+ return 0;
+}
+
+ /*ARGSUSED*/ static void
+ymhusb_close_input (int dev, int mode)
+{
+ oss_native_word flags;
+ ymhusb_midic *midic;
+
+ midic = midi_devs[dev]->devc;
+
+ MUTEX_ENTER_IRQDISABLE (midic->mutex, flags);
+ midic->open_mode = 0;
+ midic->midi_input_intr = NULL;
+ udi_usb_free_request (midic->datapipe);
+ udi_close_endpoint (midic->endpoint_handle);
+ if (midic->tmpbuf != NULL)
+ CONTIG_FREE (midic->osdev, midic->tmpbuf, TMPBUF_SIZE, midic->tmpbuf_dma_handle);
+ MUTEX_EXIT_IRQRESTORE (midic->mutex, flags);
+}
+
+ /*ARGSUSED*/ static int
+ymhusb_open_input (int dev, int mode, oss_midi_inputbyte_t inputbyte,
+ oss_midi_inputbuf_t inputbuf,
+ oss_midi_outputintr_t outputintr)
+{
+ oss_native_word flags, phaddr;
+ ymhusb_midic *midic;
+ ymhusb_devc *devc;
+
+ midic = midi_devs[dev]->devc;
+ devc = midic->devc;
+
+ MUTEX_ENTER_IRQDISABLE (midic->mutex, flags);
+ if (midic->open_mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (midic->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ midic->open_mode = mode;
+ midic->midi_input_intr = inputbyte;
+ MUTEX_EXIT_IRQRESTORE (midic->mutex, flags);
+
+ midic->tmpbuf =
+ CONTIG_MALLOC (midic->osdev, TMPBUF_SIZE, MEMLIMIT_32BITS, &phaddr, midic->tmpbuf_dma_handle);
+ memset (midic->tmpbuf, 0, TMPBUF_SIZE);
+
+ if ((midic->endpoint_handle =
+ udi_open_endpoint (midic->usbdev, midic->endpoint_desc)) == NULL)
+ {
+ midic->open_mode = 0;
+ midic->midi_input_intr = NULL;
+ cmn_err (CE_WARN, "Cannot open audio pipe\n");
+ return OSS_ENOMEM;
+ }
+ if ((midic->datapipe =
+ udi_usb_alloc_request (midic->usbdev, midic->endpoint_handle, 1,
+ UDI_USBXFER_BULK_READ)) == NULL)
+ {
+ return OSS_EIO;
+ }
+
+ return ymhmidi_start_input (devc, midic);
+}
+
+static void
+ymhusb_flush_output (int dev)
+{
+ oss_native_word flags;
+ ymhusb_midic *midic;
+ ymhusb_devc *devc;
+ int next;
+
+ midic = midi_devs[dev]->devc;
+ devc = midic->devc;
+
+ if (midic->tmp_len == 0)
+ return;
+ next = (midic->buf_t + 1) % TMPBUF_NSLOTS;
+ if (next == midic->buf_h) /* Buffer full */
+ return;
+
+ MUTEX_ENTER_IRQDISABLE (midic->mutex, flags);
+ ymhmidi_put_output (devc, midic);
+ MUTEX_EXIT_IRQRESTORE (midic->mutex, flags);
+}
+
+static int
+ymhusb_wait_output (int dev)
+{
+ ymhusb_midic *midic;
+
+ ymhusb_flush_output (dev);
+
+ midic = midi_devs[dev]->devc;
+
+ if (midic->output_busy)
+ return 1;
+
+ if (midic->buf_t == midic->buf_h)
+ return 0; /* Not busy */
+
+ return 1;
+}
+
+ /*ARGSUSED*/ static void
+ymhusb_close_output (int dev, int mode)
+{
+ oss_native_word flags;
+ ymhusb_midic *midic;
+
+ midic = midi_devs[dev]->devc;
+
+ ymhusb_flush_output (dev);
+
+ MUTEX_ENTER_IRQDISABLE (midic->mutex, flags);
+ midic->open_mode = 0;
+ midic->midi_input_intr = NULL;
+ udi_usb_free_request (midic->datapipe);
+ udi_close_endpoint (midic->endpoint_handle);
+ if (midic->outbuf != NULL)
+ CONTIG_FREE (midic->osdev, midic->outbuf, OUTBUF_SIZE, midic->outbuf_dma_handle);
+ if (midic->tmpbuf != NULL)
+ KERNEL_FREE (midic->tmpbuf);
+ midiparser_unalloc (midic->parser);
+ midic->parser = NULL;
+ MUTEX_EXIT_IRQRESTORE (midic->mutex, flags);
+}
+
+static void
+out_event (ymhusb_midic * midic, unsigned char a, unsigned char b,
+ unsigned char c, unsigned char d)
+{
+ unsigned char *e;
+ ymhusb_devc *devc = midic->devc;
+
+ if (midic->tmp_len > TMPBUF_SIZE - 4)
+ ymhmidi_put_output (devc, midic);
+
+ e = midic->tmpbuf + midic->tmp_len;
+ *e++ = a;
+ *e++ = b;
+ *e++ = c;
+ *e++ = d;
+
+ midic->tmp_len += 4;
+
+ if (midic->tmp_len >= TMPBUF_SIZE)
+ ymhmidi_put_output (devc, midic);
+}
+
+void
+parser_cb (void *context, int category, unsigned char msg, unsigned char ch,
+ unsigned char *parms, int len)
+{
+ ymhusb_midic *midic = context;
+
+ if (category == CAT_VOICE)
+ {
+ switch (msg)
+ {
+ case MIDI_NOTEON:
+ out_event (midic, 0x9, msg | ch, parms[0], parms[1]);
+ break;
+
+ case MIDI_NOTEOFF:
+ out_event (midic, 0x8, msg | ch, parms[0], parms[1]);
+ break;
+
+ case MIDI_KEY_PRESSURE:
+ out_event (midic, 0xa, msg | ch, parms[0], parms[1]);
+ break;
+ }
+
+ return;
+ }
+
+ if (category == CAT_CHN)
+ {
+ switch (msg)
+ {
+ case MIDI_CTL_CHANGE:
+ out_event (midic, 0xb, msg | ch, parms[0], parms[1]);
+ break;
+
+ case MIDI_PGM_CHANGE:
+ out_event (midic, 0xc, msg | ch, parms[0], 0);
+ break;
+
+ case MIDI_CHN_PRESSURE:
+ out_event (midic, 0xd, msg | ch, parms[0], 0);
+ break;
+
+ case MIDI_PITCH_BEND:
+ out_event (midic, 0xe, msg | ch, parms[0], parms[1]);
+ break;
+ }
+ return;
+ }
+
+ if (category == CAT_REALTIME)
+ {
+ out_event (midic, 0xf, msg | ch, 0, 0);
+ return;
+ }
+
+ if (category == CAT_MTC)
+ {
+ out_event (midic, 0x2, 0xf1, parms[0], 0);
+ return;
+ }
+
+ if (category == CAT_SYSEX)
+ {
+ int l = len, n;
+ unsigned char *d = parms;
+
+ while (l > 0)
+ {
+ n = l;
+ if (n > 3)
+ n = 3;
+
+ switch (n)
+ {
+ case 3:
+ out_event (midic, 0x4, d[0], d[1], d[2]);
+ break;
+ case 2:
+ out_event (midic, 0x6, d[0], d[1], 0);
+ break;
+ case 1:
+ out_event (midic, 0x5, d[0], 0, 0);
+ break;
+ }
+
+ l -= n;
+ d += n;
+ }
+ return;
+ }
+}
+
+ /*ARGSUSED*/ static int
+ymhusb_open_output (int dev, int mode, oss_midi_inputbyte_t inputbyte,
+ oss_midi_inputbuf_t inputbuf,
+ oss_midi_outputintr_t outputintr)
+{
+ oss_native_word flags, phaddr;
+ ymhusb_midic *midic;
+
+ midic = midi_devs[dev]->devc;
+
+ MUTEX_ENTER_IRQDISABLE (midic->mutex, flags);
+ if (midic->open_mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (midic->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ midic->open_mode = mode;
+ midic->output_busy = 0;
+ MUTEX_EXIT_IRQRESTORE (midic->mutex, flags);
+
+ midic->tmpbuf = KERNEL_MALLOC (TMPBUF_SIZE);
+ memset (midic->tmpbuf, 0, TMPBUF_SIZE);
+ midic->outbuf =
+ CONTIG_MALLOC (midic->osdev, OUTBUF_SIZE, MEMLIMIT_32BITS, &phaddr, midic->outbuf_dma_handle);
+ midic->tmp_len = 0;
+ midic->buf_h = midic->buf_t = 0; /* Empty buffer */
+ memset (midic->outbuf, 0, OUTBUF_SIZE);
+
+ if ((midic->parser = midiparser_create (parser_cb, midic)) == NULL)
+ {
+ midic->open_mode = 0;
+ midic->midi_input_intr = NULL;
+ cmn_err (CE_WARN, "Cannot create MIDI parser\n");
+ return OSS_ENOMEM;
+ }
+
+ if ((midic->endpoint_handle =
+ udi_open_endpoint (midic->usbdev, midic->endpoint_desc)) == NULL)
+ {
+ midic->open_mode = 0;
+ midic->midi_input_intr = NULL;
+ cmn_err (CE_WARN, "Cannot open audio pipe\n");
+ return OSS_ENOMEM;
+ }
+ if ((midic->datapipe =
+ udi_usb_alloc_request (midic->usbdev, midic->endpoint_handle, 1,
+ UDI_USBXFER_BULK_WRITE)) == NULL)
+ {
+ return OSS_EIO;
+ }
+
+ return 0;
+}
+
+static int
+ymhusb_out (int dev, unsigned char midi_byte)
+{
+ ymhusb_midic *midic = midi_devs[dev]->devc;
+ oss_native_word flags;
+ int next;
+
+ next = (midic->buf_t + 1) % TMPBUF_NSLOTS;
+ if (next == midic->buf_h) /* Buffer full */
+ return 0; /* Try again later */
+
+ MUTEX_ENTER_IRQDISABLE (midic->mutex, flags);
+ midiparser_input (midic->parser, midi_byte);
+ MUTEX_EXIT_IRQRESTORE (midic->mutex, flags);
+
+ return 1;
+}
+
+ /*ARGSUSED*/ static int
+ymhusb_ioctl (int dev, unsigned cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static midi_driver_t ymhusb_input_driver = {
+ ymhusb_open_input,
+ ymhusb_close_input,
+ ymhusb_ioctl,
+ ymhusb_out,
+};
+
+static void
+add_input_device (ymhusb_devc * devc, char *name, void *desc, int caps)
+{
+ int n;
+ ymhusb_midic *midic;
+ char tmp[128];
+
+ if (devc->n_inputs >= MAX_INDEVS)
+ {
+ cmn_err (CE_WARN, "Yamaha MIDI: Too many inputs\n");
+ return;
+ }
+
+ n = devc->n_inputs++;
+
+ midic = &devc->indevs[n];
+
+ midic->devc = devc;
+ midic->osdev = devc->osdev;
+ MUTEX_INIT (midic->osdev, midic->mutex, MH_DRV + 1);
+ midic->endpoint_desc = desc;
+ midic->portnum = n;
+ midic->usbdev = devc->usbdev;
+
+ sprintf (tmp, "%s input %d", name, n);
+ if ((midic->midi_dev =
+ oss_install_mididev (OSS_MIDI_DRIVER_VERSION, "YMHMIDI", tmp,
+ &ymhusb_input_driver,
+ sizeof (ymhusb_input_driver),
+ MFLAG_INPUT, midic, midic->osdev)) < 0)
+ {
+ cmn_err (CE_CONT, "Failed to install MIDI device\n");
+ return;
+ }
+ midi_devs[midic->midi_dev]->caps |= caps;
+}
+
+static midi_driver_t ymhusb_output_driver = {
+ ymhusb_open_output,
+ ymhusb_close_output,
+ ymhusb_ioctl,
+ ymhusb_out,
+ NULL,
+ 0,
+ ymhusb_flush_output,
+ ymhusb_wait_output
+};
+
+static void
+add_output_device (ymhusb_devc * devc, char *name, void *desc, int caps)
+{
+ int n;
+ ymhusb_midic *midic;
+ char tmp[128];
+
+ if (devc->n_outputs >= MAX_OUTDEVS)
+ {
+ cmn_err (CE_WARN, "Yamaha MIDI: Too many outputs\n");
+ return;
+ }
+
+ n = devc->n_outputs++;
+
+ midic = &devc->outdevs[n];
+
+ midic->devc = devc;
+ midic->osdev = devc->osdev;
+ MUTEX_INIT (midic->osdev, midic->mutex, MH_DRV + 1);
+ midic->endpoint_desc = desc;
+ midic->portnum = n;
+ midic->usbdev = devc->usbdev;
+
+ sprintf (tmp, "%s output %d", name, n);
+ if ((midic->midi_dev =
+ oss_install_mididev (OSS_MIDI_DRIVER_VERSION, "YMHMIDI", tmp,
+ &ymhusb_output_driver,
+ sizeof (ymhusb_output_driver),
+ MFLAG_OUTPUT, midic, midic->osdev)) < 0)
+ {
+ cmn_err (CE_CONT, "Failed to install MIDI device\n");
+ return;
+ }
+
+ midi_devs[midic->midi_dev]->caps |= caps;
+}
+
+void *
+yamaha_usb_midi_driver (ossusb_devc * usb_devc)
+{
+ ymhusb_devc *devc;
+ int i;
+ unsigned char *desc;
+ int desc_len;
+ int caps = MIDI_CAP_EXTERNAL;
+ unsigned int devid;
+
+ char *name = "Yamaha USB MIDI";
+
+ if (usb_devc->dev_name != NULL)
+ name = usb_devc->dev_name;
+
+ if ((devc = PMALLOC (usb_devc->osdev, sizeof (*devc))) == NULL)
+ {
+ cmn_err (CE_WARN, "Yamaha MIDI: Out of memory\n");
+ return NULL;
+ }
+
+ memset (devc, 0, sizeof (*devc));
+
+ devc->unload_func = ymhusb_unload;
+ devc->osdev = usb_devc->osdev;
+ devc->usbdev = usb_devc->last_usbdev;
+ MUTEX_INIT (devc->osdev, devc->mutex, MH_DRV);
+ devid = (usb_devc->vendor << 16) | usb_devc->product;
+
+ DDB (cmn_err
+ (CE_CONT, "Attaching Yamaha MIDI device %08x (%s)\n", devid, name));
+
+ switch (devid)
+ {
+ case 0x0499101e: /* PSR-K1 keyboard */
+ caps |= MIDI_CAP_PTOP;
+ break;
+ }
+
+ for (i = 0; i < 32; i++)
+ if ((desc =
+ udi_usbdev_get_endpoint (devc->usbdev, 0, i, &desc_len)) != NULL)
+ {
+ if (desc[2] & 0x80)
+ {
+ add_input_device (devc, name, desc, caps);
+ }
+ else
+ {
+ add_output_device (devc, name, desc, caps);
+ }
+ }
+
+ return devc;
+}
diff --git a/kernel/drv/oss_usb/oxygen8_fw.h b/kernel/drv/oss_usb/oxygen8_fw.h
new file mode 100755
index 0000000..a5fe5e6
--- /dev/null
+++ b/kernel/drv/oss_usb/oxygen8_fw.h
@@ -0,0 +1,678 @@
+/*
+ * Purpose: Firmware download for M-Audio Oxygen8 MIDI keyboard
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This this source file is released under GPL v2 license (no other versions).
+ * See the COPYING file included in the main directory of this source
+ * distribution for the license terms and conditions.
+ *
+ */
+
+const struct setup_request oxygen8_setupRequest[] = {
+ {0x00, 0x05, 0x0002, 0x0000, 0x0000, 0x0000, ""},
+ {0x40, 0xA0, 0x7F92, 0x0000, 0x0001, 0x0001, "\x01"},
+ {0x40, 0xA0, 0x7F92, 0x0000, 0x0001, 0x0001, "\x01"},
+ {0x40, 0xA0, 0x146C, 0x0000, 0x0010, 0x0010,
+ "\xC2\x00\x90\x7F\xA5\xE0\x54\x18\xFF\x13\x13\x13\x54\x1F\x44\x50"},
+ {0x40, 0xA0, 0x147C, 0x0000, 0x0010, 0x0010,
+ "\xF5\x1C\x13\x92\x01\xD2\xE8\x90\x7F\xAB\x74\xFF\xF0\x90\x7F\xA9"},
+ {0x40, 0xA0, 0x148C, 0x0000, 0x0010, 0x0010,
+ "\xF0\x90\x7F\xAA\xF0\x53\x91\xEF\x90\x7F\x95\xE0\x44\xC0\xF0\x90"},
+ {0x40, 0xA0, 0x149C, 0x0000, 0x0010, 0x0010,
+ "\x7F\xAF\xE0\x44\x01\xF0\x90\x7F\xAE\xE0\x44\x05\xF0\xD2\xAF\x12"},
+ {0x40, 0xA0, 0x14AC, 0x0000, 0x000D, 0x000D,
+ "\x17\x5F\x30\x00\xFD\x12\x11\x00\xC2\x00\x80\xF6\x22"},
+ {0x40, 0xA0, 0x1100, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xE9\xE0\x24\x5D\x60\x0D\x14\x70\x03\x02\x12\x44\x24\x02"},
+ {0x40, 0xA0, 0x1110, 0x0000, 0x0010, 0x0010,
+ "\x60\x03\x02\x12\x4A\x90\x7F\xEA\xE0\x75\x08\x00\xF5\x09\xA3\xE0"},
+ {0x40, 0xA0, 0x1120, 0x0000, 0x0010, 0x0010,
+ "\xFE\xE4\x25\x09\xF5\x09\xEE\x35\x08\xF5\x08\x90\x7F\xEE\xE0\x75"},
+ {0x40, 0xA0, 0x1130, 0x0000, 0x0010, 0x0010,
+ "\x0A\x00\xF5\x0B\xA3\xE0\xFE\xE4\x25\x0B\xF5\x0B\xEE\x35\x0A\xF5"},
+ {0x40, 0xA0, 0x1140, 0x0000, 0x0010, 0x0010,
+ "\x0A\x90\x7F\xE8\xE0\x64\xC0\x60\x03\x02\x11\xD4\xE5\x0B\x45\x0A"},
+ {0x40, 0xA0, 0x1150, 0x0000, 0x0010, 0x0010,
+ "\x70\x03\x02\x12\x4A\xC3\xE5\x0B\x94\x40\xE5\x0A\x94\x00\x50\x08"},
+ {0x40, 0xA0, 0x1160, 0x0000, 0x0010, 0x0010,
+ "\x85\x0A\x0C\x85\x0B\x0D\x80\x06\x75\x0C\x00\x75\x0D\x40\x90\x7F"},
+ {0x40, 0xA0, 0x1170, 0x0000, 0x0010, 0x0010,
+ "\xE9\xE0\xB4\xA3\x25\xAE\x0C\xAF\x0D\xAA\x08\xA9\x09\x7B\x01\xC0"},
+ {0x40, 0xA0, 0x1180, 0x0000, 0x0010, 0x0010,
+ "\x03\xC0\x02\xC0\x01\x7A\x7F\x79\x00\x78\x00\x7C\x7F\xAD\x03\xD0"},
+ {0x40, 0xA0, 0x1190, 0x0000, 0x0010, 0x0010,
+ "\x01\xD0\x02\xD0\x03\x12\x13\x56\x80\x0F\xAF\x09\xAE\x08\xAD\x0D"},
+ {0x40, 0xA0, 0x11A0, 0x0000, 0x0010, 0x0010,
+ "\x7A\x7F\x79\x00\x7B\x00\x12\x15\xA4\x90\x7F\xB5\xE5\x0D\xF0\xE5"},
+ {0x40, 0xA0, 0x11B0, 0x0000, 0x0010, 0x0010,
+ "\x0D\x25\x09\xF5\x09\xE5\x0C\x35\x08\xF5\x08\xC3\xE5\x0B\x95\x0D"},
+ {0x40, 0xA0, 0x11C0, 0x0000, 0x0010, 0x0010,
+ "\xF5\x0B\xE5\x0A\x95\x0C\xF5\x0A\x90\x7F\xB4\xE0\x20\xE2\x03\x02"},
+ {0x40, 0xA0, 0x11D0, 0x0000, 0x0010, 0x0010,
+ "\x11\x4C\x80\xF4\x90\x7F\xE8\xE0\x64\x40\x70\x6E\xE5\x0B\x45\x0A"},
+ {0x40, 0xA0, 0x11E0, 0x0000, 0x0010, 0x0010,
+ "\x60\x68\xE4\x90\x7F\xC5\xF0\x90\x7F\xB4\xE0\x20\xE3\xF9\x90\x7F"},
+ {0x40, 0xA0, 0x11F0, 0x0000, 0x0010, 0x0010,
+ "\xC5\xE0\x75\x0C\x00\xF5\x0D\x90\x7F\xE9\xE0\xB4\xA3\x15\xAE\x0C"},
+ {0x40, 0xA0, 0x1200, 0x0000, 0x0010, 0x0010,
+ "\xAF\x0D\xA8\x09\xAC\x08\x7D\x01\x7B\x01\x7A\x7E\x79\xC0\x12\x13"},
+ {0x40, 0xA0, 0x1210, 0x0000, 0x0010, 0x0010,
+ "\x56\x80\x0F\xAF\x09\xAE\x08\xAD\x0D\x7A\x7F\x79\x00\x7B\x00\x12"},
+ {0x40, 0xA0, 0x1220, 0x0000, 0x0010, 0x0010,
+ "\x14\xB9\xE5\x0D\x25\x09\xF5\x09\xE5\x0C\x35\x08\xF5\x08\xC3\xE5"},
+ {0x40, 0xA0, 0x1230, 0x0000, 0x0010, 0x0010,
+ "\x0B\x95\x0D\xF5\x0B\xE5\x0A\x95\x0C\xF5\x0A\x90\x7F\xB4\xE0\x44"},
+ {0x40, 0xA0, 0x1240, 0x0000, 0x000A, 0x000A,
+ "\x02\xF0\x80\x98\x90\x7F\xEA\xE0\xF5\x1C"},
+ {0x40, 0xA0, 0x124A, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x1558, 0x0000, 0x0006, 0x0006, "\xAB\x07\xAA\x06\xAC\x05"},
+ {0x40, 0xA0, 0x155E, 0x0000, 0x0010, 0x0010,
+ "\xE4\xFD\x30\x01\x11\xEA\xFF\xAE\x05\x0D\xEE\x24\x00\xF5\x82\xE4"},
+ {0x40, 0xA0, 0x156E, 0x0000, 0x0010, 0x0010,
+ "\x34\xE0\xF5\x83\xEF\xF0\xEB\xAE\x05\x0D\x74\x00\x2E\xF5\x82\xE4"},
+ {0x40, 0xA0, 0x157E, 0x0000, 0x0010, 0x0010,
+ "\x34\xE0\xF5\x83\xEB\xF0\xAF\x05\x0D\x74\x00\x2F\xF5\x82\xE4\x34"},
+ {0x40, 0xA0, 0x158E, 0x0000, 0x0010, 0x0010,
+ "\xE0\xF5\x83\xEC\xF0\xAF\x1C\x7A\xE0\x7B\x00\x12\x17\x20\x7F\x0A"},
+ {0x40, 0xA0, 0x159E, 0x0000, 0x0005, 0x0005, "\x7E\x00\x12\x17\x3C"},
+ {0x40, 0xA0, 0x15A3, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x14B9, 0x0000, 0x000A, 0x000A,
+ "\x8E\x0E\x8F\x0F\x8D\x10\x8A\x11\x8B\x12"},
+ {0x40, 0xA0, 0x14C3, 0x0000, 0x0010, 0x0010,
+ "\xE4\xF5\x13\xE5\x13\xC3\x95\x10\x50\x20\x05\x0F\xE5\x0F\xAE\x0E"},
+ {0x40, 0xA0, 0x14D3, 0x0000, 0x0010, 0x0010,
+ "\x70\x02\x05\x0E\x14\xFF\xE5\x12\x25\x13\xF5\x82\xE4\x35\x11\xF5"},
+ {0x40, 0xA0, 0x14E3, 0x0000, 0x000A, 0x000A,
+ "\x83\xE0\xFD\x12\x15\x58\x05\x13\x80\xD9"},
+ {0x40, 0xA0, 0x14ED, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x15A4, 0x0000, 0x000A, 0x000A,
+ "\x8E\x0E\x8F\x0F\x8D\x10\x8A\x11\x8B\x12"},
+ {0x40, 0xA0, 0x15AE, 0x0000, 0x0010, 0x0010,
+ "\xE4\xFD\x30\x01\x12\xE5\x0E\xFF\xAE\x05\x0D\xEE\x24\x03\xF5\x82"},
+ {0x40, 0xA0, 0x15BE, 0x0000, 0x0010, 0x0010,
+ "\xE4\x34\xE0\xF5\x83\xEF\xF0\xE5\x0F\xAE\x05\x0D\x74\x03\x2E\xF5"},
+ {0x40, 0xA0, 0x15CE, 0x0000, 0x0010, 0x0010,
+ "\x82\xE4\x34\xE0\xF5\x83\xE5\x0F\xF0\xAF\x1C\x7A\xE0\x7B\x03\x12"},
+ {0x40, 0xA0, 0x15DE, 0x0000, 0x000D, 0x000D,
+ "\x17\x20\xAF\x1C\xAD\x10\xAB\x12\xAA\x11\x12\x17\x04"},
+ {0x40, 0xA0, 0x15EB, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x166E, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\xD2"},
+ {0x40, 0xA0, 0x167E, 0x0000, 0x0010, 0x0010,
+ "\x00\x53\x91\xEF\x90\x7F\xAB\x74\x01\xF0\xD0\x86\xD0\x84\xD0\x85"},
+ {0x40, 0xA0, 0x168E, 0x0000, 0x0007, 0x0007,
+ "\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x1644, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\x90"},
+ {0x40, 0xA0, 0x1654, 0x0000, 0x0010, 0x0010,
+ "\x7F\xC4\xE4\xF0\x53\x91\xEF\x90\x7F\xAB\x74\x04\xF0\xD0\x86\xD0"},
+ {0x40, 0xA0, 0x1664, 0x0000, 0x000A, 0x000A,
+ "\x84\xD0\x85\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x1695, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\x53"},
+ {0x40, 0xA0, 0x16A5, 0x0000, 0x0010, 0x0010,
+ "\x91\xEF\x90\x7F\xAB\x74\x02\xF0\xD0\x86\xD0\x84\xD0\x85\xD0\x82"},
+ {0x40, 0xA0, 0x16B5, 0x0000, 0x0005, 0x0005, "\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x16BA, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\x53"},
+ {0x40, 0xA0, 0x16CA, 0x0000, 0x0010, 0x0010,
+ "\x91\xEF\x90\x7F\xAB\x74\x10\xF0\xD0\x86\xD0\x84\xD0\x85\xD0\x82"},
+ {0x40, 0xA0, 0x16DA, 0x0000, 0x0005, 0x0005, "\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x14FF, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x16DF, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\x53"},
+ {0x40, 0xA0, 0x16EF, 0x0000, 0x0010, 0x0010,
+ "\x91\xEF\x90\x7F\xAB\x74\x08\xF0\xD0\x86\xD0\x84\xD0\x85\xD0\x82"},
+ {0x40, 0xA0, 0x16FF, 0x0000, 0x0005, 0x0005, "\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x1767, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1768, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1769, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x176A, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x176B, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x176C, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x176D, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x176E, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x176F, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1770, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1771, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1772, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1773, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1774, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1775, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1776, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0043, 0x0000, 0x0003, 0x0003, "\x02\x15\x00"},
+ {0x40, 0xA0, 0x1500, 0x0000, 0x0010, 0x0010,
+ "\x02\x16\x6E\x00\x02\x16\x95\x00\x02\x16\x44\x00\x02\x16\xDF\x00"},
+ {0x40, 0xA0, 0x1510, 0x0000, 0x0010, 0x0010,
+ "\x02\x16\xBA\x00\x02\x14\xFF\x00\x02\x17\x67\x00\x02\x17\x68\x00"},
+ {0x40, 0xA0, 0x1520, 0x0000, 0x0010, 0x0010,
+ "\x02\x17\x69\x00\x02\x17\x6A\x00\x02\x17\x6B\x00\x02\x17\x6C\x00"},
+ {0x40, 0xA0, 0x1530, 0x0000, 0x0010, 0x0010,
+ "\x02\x17\x6D\x00\x02\x17\x6E\x00\x02\x17\x6F\x00\x02\x17\x70\x00"},
+ {0x40, 0xA0, 0x1540, 0x0000, 0x0010, 0x0010,
+ "\x02\x17\x71\x00\x02\x17\x72\x00\x02\x17\x73\x00\x02\x17\x74\x00"},
+ {0x40, 0xA0, 0x1550, 0x0000, 0x0008, 0x0008,
+ "\x02\x17\x75\x00\x02\x17\x76\x00"},
+ {0x40, 0xA0, 0x173C, 0x0000, 0x0010, 0x0010,
+ "\x8E\x14\x8F\x15\xE5\x15\x15\x15\xAE\x14\x70\x02\x15\x14\x4E\x60"},
+ {0x40, 0xA0, 0x174C, 0x0000, 0x0007, 0x0007,
+ "\x05\x12\x14\xEE\x80\xEE\x22"},
+ {0x40, 0xA0, 0x175F, 0x0000, 0x0008, 0x0008,
+ "\xE4\xF5\x1B\xD2\xE9\xD2\xAF\x22"},
+ {0x40, 0xA0, 0x1619, 0x0000, 0x0010, 0x0010,
+ "\xA9\x07\xE5\x1B\x70\x23\x90\x7F\xA5\xE0\x44\x80\xF0\xE9\x25\xE0"},
+ {0x40, 0xA0, 0x1629, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xA6\xF0\x8D\x16\xAF\x03\xA9\x07\x75\x17\x01\x8A\x18\x89"},
+ {0x40, 0xA0, 0x1639, 0x0000, 0x000B, 0x000B,
+ "\x19\xE4\xF5\x1A\x75\x1B\x01\xD3\x22\xC3\x22"},
+ {0x40, 0xA0, 0x15EC, 0x0000, 0x0010, 0x0010,
+ "\xA9\x07\xE5\x1B\x70\x25\x90\x7F\xA5\xE0\x44\x80\xF0\xE9\x25\xE0"},
+ {0x40, 0xA0, 0x15FC, 0x0000, 0x0010, 0x0010,
+ "\x44\x01\x90\x7F\xA6\xF0\x8D\x16\xAF\x03\xA9\x07\x75\x17\x01\x8A"},
+ {0x40, 0xA0, 0x160C, 0x0000, 0x000D, 0x000D,
+ "\x18\x89\x19\xE4\xF5\x1A\x75\x1B\x03\xD3\x22\xC3\x22"},
+ {0x40, 0xA0, 0x004B, 0x0000, 0x0003, 0x0003, "\x02\x13\x7F"},
+ {0x40, 0xA0, 0x137F, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\xC0"},
+ {0x40, 0xA0, 0x138F, 0x0000, 0x0010, 0x0010,
+ "\xD0\x75\xD0\x00\xC0\x00\xC0\x01\xC0\x02\xC0\x03\xC0\x06\xC0\x07"},
+ {0x40, 0xA0, 0x139F, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xA5\xE0\x30\xE2\x06\x75\x1B\x06\x02\x14\x4E\x90\x7F\xA5"},
+ {0x40, 0xA0, 0x13AF, 0x0000, 0x0010, 0x0010,
+ "\xE0\x20\xE1\x0C\xE5\x1B\x64\x02\x60\x06\x75\x1B\x07\x02\x14\x4E"},
+ {0x40, 0xA0, 0x13BF, 0x0000, 0x0010, 0x0010,
+ "\xAF\x1B\xEF\x24\xFE\x60\x48\x14\x60\x2C\x24\xFE\x60\x77\x24\x04"},
+ {0x40, 0xA0, 0x13CF, 0x0000, 0x0010, 0x0010,
+ "\x60\x03\x02\x14\x4E\xAB\x17\xAA\x18\xA9\x19\xAF\x1A\x05\x1A\x8F"},
+ {0x40, 0xA0, 0x13DF, 0x0000, 0x0010, 0x0010,
+ "\x82\x75\x83\x00\x12\x12\x4B\x90\x7F\xA6\xF0\xE5\x1A\x65\x16\x70"},
+ {0x40, 0xA0, 0x13EF, 0x0000, 0x0010, 0x0010,
+ "\x5E\x75\x1B\x05\x80\x59\x90\x7F\xA6\xE0\xAB\x17\xAA\x18\xA9\x19"},
+ {0x40, 0xA0, 0x13FF, 0x0000, 0x0010, 0x0010,
+ "\xAE\x1A\x8E\x82\x75\x83\x00\x12\x12\x78\x75\x1B\x02\x80\x40\xE5"},
+ {0x40, 0xA0, 0x140F, 0x0000, 0x0010, 0x0010,
+ "\x16\x24\xFE\xB5\x1A\x07\x90\x7F\xA5\xE0\x44\x20\xF0\xE5\x16\x14"},
+ {0x40, 0xA0, 0x141F, 0x0000, 0x0010, 0x0010,
+ "\xB5\x1A\x0A\x90\x7F\xA5\xE0\x44\x40\xF0\x75\x1B\x00\x90\x7F\xA6"},
+ {0x40, 0xA0, 0x142F, 0x0000, 0x0010, 0x0010,
+ "\xE0\xAB\x17\xAA\x18\xA9\x19\xAE\x1A\x8E\x82\x75\x83\x00\x12\x12"},
+ {0x40, 0xA0, 0x143F, 0x0000, 0x0010, 0x0010,
+ "\x78\x05\x1A\x80\x0A\x90\x7F\xA5\xE0\x44\x40\xF0\x75\x1B\x00\x53"},
+ {0x40, 0xA0, 0x144F, 0x0000, 0x0010, 0x0010,
+ "\x91\xDF\xD0\x07\xD0\x06\xD0\x03\xD0\x02\xD0\x01\xD0\x00\xD0\xD0"},
+ {0x40, 0xA0, 0x145F, 0x0000, 0x000D, 0x000D,
+ "\xD0\x86\xD0\x84\xD0\x85\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x1704, 0x0000, 0x0010, 0x0010,
+ "\x12\x15\xEC\xE5\x1B\x24\xFA\x60\x0E\x14\x60\x06\x24\x07\x70\xF3"},
+ {0x40, 0xA0, 0x1714, 0x0000, 0x000C, 0x000C,
+ "\xD3\x22\xE4\xF5\x1B\xD3\x22\xE4\xF5\x1B\xD3\x22"},
+ {0x40, 0xA0, 0x1720, 0x0000, 0x0010, 0x0010,
+ "\x12\x16\x19\xE5\x1B\x24\xFA\x60\x0E\x14\x60\x06\x24\x07\x70\xF3"},
+ {0x40, 0xA0, 0x1730, 0x0000, 0x000C, 0x000C,
+ "\xD3\x22\xE4\xF5\x1B\xD3\x22\xE4\xF5\x1B\xD3\x22"},
+ {0x40, 0xA0, 0x14EE, 0x0000, 0x0010, 0x0010,
+ "\x74\x00\xF5\x86\x90\xFD\xA5\x7C\x05\xA3\xE5\x82\x45\x83\x70\xF9"},
+ {0x40, 0xA0, 0x14FE, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0000, 0x0000, 0x0003, 0x0003, "\x02\x17\x53"},
+ {0x40, 0xA0, 0x1753, 0x0000, 0x000C, 0x000C,
+ "\x78\x7F\xE4\xF6\xD8\xFD\x75\x81\x20\x02\x14\x6C"},
+ {0x40, 0xA0, 0x124B, 0x0000, 0x0010, 0x0010,
+ "\xBB\x01\x0C\xE5\x82\x29\xF5\x82\xE5\x83\x3A\xF5\x83\xE0\x22\x50"},
+ {0x40, 0xA0, 0x125B, 0x0000, 0x0010, 0x0010,
+ "\x06\xE9\x25\x82\xF8\xE6\x22\xBB\xFE\x06\xE9\x25\x82\xF8\xE2\x22"},
+ {0x40, 0xA0, 0x126B, 0x0000, 0x000D, 0x000D,
+ "\xE5\x82\x29\xF5\x82\xE5\x83\x3A\xF5\x83\xE4\x93\x22"},
+ {0x40, 0xA0, 0x1278, 0x0000, 0x0010, 0x0010,
+ "\xF8\xBB\x01\x0D\xE5\x82\x29\xF5\x82\xE5\x83\x3A\xF5\x83\xE8\xF0"},
+ {0x40, 0xA0, 0x1288, 0x0000, 0x0010, 0x0010,
+ "\x22\x50\x06\xE9\x25\x82\xC8\xF6\x22\xBB\xFE\x05\xE9\x25\x82\xC8"},
+ {0x40, 0xA0, 0x1298, 0x0000, 0x0002, 0x0002, "\xF2\x22"},
+ {0x40, 0xA0, 0x129A, 0x0000, 0x0010, 0x0010,
+ "\xE7\x09\xF6\x08\xDF\xFA\x80\x46\xE7\x09\xF2\x08\xDF\xFA\x80\x3E"},
+ {0x40, 0xA0, 0x12AA, 0x0000, 0x0010, 0x0010,
+ "\x88\x82\x8C\x83\xE7\x09\xF0\xA3\xDF\xFA\x80\x32\xE3\x09\xF6\x08"},
+ {0x40, 0xA0, 0x12BA, 0x0000, 0x0010, 0x0010,
+ "\xDF\xFA\x80\x6E\xE3\x09\xF2\x08\xDF\xFA\x80\x66\x88\x82\x8C\x83"},
+ {0x40, 0xA0, 0x12CA, 0x0000, 0x0010, 0x0010,
+ "\xE3\x09\xF0\xA3\xDF\xFA\x80\x5A\x89\x82\x8A\x83\xE0\xA3\xF6\x08"},
+ {0x40, 0xA0, 0x12DA, 0x0000, 0x0010, 0x0010,
+ "\xDF\xFA\x80\x4E\x89\x82\x8A\x83\xE0\xA3\xF2\x08\xDF\xFA\x80\x42"},
+ {0x40, 0xA0, 0x12EA, 0x0000, 0x0010, 0x0010,
+ "\x80\xD2\x80\xFA\x80\xC6\x80\xD4\x80\x55\x80\xF2\x80\x29\x80\x10"},
+ {0x40, 0xA0, 0x12FA, 0x0000, 0x0010, 0x0010,
+ "\x80\xA6\x80\xEA\x80\x9A\x80\xA8\x80\xDA\x80\xE2\x80\xCA\x80\x29"},
+ {0x40, 0xA0, 0x130A, 0x0000, 0x0010, 0x0010,
+ "\x88\x84\x8C\x85\x89\x82\x8A\x83\xE4\x93\xA3\x05\x86\xF0\xA3\x05"},
+ {0x40, 0xA0, 0x131A, 0x0000, 0x0010, 0x0010,
+ "\x86\xDF\xF5\xDE\xF3\x80\x0B\x89\x82\x8A\x83\xE4\x93\xA3\xF6\x08"},
+ {0x40, 0xA0, 0x132A, 0x0000, 0x0010, 0x0010,
+ "\xDF\xF9\xEC\xFA\xA9\xF0\xED\xFB\x22\x88\x84\x8C\x85\x89\x82\x8A"},
+ {0x40, 0xA0, 0x133A, 0x0000, 0x0010, 0x0010,
+ "\x83\xE0\xA3\x05\x86\xF0\xA3\x05\x86\xDF\xF6\xDE\xF4\x80\xE3\x89"},
+ {0x40, 0xA0, 0x134A, 0x0000, 0x0010, 0x0010,
+ "\x82\x8A\x83\xE4\x93\xA3\xF2\x08\xDF\xF9\x80\xD6\x88\xF0\xED\x24"},
+ {0x40, 0xA0, 0x135A, 0x0000, 0x0010, 0x0010,
+ "\x02\xB4\x04\x00\x50\xCC\xF5\x82\xEB\x24\x02\xB4\x04\x00\x50\xC2"},
+ {0x40, 0xA0, 0x136A, 0x0000, 0x0010, 0x0010,
+ "\x23\x23\x45\x82\xF5\x82\xEF\x4E\x60\xB8\xEF\x60\x01\x0E\xE5\x82"},
+ {0x40, 0xA0, 0x137A, 0x0000, 0x0005, 0x0005, "\x23\x90\x12\xEA\x73"},
+ {0x40, 0xA0, 0x7F92, 0x0000, 0x0001, 0x0001, "\x00"},
+ {0x40, 0xA0, 0x7F92, 0x0000, 0x0001, 0x0001, "\x01"},
+ {0x40, 0xA0, 0x0100, 0x0000, 0x0010, 0x0010,
+ "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x0110, 0x0000, 0x0010, 0x0010,
+ "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x0120, 0x0000, 0x0010, 0x0010,
+ "\x4D\x69\x64\x69\x6D\x61\x6E\x20\x55\x53\x42\x20\x4D\x69\x64\x69"},
+ {0x40, 0xA0, 0x0130, 0x0000, 0x0010, 0x0010,
+ "\x53\x70\x6F\x72\x74\x20\x31\x78\x31\x20\x20\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x0140, 0x0000, 0x0010, 0x0010,
+ "\x46\x69\x72\x6D\x77\x61\x72\x65\x20\x52\x65\x6C\x65\x61\x73\x65"},
+ {0x40, 0xA0, 0x0150, 0x0000, 0x0010, 0x0010,
+ "\x20\x31\x2E\x32\x31\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x0160, 0x0000, 0x0010, 0x0010,
+ "\x28\x63\x29\x20\x32\x30\x30\x30\x2D\x32\x30\x30\x31\x2C\x20\x4D"},
+ {0x40, 0xA0, 0x0170, 0x0000, 0x0010, 0x0010,
+ "\x69\x64\x69\x6D\x61\x6E\x20\x49\x6E\x63\x2E\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x0180, 0x0000, 0x0010, 0x0010,
+ "\x41\x6C\x6C\x20\x72\x69\x67\x68\x74\x73\x20\x72\x65\x73\x65\x72"},
+ {0x40, 0xA0, 0x0190, 0x0000, 0x0010, 0x0010,
+ "\x76\x65\x64\x2E\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x01A0, 0x0000, 0x0010, 0x0010,
+ "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x01B0, 0x0000, 0x0010, 0x0010,
+ "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x08B2, 0x0000, 0x0003, 0x0003, "\x01\x1C\x00"},
+ {0x40, 0xA0, 0x040D, 0x0000, 0x0010, 0x0010,
+ "\xC2\x01\xC2\x00\xC2\x04\xC2\x03\x12\x09\xE1\xD2\xE8\x43\xD8\x20"},
+ {0x40, 0xA0, 0x041D, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xAB\x74\xFF\xF0\x90\x7F\xA9\xF0\x90\x7F\xAA\xF0\x53\x91"},
+ {0x40, 0xA0, 0x042D, 0x0000, 0x0010, 0x0010,
+ "\xEF\x90\x7F\x95\xE0\x44\xC0\xF0\x90\x7F\xAF\xE0\x44\x01\xF0\x90"},
+ {0x40, 0xA0, 0x043D, 0x0000, 0x0010, 0x0010,
+ "\x7F\xAE\xE0\x44\x1D\xF0\x90\x7F\x92\xE0\x44\x02\xF0\x90\x7F\x95"},
+ {0x40, 0xA0, 0x044D, 0x0000, 0x0010, 0x0010,
+ "\xE0\x44\x01\xF0\x90\x7F\x9E\xE0\x54\xFE\xF0\x90\x7F\x95\xE0\x44"},
+ {0x40, 0xA0, 0x045D, 0x0000, 0x0010, 0x0010,
+ "\x02\xF0\x90\x7F\x9E\xE0\x44\x02\xF0\x90\x7F\x95\xE0\x54\x83\xF0"},
+ {0x40, 0xA0, 0x046D, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\x9E\xE0\x44\x7C\xF0\x90\x7F\x94\xE0\x54\xFE\xF0\x90\x7F"},
+ {0x40, 0xA0, 0x047D, 0x0000, 0x0010, 0x0010,
+ "\x9D\xE0\x44\x01\xF0\x90\x7F\x9A\xE0\x44\x01\x90\x7F\x97\xF0\x43"},
+ {0x40, 0xA0, 0x048D, 0x0000, 0x0010, 0x0010,
+ "\x21\x20\x43\x21\x40\x43\x21\x10\x53\x89\xF0\xE4\xF5\x8C\xF5\x8A"},
+ {0x40, 0xA0, 0x049D, 0x0000, 0x0010, 0x0010,
+ "\xD2\x8C\xD2\xA9\x12\x0B\xAE\xD2\xAF\xE5\x89\x54\x0F\x24\x20\xF5"},
+ {0x40, 0xA0, 0x04AD, 0x0000, 0x0010, 0x0010,
+ "\x89\x75\x8D\xFE\x75\x8B\xFE\xD2\x8E\xC2\xAC\x75\x98\x50\xC2\x98"},
+ {0x40, 0xA0, 0x04BD, 0x0000, 0x0010, 0x0010,
+ "\xC2\x99\xD2\xAC\x53\x21\xDF\x53\x21\xBF\x53\x21\xEF\x90\x7F\x9A"},
+ {0x40, 0xA0, 0x04CD, 0x0000, 0x0010, 0x0010,
+ "\xE0\x54\xFE\x90\x7F\x97\xF0\x90\x7F\x98\xE5\x21\xF0\x75\x24\x3D"},
+ {0x40, 0xA0, 0x04DD, 0x0000, 0x0010, 0x0010,
+ "\xE5\x24\x70\xFC\x43\x21\x20\x43\x21\x40\x43\x21\x10\x90\x7F\x98"},
+ {0x40, 0xA0, 0x04ED, 0x0000, 0x0010, 0x0010,
+ "\xE5\x21\xF0\x20\x01\x3C\x75\x24\xF4\xE5\x24\x60\x03\x30\x01\xF9"},
+ {0x40, 0xA0, 0x04FD, 0x0000, 0x0010, 0x0010,
+ "\x75\x24\xF4\xE5\x24\x60\x03\x30\x01\xF9\x75\x24\xF4\xE5\x24\x60"},
+ {0x40, 0xA0, 0x050D, 0x0000, 0x0010, 0x0010,
+ "\x03\x30\x01\xF9\x75\x24\xF4\xE5\x24\x60\x03\x30\x01\xF9\x75\x24"},
+ {0x40, 0xA0, 0x051D, 0x0000, 0x0010, 0x0010,
+ "\xF4\xE5\x24\x60\x03\x30\x01\xF9\x20\x01\xC8\xD2\x06\x12\x0A\xE0"},
+ {0x40, 0xA0, 0x052D, 0x0000, 0x0010, 0x0010,
+ "\x80\xC1\x30\x01\x0C\x12\x01\xFF\xC2\x01\x90\x7F\xAE\xE0\x44\x02"},
+ {0x40, 0xA0, 0x053D, 0x0000, 0x0010, 0x0010,
+ "\xF0\x30\x04\x1A\x12\x0B\x91\x50\x13\x12\x0B\x05\x20\x03\x07\x90"},
+ {0x40, 0xA0, 0x054D, 0x0000, 0x0010, 0x0010,
+ "\x7F\xD6\xE0\x20\xE7\xF3\x12\x0B\x26\x12\x0B\xB2\xC2\x04\x05\x1C"},
+ {0x40, 0xA0, 0x055D, 0x0000, 0x0010, 0x0010,
+ "\xE5\x1C\xC3\x94\x06\x40\x03\xE4\xF5\x1C\xE5\x1C\x75\xF0\x03\xA4"},
+ {0x40, 0xA0, 0x056D, 0x0000, 0x000E, 0x000E,
+ "\x24\x0A\xF8\x08\xE6\xFA\x08\xE6\xF9\x12\x07\x11\x80\xB4"},
+ {0x40, 0xA0, 0x057B, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0033, 0x0000, 0x0003, 0x0003, "\x02\x0B\xAA"},
+ {0x40, 0xA0, 0x0BAA, 0x0000, 0x0004, 0x0004, "\x53\xD8\xEF\x32"},
+ {0x40, 0xA0, 0x0023, 0x0000, 0x0003, 0x0003, "\x02\x07\x17"},
+ {0x40, 0xA0, 0x0717, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\xC0"},
+ {0x40, 0xA0, 0x0727, 0x0000, 0x000C, 0x000C,
+ "\xD0\x75\xD0\x00\xC0\x00\xC0\x05\xC0\x06\xC0\x07"},
+ {0x40, 0xA0, 0x0733, 0x0000, 0x0010, 0x0010,
+ "\x30\x99\x23\xC2\x99\xE5\x68\x60\x1B\xAF\x67\x05\x67\x74\x00\x2F"},
+ {0x40, 0xA0, 0x0743, 0x0000, 0x0010, 0x0010,
+ "\xF5\x82\xE4\x34\x0F\xF5\x83\xE0\xF5\x99\x15\x68\x53\x21\xBF\x75"},
+ {0x40, 0xA0, 0x0753, 0x0000, 0x0010, 0x0010,
+ "\x23\x0C\x80\x02\xD2\x02\x30\x98\x1E\xC2\x98\xAF\x99\xE5\x66\x04"},
+ {0x40, 0xA0, 0x0763, 0x0000, 0x0010, 0x0010,
+ "\x54\x3F\xFE\x65\x65\x60\x0A\xAD\x66\x74\x25\x2D\xF8\xA6\x07\x8E"},
+ {0x40, 0xA0, 0x0773, 0x0000, 0x0007, 0x0007,
+ "\x66\x53\x21\xDF\x75\x22\x0C"},
+ {0x40, 0xA0, 0x077A, 0x0000, 0x0010, 0x0010,
+ "\xD0\x07\xD0\x06\xD0\x05\xD0\x00\xD0\xD0\xD0\x86\xD0\x84\xD0\x85"},
+ {0x40, 0xA0, 0x078A, 0x0000, 0x0007, 0x0007,
+ "\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x0A17, 0x0000, 0x0010, 0x0010,
+ "\xA2\xAC\x92\x06\xC2\xAC\x30\x02\x0C\xC2\x02\x8F\x99\x53\x21\xBF"},
+ {0x40, 0xA0, 0x0A27, 0x0000, 0x0010, 0x0010,
+ "\x75\x23\x0C\x80\x12\xAE\x69\x05\x69\x74\x00\x2E\xF5\x82\xE4\x34"},
+ {0x40, 0xA0, 0x0A37, 0x0000, 0x000B, 0x000B,
+ "\x0F\xF5\x83\xEF\xF0\x05\x68\xA2\x06\x92\xAC"},
+ {0x40, 0xA0, 0x0A42, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x01C0, 0x0000, 0x0010, 0x0010,
+ "\x12\x01\x00\x01\x00\x00\x00\x40\x63\x07\x15\x10\x21\x01\x00\x00"},
+ {0x40, 0xA0, 0x01D0, 0x0000, 0x0010, 0x0010,
+ "\x00\x01\x09\x02\x27\x00\x01\x01\x00\xA0\x00\x09\x04\x00\x00\x03"},
+ {0x40, 0xA0, 0x01E0, 0x0000, 0x0010, 0x0010,
+ "\xFF\x00\x00\x00\x07\x05\x81\x03\x20\x00\x01\x07\x05\x82\x02\x20"},
+ {0x40, 0xA0, 0x01F0, 0x0000, 0x000F, 0x000F,
+ "\x00\x00\x07\x05\x02\x02\x20\x00\x00\x04\x03\x09\x04\x00\x00"},
+ {0x40, 0xA0, 0x08B5, 0x0000, 0x0010, 0x0010,
+ "\x01\x24\x00\xC1\x01\x01\x22\x00\x01\x21\xFF\x01\x23\x00\xC1\x82"},
+ {0x40, 0xA0, 0x08C5, 0x0000, 0x000F, 0x000F,
+ "\x01\x65\x00\x01\x66\x00\x01\x67\x00\x01\x69\x00\x01\x68\x00"},
+ {0x40, 0xA0, 0x0043, 0x0000, 0x0003, 0x0003, "\x02\x09\x00"},
+ {0x40, 0xA0, 0x0900, 0x0000, 0x0010, 0x0010,
+ "\x02\x0A\x6D\x00\x02\x08\x03\x00\x02\x0A\x43\x00\x02\x0A\x94\x00"},
+ {0x40, 0xA0, 0x0910, 0x0000, 0x0010, 0x0010,
+ "\x02\x0A\xBB\x00\x02\x0B\xBE\x00\x02\x0B\xBF\x00\x02\x0B\xC0\x00"},
+ {0x40, 0xA0, 0x0920, 0x0000, 0x0010, 0x0010,
+ "\x02\x0B\xC1\x00\x02\x0B\xC2\x00\x02\x0B\xC3\x00\x02\x0B\xC4\x00"},
+ {0x40, 0xA0, 0x0930, 0x0000, 0x0010, 0x0010,
+ "\x02\x0B\xC5\x00\x02\x0B\xC6\x00\x02\x0B\xC7\x00\x02\x0B\xC8\x00"},
+ {0x40, 0xA0, 0x0940, 0x0000, 0x0010, 0x0010,
+ "\x02\x0B\xC9\x00\x02\x0B\xCA\x00\x02\x0B\xCB\x00\x02\x0B\xCC\x00"},
+ {0x40, 0xA0, 0x0950, 0x0000, 0x0008, 0x0008,
+ "\x02\x0B\xCD\x00\x02\x0B\xCE\x00"},
+ {0x40, 0xA0, 0x08D4, 0x0000, 0x0010, 0x0010,
+ "\x12\x0A\xFF\x07\x91\xFF\x06\x08\xFF\x09\x58\xFF\x07\x91\xFF\x06"},
+ {0x40, 0xA0, 0x08E4, 0x0000, 0x000A, 0x000A,
+ "\x08\xFF\x0B\x57\x01\x08\xFF\x01\x09\x00"},
+ {0x40, 0xA0, 0x0791, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xB6\xE0\x20\xE1\x6A\x7A\x7E\x79\x80\x7E\x7E\x7F\x80\x74"},
+ {0x40, 0xA0, 0x07A1, 0x0000, 0x0010, 0x0010,
+ "\x7E\x90\x7F\xE3\xF0\x74\x80\x90\x7F\xE4\xF0\xE4\xFF\xE5\x66\x65"},
+ {0x40, 0xA0, 0x07B1, 0x0000, 0x0010, 0x0010,
+ "\x65\x60\x43\xEF\xC3\x94\x08\x50\x3D\xE4\xFD\xE5\x66\x65\x65\x60"},
+ {0x40, 0xA0, 0x07C1, 0x0000, 0x0010, 0x0010,
+ "\x1B\xED\xC3\x94\x03\x50\x15\x74\x25\x25\x65\xF8\xE6\x90\x7F\xE5"},
+ {0x40, 0xA0, 0x07D1, 0x0000, 0x0010, 0x0010,
+ "\xF0\x05\x65\xE5\x65\x54\x3F\xF5\x65\x0D\x80\xDF\xED\x60\xCE\xFE"},
+ {0x40, 0xA0, 0x07E1, 0x0000, 0x0010, 0x0010,
+ "\xEE\xC3\x94\x03\x50\x08\xE4\x90\x7F\xE5\xF0\x0E\x80\xF2\x90\x7F"},
+ {0x40, 0xA0, 0x07F1, 0x0000, 0x0010, 0x0010,
+ "\xE5\xED\xF0\x0F\x80\xB7\xEF\x60\x08\x25\xE0\x25\xE0\x90\x7F\xB7"},
+ {0x40, 0xA0, 0x0801, 0x0000, 0x0001, 0x0001, "\xF0"},
+ {0x40, 0xA0, 0x0802, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0958, 0x0000, 0x0010, 0x0010,
+ "\xE5\x08\x60\x16\x14\x60\x2A\x80\x00\x12\x08\xFD\xEF\x65\x09\x60"},
+ {0x40, 0xA0, 0x0968, 0x0000, 0x0010, 0x0010,
+ "\x36\x12\x08\xFD\x8F\x09\xE4\xF5\x08\x22\xE5\x22\x60\x10\xD5\x22"},
+ {0x40, 0xA0, 0x0978, 0x0000, 0x0010, 0x0010,
+ "\x0D\xA2\xAF\x92\x06\xC2\xAF\x43\x21\x20\xA2\x06\x92\xAF\x05\x08"},
+ {0x40, 0xA0, 0x0988, 0x0000, 0x0010, 0x0010,
+ "\x22\xE5\x23\x60\x10\xD5\x23\x0D\xA2\xAF\x92\x06\xC2\xAF\x43\x21"},
+ {0x40, 0xA0, 0x0998, 0x0000, 0x0007, 0x0007,
+ "\x40\xA2\x06\x92\xAF\x05\x08"},
+ {0x40, 0xA0, 0x099F, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0B57, 0x0000, 0x0010, 0x0010,
+ "\xA2\xAF\x92\x06\xC2\xAF\x90\x7F\x98\xE5\x21\xF0\xA2\x06\x92\xAF"},
+ {0x40, 0xA0, 0x0B67, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0608, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xC8\xE0\x30\xE1\x03\x02\x06\x92\x90\x7F\xC9\xE0\xF5\x6A"},
+ {0x40, 0xA0, 0x0618, 0x0000, 0x0010, 0x0010,
+ "\xC3\xE4\x95\x68\xFF\x74\x01\x94\x00\xFE\xC3\xE5\x6A\x9F\xE4\x9E"},
+ {0x40, 0xA0, 0x0628, 0x0000, 0x0010, 0x0010,
+ "\x50\x68\xE4\xF5\x6B\xE5\x6B\xC3\x95\x6A\x50\x59\x74\xC3\x25\x6B"},
+ {0x40, 0xA0, 0x0638, 0x0000, 0x0010, 0x0010,
+ "\xF5\x82\xE4\x34\x7D\xF5\x83\xE0\x54\x0F\xFD\x60\x48\x74\xC0\x25"},
+ {0x40, 0xA0, 0x0648, 0x0000, 0x0010, 0x0010,
+ "\x6B\xF5\x82\xE4\x34\x7D\x90\x7F\xE3\xF0\x74\xC0\x25\x6B\xF5\x82"},
+ {0x40, 0xA0, 0x0658, 0x0000, 0x0010, 0x0010,
+ "\xE4\x34\x7D\xE5\x82\x90\x7F\xE4\xF0\xAF\x05\xED\x14\x60\x16\x14"},
+ {0x40, 0xA0, 0x0668, 0x0000, 0x0010, 0x0010,
+ "\x60\x0B\x14\x70\x18\x90\x7F\xE5\xE0\xFF\x12\x0A\x17\x90\x7F\xE5"},
+ {0x40, 0xA0, 0x0678, 0x0000, 0x0010, 0x0010,
+ "\xE0\xFF\x12\x0A\x17\x90\x7F\xE5\xE0\xFF\x12\x0A\x17\x74\x04\x25"},
+ {0x40, 0xA0, 0x0688, 0x0000, 0x000A, 0x000A,
+ "\x6B\xF5\x6B\x80\xA0\xE4\x90\x7F\xC9\xF0"},
+ {0x40, 0xA0, 0x0692, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x08EE, 0x0000, 0x0003, 0x0003, "\x01\x1D\x00"},
+ {0x40, 0xA0, 0x000B, 0x0000, 0x0003, 0x0003, "\x02\x0B\x84"},
+ {0x40, 0xA0, 0x0B84, 0x0000, 0x000D, 0x000D,
+ "\xC0\xE0\x05\x1D\xE5\x24\x60\x02\x15\x24\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x08FD, 0x0000, 0x0003, 0x0003, "\xAF\x1D\x22"},
+ {0x40, 0xA0, 0x0BAE, 0x0000, 0x0004, 0x0004, "\xE4\xF5\x1D\x22"},
+ {0x40, 0xA0, 0x08F1, 0x0000, 0x000B, 0x000B,
+ "\x01\x72\x01\x01\x73\x01\xC1\x85\x01\x74\x02"},
+ {0x40, 0xA0, 0x01FF, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xE9\xE0\x70\x03\x02\x02\xD4\x14\x70\x03\x02\x03\x4F\x24"},
+ {0x40, 0xA0, 0x020F, 0x0000, 0x0010, 0x0010,
+ "\xFE\x70\x03\x02\x03\xA8\x24\xFB\x70\x03\x02\x02\xCE\x14\x70\x03"},
+ {0x40, 0xA0, 0x021F, 0x0000, 0x0010, 0x0010,
+ "\x02\x02\xC8\x14\x70\x03\x02\x02\xBC\x14\x70\x03\x02\x02\xC2\x24"},
+ {0x40, 0xA0, 0x022F, 0x0000, 0x0010, 0x0010,
+ "\x05\x60\x03\x02\x03\xFA\x12\x0B\xB4\x40\x03\x02\x04\x05\x90\x7F"},
+ {0x40, 0xA0, 0x023F, 0x0000, 0x0010, 0x0010,
+ "\xEB\xE0\x24\xFE\x60\x16\x14\x60\x3F\x24\x02\x70\x67\x74\x01\x90"},
+ {0x40, 0xA0, 0x024F, 0x0000, 0x0010, 0x0010,
+ "\x7F\xD4\xF0\x74\xC0\x90\x7F\xD5\xF0\x02\x04\x05\x90\x7F\xEA\xE0"},
+ {0x40, 0xA0, 0x025F, 0x0000, 0x0010, 0x0010,
+ "\xFF\x12\x08\x63\x8B\x6A\x8A\x6B\x89\x6C\xEA\x49\x60\x11\xAE\x02"},
+ {0x40, 0xA0, 0x026F, 0x0000, 0x0010, 0x0010,
+ "\xEE\x90\x7F\xD4\xF0\xAF\x01\xEF\x90\x7F\xD5\xF0\x02\x04\x05\x90"},
+ {0x40, 0xA0, 0x027F, 0x0000, 0x0010, 0x0010,
+ "\x7F\xC4\x74\x01\xF0\x02\x04\x05\x90\x7F\xEA\xE0\xFF\x12\x09\xA0"},
+ {0x40, 0xA0, 0x028F, 0x0000, 0x0010, 0x0010,
+ "\x8B\x6A\x8A\x6B\x89\x6C\xEA\x49\x60\x11\xAE\x02\xEE\x90\x7F\xD4"},
+ {0x40, 0xA0, 0x029F, 0x0000, 0x0010, 0x0010,
+ "\xF0\xAF\x01\xEF\x90\x7F\xD5\xF0\x02\x04\x05\x90\x7F\xC4\x74\x01"},
+ {0x40, 0xA0, 0x02AF, 0x0000, 0x0010, 0x0010,
+ "\xF0\x02\x04\x05\x90\x7F\xC4\x74\x01\xF0\x02\x04\x05\x12\x0B\x76"},
+ {0x40, 0xA0, 0x02BF, 0x0000, 0x0010, 0x0010,
+ "\x02\x04\x05\x12\x0B\xA2\x02\x04\x05\x12\x0B\x9A\x02\x04\x05\x12"},
+ {0x40, 0xA0, 0x02CF, 0x0000, 0x0010, 0x0010,
+ "\x0B\x68\x02\x04\x05\x12\x0B\xB6\x40\x03\x02\x04\x05\x90\x7F\xE8"},
+ {0x40, 0xA0, 0x02DF, 0x0000, 0x0010, 0x0010,
+ "\xE0\x24\x7F\x60\x24\x14\x60\x31\x24\x02\x70\x5B\xA2\x03\xE4\x33"},
+ {0x40, 0xA0, 0x02EF, 0x0000, 0x0010, 0x0010,
+ "\xFF\x25\xE0\xFF\xA2\x00\xE4\x33\x4F\x90\x7F\x00\xF0\xE4\xA3\xF0"},
+ {0x40, 0xA0, 0x02FF, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xB5\x74\x02\xF0\x02\x04\x05\xE4\x90\x7F\x00\xF0\xA3\xF0"},
+ {0x40, 0xA0, 0x030F, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xB5\x74\x02\xF0\x02\x04\x05\x90\x7F\xEC\xE0\xF4\x54\x80"},
+ {0x40, 0xA0, 0x031F, 0x0000, 0x0010, 0x0010,
+ "\xFF\xC4\x54\x0F\xFF\xE0\x54\x07\x2F\x25\xE0\x24\xB4\xF5\x82\xE4"},
+ {0x40, 0xA0, 0x032F, 0x0000, 0x0010, 0x0010,
+ "\x34\x7F\xF5\x83\xE0\x54\xFD\x90\x7F\x00\xF0\xE4\xA3\xF0\x90\x7F"},
+ {0x40, 0xA0, 0x033F, 0x0000, 0x0010, 0x0010,
+ "\xB5\x74\x02\xF0\x02\x04\x05\x90\x7F\xC4\x74\x01\xF0\x02\x04\x05"},
+ {0x40, 0xA0, 0x034F, 0x0000, 0x0010, 0x0010,
+ "\x12\x0B\xB8\x40\x03\x02\x04\x05\x90\x7F\xE8\xE0\x24\xFE\x60\x1C"},
+ {0x40, 0xA0, 0x035F, 0x0000, 0x0010, 0x0010,
+ "\x24\x02\x60\x03\x02\x04\x05\x90\x7F\xEA\xE0\xB4\x01\x05\xC2\x03"},
+ {0x40, 0xA0, 0x036F, 0x0000, 0x0010, 0x0010,
+ "\x02\x04\x05\x90\x7F\xC4\x74\x01\xF0\x02\x04\x05\x90\x7F\xEA\xE0"},
+ {0x40, 0xA0, 0x037F, 0x0000, 0x0010, 0x0010,
+ "\x70\x1F\x90\x7F\xEC\xE0\xF4\x54\x80\xFF\xC4\x54\x0F\xFF\xE0\x54"},
+ {0x40, 0xA0, 0x038F, 0x0000, 0x0010, 0x0010,
+ "\x07\x2F\x25\xE0\x24\xB4\xF5\x82\xE4\x34\x7F\xF5\x83\xE4\xF0\x80"},
+ {0x40, 0xA0, 0x039F, 0x0000, 0x0010, 0x0010,
+ "\x65\x90\x7F\xC4\x74\x01\xF0\x80\x5D\x12\x0B\xBA\x50\x58\x90\x7F"},
+ {0x40, 0xA0, 0x03AF, 0x0000, 0x0010, 0x0010,
+ "\xE8\xE0\x24\xFE\x60\x17\x24\x02\x70\x4C\x90\x7F\xEA\xE0\xB4\x01"},
+ {0x40, 0xA0, 0x03BF, 0x0000, 0x0010, 0x0010,
+ "\x04\xD2\x03\x80\x41\x90\x7F\xC4\x74\x01\xF0\x80\x39\x90\x7F\xEA"},
+ {0x40, 0xA0, 0x03CF, 0x0000, 0x0010, 0x0010,
+ "\xE0\x70\x20\x90\x7F\xEC\xE0\xF4\x54\x80\xFF\xC4\x54\x0F\xFF\xE0"},
+ {0x40, 0xA0, 0x03DF, 0x0000, 0x0010, 0x0010,
+ "\x54\x07\x2F\x25\xE0\x24\xB4\xF5\x82\xE4\x34\x7F\xF5\x83\x74\x01"},
+ {0x40, 0xA0, 0x03EF, 0x0000, 0x0010, 0x0010,
+ "\xF0\x80\x13\x90\x7F\xC4\x74\x01\xF0\x80\x0B\x12\x0B\xBC\x50\x06"},
+ {0x40, 0xA0, 0x03FF, 0x0000, 0x000D, 0x000D,
+ "\x90\x7F\xC4\x74\x01\xF0\x90\x7F\xB4\xE0\x44\x02\xF0"},
+ {0x40, 0xA0, 0x040C, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x09E1, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xDE\x74\x06\xF0\x90\x7F\xDF\x74\x04\xF0\x90\x7F\xDD\x74"},
+ {0x40, 0xA0, 0x09F1, 0x0000, 0x0010, 0x0010,
+ "\x18\xF0\x90\x7F\xB6\x74\x02\xF0\x90\x7F\xB8\xF0\x90\x7F\xBA\xF0"},
+ {0x40, 0xA0, 0x0A01, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xBC\xF0\x90\x7F\xBE\xF0\x90\x7F\xC0\xF0\x90\x7F\xC2\xF0"},
+ {0x40, 0xA0, 0x0A11, 0x0000, 0x0006, 0x0006, "\xE4\x90\x7F\xC9\xF0\x22"},
+ {0x40, 0xA0, 0x0B91, 0x0000, 0x0009, 0x0009,
+ "\x90\x7F\xAF\xE0\x44\x08\xF0\xD3\x22"},
+ {0x40, 0xA0, 0x0BB2, 0x0000, 0x0002, 0x0002, "\xD3\x22"},
+ {0x40, 0xA0, 0x0BB4, 0x0000, 0x0002, 0x0002, "\xD3\x22"},
+ {0x40, 0xA0, 0x0B9A, 0x0000, 0x0008, 0x0008,
+ "\x90\x7F\xEA\xE0\xF5\x76\xD3\x22"},
+ {0x40, 0xA0, 0x0B68, 0x0000, 0x000E, 0x000E,
+ "\x90\x7F\x00\xE5\x76\xF0\x90\x7F\xB5\x74\x01\xF0\xD3\x22"},
+ {0x40, 0xA0, 0x0BA2, 0x0000, 0x0008, 0x0008,
+ "\x90\x7F\xEA\xE0\xF5\x75\xD3\x22"},
+ {0x40, 0xA0, 0x0B76, 0x0000, 0x000E, 0x000E,
+ "\x90\x7F\x00\xE5\x75\xF0\x90\x7F\xB5\x74\x01\xF0\xD3\x22"},
+ {0x40, 0xA0, 0x0BB6, 0x0000, 0x0002, 0x0002, "\xD3\x22"},
+ {0x40, 0xA0, 0x0BB8, 0x0000, 0x0002, 0x0002, "\xD3\x22"},
+ {0x40, 0xA0, 0x0BBA, 0x0000, 0x0002, 0x0002, "\xD3\x22"},
+ {0x40, 0xA0, 0x0BBC, 0x0000, 0x0002, 0x0002, "\xD3\x22"},
+ {0x40, 0xA0, 0x0A6D, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\xD2"},
+ {0x40, 0xA0, 0x0A7D, 0x0000, 0x0010, 0x0010,
+ "\x01\x53\x91\xEF\x90\x7F\xAB\x74\x01\xF0\xD0\x86\xD0\x84\xD0\x85"},
+ {0x40, 0xA0, 0x0A8D, 0x0000, 0x0007, 0x0007,
+ "\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x0A43, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\x90"},
+ {0x40, 0xA0, 0x0A53, 0x0000, 0x0010, 0x0010,
+ "\x7F\xC4\xE4\xF0\x53\x91\xEF\x90\x7F\xAB\x74\x04\xF0\xD0\x86\xD0"},
+ {0x40, 0xA0, 0x0A63, 0x0000, 0x000A, 0x000A,
+ "\x84\xD0\x85\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x0803, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\xC0"},
+ {0x40, 0xA0, 0x0813, 0x0000, 0x0001, 0x0001, "\xD0"},
+ {0x40, 0xA0, 0x0814, 0x0000, 0x0010, 0x0010,
+ "\x53\x91\xEF\x90\x7F\xAB\x74\x02\xF0\x30\x05\x14\x15\x72\xE5\x72"},
+ {0x40, 0xA0, 0x0824, 0x0000, 0x0010, 0x0010,
+ "\x70\x2E\x43\x21\x10\xC2\x05\xC3\x74\x1E\x95\x74\xF5\x72\x80\x20"},
+ {0x40, 0xA0, 0x0834, 0x0000, 0x0010, 0x0010,
+ "\xD5\x72\x1D\x53\x21\xEF\xD2\x05\xE5\x73\x25\x74\xF5\x74\x64\x02"},
+ {0x40, 0xA0, 0x0844, 0x0000, 0x0010, 0x0010,
+ "\x60\x05\xE5\x74\xB4\x1C\x06\xE5\x73\xF4\x04\xF5\x73\x85\x74\x72"},
+ {0x40, 0xA0, 0x0854, 0x0000, 0x000F, 0x000F,
+ "\xD0\xD0\xD0\x86\xD0\x84\xD0\x85\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x0ABB, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\x53"},
+ {0x40, 0xA0, 0x0ACB, 0x0000, 0x0010, 0x0010,
+ "\x91\xEF\x90\x7F\xAB\x74\x10\xF0\xD0\x86\xD0\x84\xD0\x85\xD0\x82"},
+ {0x40, 0xA0, 0x0ADB, 0x0000, 0x0005, 0x0005, "\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x0BBE, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0A94, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\xD2"},
+ {0x40, 0xA0, 0x0AA4, 0x0000, 0x0010, 0x0010,
+ "\x04\x53\x91\xEF\x90\x7F\xAB\x74\x08\xF0\xD0\x86\xD0\x84\xD0\x85"},
+ {0x40, 0xA0, 0x0AB4, 0x0000, 0x0007, 0x0007,
+ "\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x0BBF, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BC0, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BC1, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BC2, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BC3, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BC4, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BC5, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BC6, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BC7, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BC8, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BC9, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BCA, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BCB, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BCC, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BCD, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BCE, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0B26, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xD6\xE0\x30\xE7\x12\xE0\x44\x01\xF0\x7F\x14\x7E\x00\x12"},
+ {0x40, 0xA0, 0x0B36, 0x0000, 0x000A, 0x000A,
+ "\x0B\x40\x90\x7F\xD6\xE0\x54\xFE\xF0\x22"},
+ {0x40, 0xA0, 0x0B05, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xD6\xE0\x44\x80\xF0\x43\x87\x01\x00\x00\x00\x00\x00\x22"},
+ {0x40, 0xA0, 0x0AE0, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xD6\xE0\x54\xFB\xF0\xE0\x44\x08\xF0\x30\x06\x04\xE0\x44"},
+ {0x40, 0xA0, 0x0AF0, 0x0000, 0x0010, 0x0010,
+ "\x02\xF0\x7F\xF4\x7E\x01\x12\x0B\x40\x90\x7F\xD6\xE0\x54\xF7\xF0"},
+ {0x40, 0xA0, 0x0B00, 0x0000, 0x0005, 0x0005, "\xE0\x44\x04\xF0\x22"},
+ {0x40, 0xA0, 0x09A0, 0x0000, 0x0002, 0x0002, "\x8F\x6D"},
+ {0x40, 0xA0, 0x09A2, 0x0000, 0x0010, 0x0010,
+ "\xE4\xF5\x6E\x75\x6F\xFF\x75\x70\x01\x75\x71\xF9\xAB\x6F\xAA\x70"},
+ {0x40, 0xA0, 0x09B2, 0x0000, 0x0010, 0x0010,
+ "\xA9\x71\x90\x00\x01\x12\x06\xAC\xB4\x03\x1D\xAF\x6E\x05\x6E\xEF"},
+ {0x40, 0xA0, 0x09C2, 0x0000, 0x0010, 0x0010,
+ "\xB5\x6D\x01\x22\x12\x06\x93\x7E\x00\x29\xFF\xEE\x3A\xA9\x07\x75"},
+ {0x40, 0xA0, 0x09D2, 0x0000, 0x000E, 0x000E,
+ "\x6F\xFF\xF5\x70\x89\x71\x80\xD4\x7B\x00\x7A\x00\x79\x00"},
+ {0x40, 0xA0, 0x09E0, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0863, 0x0000, 0x0010, 0x0010,
+ "\xE4\xFE\x75\x6F\xFF\x75\x70\x01\x75\x71\xD2\xAB\x6F\xAA\x70\xA9"},
+ {0x40, 0xA0, 0x0873, 0x0000, 0x0010, 0x0010,
+ "\x71\x90\x00\x01\x12\x06\xAC\x64\x02\x70\x2D\xAD\x06\x0E\xED\xB5"},
+ {0x40, 0xA0, 0x0883, 0x0000, 0x0010, 0x0010,
+ "\x07\x01\x22\x90\x00\x02\x12\x06\xD9\x85\xF0\x6D\xF5\x6E\x62\x6D"},
+ {0x40, 0xA0, 0x0893, 0x0000, 0x0010, 0x0010,
+ "\xE5\x6D\x62\x6E\xE5\x6E\x62\x6D\x29\xFD\xE5\x6D\x3A\xA9\x05\x75"},
+ {0x40, 0xA0, 0x08A3, 0x0000, 0x000E, 0x000E,
+ "\x6F\xFF\xF5\x70\x89\x71\x80\xC3\x7B\x00\x7A\x00\x79\x00"},
+ {0x40, 0xA0, 0x08B1, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0B40, 0x0000, 0x0010, 0x0010,
+ "\x8E\x6A\x8F\x6B\xE5\x6B\x15\x6B\xAE\x6A\x70\x02\x15\x6A\x4E\x60"},
+ {0x40, 0xA0, 0x0B50, 0x0000, 0x0007, 0x0007,
+ "\x05\x12\x0B\x15\x80\xEE\x22"},
+ {0x40, 0xA0, 0x0B15, 0x0000, 0x0010, 0x0010,
+ "\x74\x00\xF5\x86\x90\xFD\xA5\x7C\x05\xA3\xE5\x82\x45\x83\x70\xF9"},
+ {0x40, 0xA0, 0x0B25, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0000, 0x0000, 0x0003, 0x0003, "\x02\x05\x7C"},
+ {0x40, 0xA0, 0x057C, 0x0000, 0x000C, 0x000C,
+ "\x78\x7F\xE4\xF6\xD8\xFD\x75\x81\x76\x02\x05\xC3"},
+ {0x40, 0xA0, 0x0693, 0x0000, 0x0010, 0x0010,
+ "\xBB\x01\x06\x89\x82\x8A\x83\xE0\x22\x50\x02\xE7\x22\xBB\xFE\x02"},
+ {0x40, 0xA0, 0x06A3, 0x0000, 0x0009, 0x0009,
+ "\xE3\x22\x89\x82\x8A\x83\xE4\x93\x22"},
+ {0x40, 0xA0, 0x06AC, 0x0000, 0x0010, 0x0010,
+ "\xBB\x01\x0C\xE5\x82\x29\xF5\x82\xE5\x83\x3A\xF5\x83\xE0\x22\x50"},
+ {0x40, 0xA0, 0x06BC, 0x0000, 0x0010, 0x0010,
+ "\x06\xE9\x25\x82\xF8\xE6\x22\xBB\xFE\x06\xE9\x25\x82\xF8\xE2\x22"},
+ {0x40, 0xA0, 0x06CC, 0x0000, 0x000D, 0x000D,
+ "\xE5\x82\x29\xF5\x82\xE5\x83\x3A\xF5\x83\xE4\x93\x22"},
+ {0x40, 0xA0, 0x06D9, 0x0000, 0x0010, 0x0010,
+ "\xBB\x01\x10\xE5\x82\x29\xF5\x82\xE5\x83\x3A\xF5\x83\xE0\xF5\xF0"},
+ {0x40, 0xA0, 0x06E9, 0x0000, 0x0010, 0x0010,
+ "\xA3\xE0\x22\x50\x09\xE9\x25\x82\xF8\x86\xF0\x08\xE6\x22\xBB\xFE"},
+ {0x40, 0xA0, 0x06F9, 0x0000, 0x0010, 0x0010,
+ "\x0A\xE9\x25\x82\xF8\xE2\xF5\xF0\x08\xE2\x22\xE5\x83\x2A\xF5\x83"},
+ {0x40, 0xA0, 0x0709, 0x0000, 0x0008, 0x0008,
+ "\xE9\x93\xF5\xF0\xA3\xE9\x93\x22"},
+ {0x40, 0xA0, 0x0711, 0x0000, 0x0006, 0x0006, "\x8A\x83\x89\x82\xE4\x73"},
+ {0x40, 0xA0, 0x0588, 0x0000, 0x0010, 0x0010,
+ "\x02\x04\x0D\xE4\x93\xA3\xF8\xE4\x93\xA3\x40\x03\xF6\x80\x01\xF2"},
+ {0x40, 0xA0, 0x0598, 0x0000, 0x0010, 0x0010,
+ "\x08\xDF\xF4\x80\x29\xE4\x93\xA3\xF8\x54\x07\x24\x0C\xC8\xC3\x33"},
+ {0x40, 0xA0, 0x05A8, 0x0000, 0x0010, 0x0010,
+ "\xC4\x54\x0F\x44\x20\xC8\x83\x40\x04\xF4\x56\x80\x01\x46\xF6\xDF"},
+ {0x40, 0xA0, 0x05B8, 0x0000, 0x0010, 0x0010,
+ "\xE4\x80\x0B\x01\x02\x04\x08\x10\x20\x40\x80\x90\x08\xB2\xE4\x7E"},
+ {0x40, 0xA0, 0x05C8, 0x0000, 0x0010, 0x0010,
+ "\x01\x93\x60\xBC\xA3\xFF\x54\x3F\x30\xE5\x09\x54\x1F\xFE\xE4\x93"},
+ {0x40, 0xA0, 0x05D8, 0x0000, 0x0010, 0x0010,
+ "\xA3\x60\x01\x0E\xCF\x54\xC0\x25\xE0\x60\xA8\x40\xB8\xE4\x93\xA3"},
+ {0x40, 0xA0, 0x05E8, 0x0000, 0x0010, 0x0010,
+ "\xFA\xE4\x93\xA3\xF8\xE4\x93\xA3\xC8\xC5\x82\xC8\xCA\xC5\x83\xCA"},
+ {0x40, 0xA0, 0x05F8, 0x0000, 0x0010, 0x0010,
+ "\xF0\xA3\xC8\xC5\x82\xC8\xCA\xC5\x83\xCA\xDF\xE9\xDE\xE7\x80\xBE"},
+ {0x40, 0xA0, 0x08FC, 0x0000, 0x0001, 0x0001, "\x00"},
+ {0x40, 0xA0, 0x7F92, 0x0000, 0x0001, 0x0001, "\x01"},
+ {0x40, 0xA0, 0x7F92, 0x0000, 0x0001, 0x0001, "\x00"},
+ {0x00, 0x05, 0x0002, 0x0000, 0x0000, 0x0000, ""},
+ {0x00, 0x09, 0x0001, 0x0000, 0x0000, 0x0000, ""},
+ {0x00, 0x00, 0x0000, 0x0000, 0x0000, 0x0000, NULL}
+};