diff options
Diffstat (limited to 'kernel/drv/oss_usb')
-rw-r--r-- | kernel/drv/oss_usb/.config | 3 | ||||
-rw-r--r-- | kernel/drv/oss_usb/.devices | 28 | ||||
-rw-r--r-- | kernel/drv/oss_usb/.name | 1 | ||||
-rw-r--r-- | kernel/drv/oss_usb/.params | 2 | ||||
-rwxr-xr-x | kernel/drv/oss_usb/midisport1x1_fw.h | 677 | ||||
-rwxr-xr-x | kernel/drv/oss_usb/midisport2x2_fw.h | 756 | ||||
-rw-r--r-- | kernel/drv/oss_usb/oss_usb.c | 2505 | ||||
-rw-r--r-- | kernel/drv/oss_usb/oss_usb.man | 56 | ||||
-rw-r--r-- | kernel/drv/oss_usb/ossusb.h | 246 | ||||
-rw-r--r-- | kernel/drv/oss_usb/ossusb_audio.c | 1425 | ||||
-rw-r--r-- | kernel/drv/oss_usb/ossusb_midi.c | 442 | ||||
-rw-r--r-- | kernel/drv/oss_usb/ossusb_midisport.c | 957 | ||||
-rw-r--r-- | kernel/drv/oss_usb/ossusb_ymhmidi.c | 653 | ||||
-rwxr-xr-x | kernel/drv/oss_usb/oxygen8_fw.h | 678 |
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} +}; |