Added AX88772A/B harwdare support
* Synchronized with FreeBSD driver - added support for AX88772A and AX88772B chipsets; * Some new hardware ids added; * Fixed devices lookup routine.
This commit is contained in:
@@ -21,22 +21,21 @@
|
||||
|
||||
|
||||
struct DeviceInfo {
|
||||
union Id {
|
||||
uint16 fIds[2];
|
||||
uint32 fKey;
|
||||
} fId;
|
||||
uint16 fIds[2];
|
||||
|
||||
enum Type {
|
||||
AX88172 = 0,
|
||||
AX88772 = 1,
|
||||
AX88178 = 2
|
||||
AX88178 = 2,
|
||||
AX88772A = 3,
|
||||
AX88772B = 4
|
||||
} fType;
|
||||
|
||||
const char* fName;
|
||||
|
||||
inline uint16 VendorId() { return fId.fIds[0]; }
|
||||
inline uint16 ProductId() { return fId.fIds[1]; }
|
||||
inline uint32 Key() { return fId.fKey; }
|
||||
inline uint16 VendorId() { return fIds[0]; }
|
||||
inline uint16 ProductId() { return fIds[1]; }
|
||||
inline uint32 Key() { return fIds[0] << 16 | fIds[1]; }
|
||||
};
|
||||
|
||||
|
||||
@@ -83,7 +82,7 @@ virtual status_t SetPromiscuousMode(bool bOn);
|
||||
uint32 EthernetCRC32(const uint8* buffer, size_t length);
|
||||
virtual status_t ModifyMulticastTable(bool add,
|
||||
ether_address_t* group);
|
||||
status_t ReadMACAddress(ether_address_t *address);
|
||||
virtual status_t ReadMACAddress(ether_address_t *address);
|
||||
status_t ReadRXControlRegister(uint16 *rxcontrol);
|
||||
status_t WriteRXControlRegister(uint16 rxcontrol);
|
||||
|
||||
@@ -115,7 +114,7 @@ virtual status_t ModifyMulticastTable(bool add,
|
||||
int32 fStatusWrite;
|
||||
sem_id fNotifyReadSem;
|
||||
sem_id fNotifyWriteSem;
|
||||
|
||||
|
||||
uint8 * fNotifyBuffer;
|
||||
uint32 fNotifyBufferLength;
|
||||
sem_id fLinkStateChangeSem;
|
||||
|
||||
@@ -51,7 +51,8 @@ enum ASIXVendorRequests {
|
||||
READ_PHY_SEL_STATE = 0x21, // AX88772
|
||||
WRITE_PHY_SEL = 0x22, // AX88772
|
||||
READ_MIIS_IF_STATE = 0x21, // AX88178
|
||||
WRITE_MIIS_IF_STATE = 0x22 // AX88178
|
||||
WRITE_MIIS_IF_STATE = 0x22, // AX88178
|
||||
WRITE_RXCONTROL_CFG = 0x2A // AX88772B
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -128,9 +128,13 @@ enum AX88772_SoftwareReset {
|
||||
|
||||
// Software PHY Select Status
|
||||
enum AX88772_SoftwarePHYSelStatus {
|
||||
SW_PHY_SEL_STATUS_EXT = 0x00,
|
||||
SW_PHY_SEL_STATUS_INT = 0x01,
|
||||
SW_PHY_SEL_STATUS_ASEL = 0x02
|
||||
SW_PHY_SEL_STATUS_EXT = 0x00,
|
||||
SW_PHY_SEL_STATUS_INT = 0x01,
|
||||
SW_PHY_SEL_STATUS_ASEL = 0x02,
|
||||
SW_PHY_SEL_STATUS_SS_MII = 0x04,
|
||||
SW_PHY_SEL_STATUS_SS_RVRS_MII = 0x08,
|
||||
SW_PHY_SEL_STATUS_SS_RVRS_GMII = 0x0C,
|
||||
SW_PHY_SEL_STATUS_SS_ENB = 0x10
|
||||
};
|
||||
|
||||
|
||||
@@ -153,6 +157,38 @@ enum AX88772_BBState {
|
||||
LINK_STATE_MDINT = 0x08
|
||||
};
|
||||
|
||||
// EEPROM Map.
|
||||
enum AX88772B_EEPROM {
|
||||
EEPROM_772B_NODE_ID = 0x04
|
||||
};
|
||||
|
||||
enum AX88772B_MFB {
|
||||
AX88772B_MFB_2K = 0,
|
||||
AX88772B_MFB_4K = 1,
|
||||
AX88772B_MFB_6K = 2,
|
||||
AX88772B_MFB_8K = 3,
|
||||
AX88772B_MFB_16K = 4,
|
||||
AX88772B_MFB_20K = 5,
|
||||
AX88772B_MFB_24K = 6,
|
||||
AX88772B_MFB_32K = 7,
|
||||
AX88772B_MFB_Count = 8
|
||||
};
|
||||
|
||||
struct _AX88772B_MFB {
|
||||
size_t ByteCount;
|
||||
size_t Threshold;
|
||||
size_t Size;
|
||||
|
||||
} AX88772B_MFBTable[AX88772B_MFB_Count] = {
|
||||
{ 0x8000, 0x8001, 2048 },
|
||||
{ 0x8100, 0x8147, 4096 },
|
||||
{ 0x8200, 0x81EB, 6144 },
|
||||
{ 0x8300, 0x83D7, 8192 },
|
||||
{ 0x8400, 0x851E, 16384 },
|
||||
{ 0x8500, 0x8666, 20480 },
|
||||
{ 0x8600, 0x87AE, 24576 },
|
||||
{ 0x8700, 0x8A3D, 32768 }
|
||||
};
|
||||
|
||||
const uint16 maxFrameSize = 1536;
|
||||
|
||||
@@ -184,6 +220,35 @@ AX88772Device::InitDevice()
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
AX88772Device::ReadMACAddress(ether_address_t *address)
|
||||
{
|
||||
if (fDeviceInfo.fType != DeviceInfo::AX88772B)
|
||||
return ASIXDevice::ReadMACAddress(address);
|
||||
|
||||
// Auto-loaded default station address from internal ROM is
|
||||
// 00:00:00:00:00:00 such that an explicit access to EEPROM
|
||||
// is required to get real station address.
|
||||
for (size_t i = 0; i < sizeof(ether_address_t) / 2; i++) {
|
||||
size_t actual_length = 0;
|
||||
uint16 addr = 0;
|
||||
status_t result = gUSBModule->send_request(fDevice,
|
||||
USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_IN,
|
||||
READ_SROM, EEPROM_772B_NODE_ID + i, 0,
|
||||
sizeof(addr), &addr, &actual_length);
|
||||
if (result != B_OK) {
|
||||
TRACE_ALWAYS("Error reading MAC[%d] address:%#010x\n", i, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
address->ebyte[i * 2 + 0] = (uint8)addr;
|
||||
address->ebyte[i * 2 + 1] = (uint8)(addr >> 8);
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
AX88772Device::SetupDevice(bool deviceReplugged)
|
||||
{
|
||||
@@ -194,10 +259,51 @@ AX88772Device::SetupDevice(bool deviceReplugged)
|
||||
|
||||
result = fMII.Init(fDevice);
|
||||
|
||||
switch (fDeviceInfo.fType) {
|
||||
case DeviceInfo::AX88772A:
|
||||
result = _SetupAX88772A();
|
||||
break;
|
||||
case DeviceInfo::AX88772B:
|
||||
result = _SetupAX88772B();
|
||||
break;
|
||||
default:
|
||||
result = _SetupAX88772();
|
||||
break;
|
||||
}
|
||||
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
result = fMII.SetupPHY();
|
||||
if (result != B_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t actualLength = 0;
|
||||
result = gUSBModule->send_request(fDevice,
|
||||
USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
|
||||
WRITE_MEDIUM_MODE,
|
||||
MEDIUM_STATE_FD | MEDIUM_STATE_BIT2 |
|
||||
MEDIUM_STATE_RFC| MEDIUM_STATE_TFC |
|
||||
MEDIUM_STATE_RE | MEDIUM_STATE_PS_100,
|
||||
0, 0, 0, &actualLength);
|
||||
|
||||
if (result != B_OK) {
|
||||
TRACE_ALWAYS("Error of setting medium mode: %#010x\n", result);
|
||||
}
|
||||
|
||||
TRACE_RET(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
AX88772Device::_SetupAX88772()
|
||||
{
|
||||
size_t actualLength = 0;
|
||||
// enable GPIO2 - magic from FreeBSD's if_axe
|
||||
uint16 GPIOs = GPIO_OO_2EN | GPIO_IO_2 | GPIO_RSE;
|
||||
result = gUSBModule->send_request(fDevice,
|
||||
status_t result = gUSBModule->send_request(fDevice,
|
||||
USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
|
||||
WRITE_GPIOS, GPIOs, 0, 0, 0, &actualLength);
|
||||
|
||||
@@ -268,25 +374,124 @@ AX88772Device::SetupDevice(bool deviceReplugged)
|
||||
return result;
|
||||
}
|
||||
|
||||
result = fMII.SetupPHY();
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
AX88772Device::_WakeupPHY()
|
||||
{
|
||||
// select PHY
|
||||
bool useEmbeddedPHY = fMII.PHYID() == PHYIDEmbedded;
|
||||
uint16 selectPHY = useEmbeddedPHY ?
|
||||
SW_PHY_SEL_STATUS_INT : SW_PHY_SEL_STATUS_EXT;
|
||||
|
||||
selectPHY |= SW_PHY_SEL_STATUS_SS_MII | SW_PHY_SEL_STATUS_SS_ENB;
|
||||
|
||||
size_t actualLength = 0;
|
||||
status_t result = gUSBModule->send_request(fDevice,
|
||||
USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
|
||||
WRITE_PHY_SEL, selectPHY, 0, 0, 0, &actualLength);
|
||||
snooze(31000);
|
||||
|
||||
TRACE("Selecting %s PHY[%#02x].\n",
|
||||
useEmbeddedPHY ? "embedded" : "external", selectPHY);
|
||||
|
||||
if (result != B_OK) {
|
||||
TRACE_ALWAYS("Error of selecting PHY:%#010x\n", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
result = gUSBModule->send_request(fDevice,
|
||||
USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
|
||||
WRITE_MEDIUM_MODE,
|
||||
MEDIUM_STATE_FD | MEDIUM_STATE_BIT2 |
|
||||
MEDIUM_STATE_RFC| MEDIUM_STATE_TFC |
|
||||
MEDIUM_STATE_RE | MEDIUM_STATE_PS_100,
|
||||
0, 0, 0, &actualLength);
|
||||
struct SWReset {
|
||||
uint16 reset;
|
||||
bigtime_t delay;
|
||||
} resetCommands[] = {
|
||||
{ SW_RESET_IPRL | SW_RESET_IPPD, 250000 },
|
||||
{ SW_RESET_IPRL, 1000000 },
|
||||
{ SW_RESET_CLR, 31000 },
|
||||
{ SW_RESET_IPRL, 31000 }
|
||||
};
|
||||
|
||||
if (result != B_OK) {
|
||||
TRACE_ALWAYS("Error of setting medium mode: %#010x\n", result);
|
||||
for (size_t i = 0; i < _countof(resetCommands); i++) {
|
||||
result = gUSBModule->send_request(fDevice,
|
||||
USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
|
||||
WRITE_SOFT_RESET, resetCommands[i].reset,
|
||||
0, 0, 0, &actualLength);
|
||||
|
||||
snooze(resetCommands[i].delay);
|
||||
|
||||
if (result != B_OK) {
|
||||
TRACE_ALWAYS("Error of SW reset command %d:[%#04x]: %#010x\n",
|
||||
i, resetCommands[i].reset, result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
TRACE_RET(result);
|
||||
return result;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
AX88772Device::_SetupAX88772A()
|
||||
{
|
||||
// Reload EEPROM
|
||||
size_t actualLength = 0;
|
||||
status_t result = gUSBModule->send_request(fDevice,
|
||||
USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
|
||||
WRITE_GPIOS, GPIO_RSE, 0, 0, 0, &actualLength);
|
||||
|
||||
if (result != B_OK) {
|
||||
TRACE_ALWAYS("Error of reloading EEPROM: %#010x\n", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
result = _WakeupPHY();
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
result = WriteRXControlRegister(0);
|
||||
if (result != B_OK) {
|
||||
TRACE_ALWAYS("Error of writing %#04x RX Control:%#010x\n", 0, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
fIPG[0] = 0x15;
|
||||
fIPG[1] = 0x16;
|
||||
fIPG[2] = 0x1A;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
AX88772Device::_SetupAX88772B()
|
||||
{
|
||||
// Reload EEPROM
|
||||
size_t actualLength = 0;
|
||||
status_t result = gUSBModule->send_request(fDevice,
|
||||
USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
|
||||
WRITE_GPIOS, GPIO_RSE, 0, 0, 0, &actualLength);
|
||||
|
||||
if (result != B_OK) {
|
||||
TRACE_ALWAYS("Error of reloading EEPROM: %#010x\n", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
result = _WakeupPHY();
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
result = WriteRXControlRegister(0);
|
||||
if (result != B_OK) {
|
||||
TRACE_ALWAYS("Error of writing %#04x RX Control:%#010x\n", 0, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
fIPG[0] = 0x15;
|
||||
fIPG[1] = 0x16;
|
||||
fIPG[2] = 0x1A;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -306,6 +511,21 @@ AX88772Device::StartDevice()
|
||||
if (actualLength != sizeof(fIPG)) {
|
||||
TRACE_ALWAYS("Mismatch of written IPGs data. "
|
||||
"%d bytes of %d written.\n", actualLength, sizeof(fIPG));
|
||||
|
||||
}
|
||||
// AX88772B uses different maximum frame burst configuration.
|
||||
if (fDeviceInfo.fType == DeviceInfo::AX88772B) {
|
||||
result = gUSBModule->send_request(fDevice,
|
||||
USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
|
||||
WRITE_RXCONTROL_CFG,
|
||||
AX88772B_MFBTable[AX88772B_MFB_2K].ByteCount,
|
||||
AX88772B_MFBTable[AX88772B_MFB_2K].Threshold,
|
||||
0, 0, &actualLength);
|
||||
|
||||
if (result != B_OK) {
|
||||
TRACE_ALWAYS("Error of writing frame burst:%#010x\n", result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
uint16 rxcontrol = RXCTL_START | RXCTL_BROADCAST;
|
||||
|
||||
@@ -25,6 +25,12 @@ virtual status_t SetupDevice(bool deviceReplugged);
|
||||
virtual status_t StartDevice();
|
||||
virtual status_t OnNotify(uint32 actualLength);
|
||||
virtual status_t GetLinkState(ether_link_state *state);
|
||||
virtual status_t ReadMACAddress(ether_address_t *address);
|
||||
|
||||
status_t _WakeupPHY();
|
||||
status_t _SetupAX88772();
|
||||
status_t _SetupAX88772A();
|
||||
status_t _SetupAX88772B();
|
||||
};
|
||||
|
||||
#endif // _USB_AX88772_DEVICE_H_
|
||||
|
||||
@@ -35,33 +35,38 @@ mutex gDriverLock;
|
||||
// IMPORTANT: keep entries sorted by ids to let the
|
||||
// binary search lookup procedure work correctly !!!
|
||||
DeviceInfo gSupportedDevices[] = {
|
||||
{ { { 0x0411, 0x003d } }, DeviceInfo::AX88172, "Melco LUA-U2-KTX" },
|
||||
{ { { 0x04bb, 0x0930 } }, DeviceInfo::AX88178, "I/O Data ETG-US2" },
|
||||
{ { { 0x04f1, 0x3008 } }, DeviceInfo::AX88172, "JVC MP-PRX1" },
|
||||
{ { { 0x050d, 0x5055 } }, DeviceInfo::AX88178, "Belkin F5D5055" },
|
||||
{ { { 0x0557, 0x2009 } }, DeviceInfo::AX88172, "ATEN UC-210T" },
|
||||
{ { { 0x05ac, 0x1402 } }, DeviceInfo::AX88772, "Apple A1277" },
|
||||
{ { { 0x077b, 0x2226 } }, DeviceInfo::AX88172, "LinkSys USB 2.0" },
|
||||
{ { { 0x07aa, 0x0017 } }, DeviceInfo::AX88172, "Corega USB2TX" },
|
||||
{ { { 0x07b8, 0x420a } }, DeviceInfo::AX88172, "ABOCOM UF200" },
|
||||
{ { { 0x07d1, 0x3c05 } }, DeviceInfo::AX88772, "D-Link DUB-E100 rev.B1" },
|
||||
{ { { 0x0846, 0x1040 } }, DeviceInfo::AX88172, "NetGear USB 2.0 Ethernet" },
|
||||
{ { { 0x086e, 0x1920 } }, DeviceInfo::AX88172, "System TALKS SGC-X2UL" },
|
||||
{ { { 0x08dd, 0x90ff } }, DeviceInfo::AX88172, "Billionton USB2AR" },
|
||||
{ { { 0x0b95, 0x1720 } }, DeviceInfo::AX88172, "ASIX 88172 10/100" },
|
||||
{ { { 0x0b95, 0x1780 } }, DeviceInfo::AX88178, "ASIX 88178 10/100/1000" },
|
||||
{ { { 0x0b95, 0x7720 } }, DeviceInfo::AX88772, "ASIX 88772 10/100" },
|
||||
{ { { 0x0df6, 0x061c } }, DeviceInfo::AX88178, "Sitecom LN-028" },
|
||||
{ { { 0x1189, 0x0893 } }, DeviceInfo::AX88172, "Acer C&M EP-1427X-2" },
|
||||
{ { { 0x13b1, 0x0018 } }, DeviceInfo::AX88772, "Linksys USB200M rev.2" },
|
||||
{ { { 0x14ea, 0xab11 } }, DeviceInfo::AX88178, "Planex GU-1000T" },
|
||||
{ { { 0x1557, 0x7720 } }, DeviceInfo::AX88772, "OQO 01+ Ethernet" },
|
||||
{ { { 0x1631, 0x6200 } }, DeviceInfo::AX88172, "GoodWay USB2Ethernet" },
|
||||
{ { { 0x1737, 0x0039 } }, DeviceInfo::AX88178, "LinkSys 1000" },
|
||||
{ { { 0x2001, 0x1A00 } }, DeviceInfo::AX88172, "D-Link DUB-E100" },
|
||||
{ { { 0x2001, 0x3c05 } }, DeviceInfo::AX88772, "D-Link DUB-E100 rev.B1" },
|
||||
{ { { 0x6189, 0x182d } }, DeviceInfo::AX88172, "Sitecom LN-029" }
|
||||
};
|
||||
{ { 0x0411, 0x003d }, DeviceInfo::AX88172, "Melco LUA-U2-KTX" },
|
||||
{ { 0x0411, 0x006e }, DeviceInfo::AX88178, "Melco LUA3-U2-AGT" },
|
||||
{ { 0x04bb, 0x0930 }, DeviceInfo::AX88178, "I/O Data ETG-US2" },
|
||||
{ { 0x04f1, 0x3008 }, DeviceInfo::AX88172, "JVC MP-PRX1" },
|
||||
{ { 0x050d, 0x5055 }, DeviceInfo::AX88178, "Belkin F5D5055" },
|
||||
{ { 0x0557, 0x2009 }, DeviceInfo::AX88172, "ATEN UC-210T" },
|
||||
{ { 0x05ac, 0x1402 }, DeviceInfo::AX88772, "Apple A1277" },
|
||||
{ { 0x077b, 0x2226 }, DeviceInfo::AX88172, "LinkSys USB 2.0" },
|
||||
{ { 0x0789, 0x0160 }, DeviceInfo::AX88178, "Logitec LAN-GTJ/U2A" },
|
||||
{ { 0x07aa, 0x0017 }, DeviceInfo::AX88172, "Corega USB2TX" },
|
||||
{ { 0x07b8, 0x420a }, DeviceInfo::AX88172, "ABOCOM UF200" },
|
||||
{ { 0x07d1, 0x3c05 }, DeviceInfo::AX88772, "D-Link DUB-E100 rev.B1" },
|
||||
{ { 0x0846, 0x1040 }, DeviceInfo::AX88172, "NetGear USB 2.0 Ethernet" },
|
||||
{ { 0x086e, 0x1920 }, DeviceInfo::AX88172, "System TALKS SGC-X2UL" },
|
||||
{ { 0x08dd, 0x90ff }, DeviceInfo::AX88172, "Billionton USB2AR" },
|
||||
{ { 0x0b95, 0x1720 }, DeviceInfo::AX88172, "ASIX 88172 10/100" },
|
||||
{ { 0x0b95, 0x1780 }, DeviceInfo::AX88178, "ASIX 88178 10/100/1000" },
|
||||
{ { 0x0b95, 0x7720 }, DeviceInfo::AX88772, "ASIX 88772 10/100" },
|
||||
{ { 0x0b95, 0x772a }, DeviceInfo::AX88772A, "AX88772A 10/100" },
|
||||
{ { 0x0b95, 0x772b }, DeviceInfo::AX88772B, "AX88772B 10/100" },
|
||||
{ { 0x0b95, 0x7e2b }, DeviceInfo::AX88772B, "AX88772B 10/100" },
|
||||
{ { 0x0df6, 0x061c }, DeviceInfo::AX88178, "Sitecom LN-028" },
|
||||
{ { 0x1189, 0x0893 }, DeviceInfo::AX88172, "Acer C&M EP-1427X-2" },
|
||||
{ { 0x13b1, 0x0018 }, DeviceInfo::AX88772A, "Linksys USB200M rev.2" },
|
||||
{ { 0x14ea, 0xab11 }, DeviceInfo::AX88178, "Planex GU-1000T" },
|
||||
{ { 0x1557, 0x7720 }, DeviceInfo::AX88772, "OQO 01+ Ethernet" },
|
||||
{ { 0x1631, 0x6200 }, DeviceInfo::AX88172, "GoodWay USB2Ethernet" },
|
||||
{ { 0x1737, 0x0039 }, DeviceInfo::AX88178, "LinkSys 1000" },
|
||||
{ { 0x2001, 0x1A00 }, DeviceInfo::AX88172, "D-Link DUB-E100" },
|
||||
{ { 0x2001, 0x3c05 }, DeviceInfo::AX88772, "D-Link DUB-E100 rev.B1" },
|
||||
{ { 0x6189, 0x182d }, DeviceInfo::AX88172, "Sitecom LN-029" }
|
||||
};
|
||||
|
||||
|
||||
ASIXDevice *
|
||||
@@ -75,24 +80,26 @@ lookup_and_create_device(usb_device device)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TRACE("trying %#06x:%#06x.\n",
|
||||
TRACE("trying %#06x:%#06x.\n",
|
||||
deviceDescriptor->vendor_id, deviceDescriptor->product_id);
|
||||
|
||||
|
||||
// use binary search to lookup device in table
|
||||
DeviceInfo::Id id = { { deviceDescriptor->vendor_id,
|
||||
deviceDescriptor->product_id } };
|
||||
uint32 id = deviceDescriptor->vendor_id << 16
|
||||
| deviceDescriptor->product_id;
|
||||
int left = -1;
|
||||
int right = _countof(gSupportedDevices);
|
||||
while ((right - left) > 1) {
|
||||
int i = (left + right) / 2;
|
||||
((gSupportedDevices[i].Key() < id.fKey) ? left : right) = i;
|
||||
((gSupportedDevices[i].Key() < id) ? left : right) = i;
|
||||
}
|
||||
|
||||
if (gSupportedDevices[right].Key() == id.fKey) {
|
||||
if (gSupportedDevices[right].Key() == id) {
|
||||
switch (gSupportedDevices[right].fType) {
|
||||
case DeviceInfo::AX88172:
|
||||
return new AX88172Device(device, gSupportedDevices[right]);
|
||||
case DeviceInfo::AX88772:
|
||||
case DeviceInfo::AX88772A:
|
||||
case DeviceInfo::AX88772B:
|
||||
return new AX88772Device(device, gSupportedDevices[right]);
|
||||
case DeviceInfo::AX88178:
|
||||
return new AX88178Device(device, gSupportedDevices[right]);
|
||||
@@ -101,6 +108,8 @@ lookup_and_create_device(usb_device device)
|
||||
static_cast<int>(gSupportedDevices[right].fType));
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
TRACE_ALWAYS("Search for %#x failed %d-%d.\n", id, left, right);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -224,7 +233,7 @@ init_driver()
|
||||
const size_t count = _countof(gSupportedDevices);
|
||||
static usb_support_descriptor sDescriptors[count] = {{ 0 }};
|
||||
|
||||
for(size_t i = 0; i < count; i++) {
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
sDescriptors[i].vendor = gSupportedDevices[i].VendorId();
|
||||
sDescriptors[i].product = gSupportedDevices[i].ProductId();
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
|
||||
const uint8 kInvalidRequest = 0xff;
|
||||
const char* const kVersion = "ver.0.9.1";
|
||||
const char* const kVersion = "ver.0.10.1";
|
||||
extern usb_module_info *gUSBModule;
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user