Bringing usb_davicom to life: part 1 of 3:
* Unfortunately I have to rollback r42712 completely because it was "the attempt in the wrong direction" and the working version was already implemented on top of previous revision. Just fixed version and code style refactored one are coming soon. Please be patient. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42747 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -33,11 +33,8 @@
|
||||
#define NSR 0x01 // Network status
|
||||
#define RCR 0x05 // RX Control
|
||||
#define PAR 0x10 // 6 bits - Physical address (MAC)
|
||||
#define GPCR 0x1E // GPIO pins direction
|
||||
#define GPR 0x1F // GPIO pins data
|
||||
#define VID 0x28 // Vendor ID (16bit)
|
||||
#define PID 0x2A // Product ID (16bit)
|
||||
#define CHIPR 0x2C // Chip revision
|
||||
#define GPCR 0x1E // General purpose control
|
||||
#define GPR 0x1F // General purpose
|
||||
|
||||
#define NCR_EXT_PHY 0x80 // External PHY
|
||||
#define NCR_FDX 0x08 // Full duplex
|
||||
@@ -63,7 +60,7 @@
|
||||
|
||||
|
||||
status_t
|
||||
DavicomDevice::_ReadRegister(uint8 reg, size_t size, void* buffer)
|
||||
DavicomDevice::_ReadRegister(uint8 reg, size_t size, uint8* buffer)
|
||||
{
|
||||
if (size > 255) return B_BAD_VALUE;
|
||||
size_t actualLength;
|
||||
@@ -187,6 +184,14 @@ DavicomDevice::Open(uint32 flags)
|
||||
return result;
|
||||
}
|
||||
|
||||
// setup state notifications
|
||||
result = gUSBModule->queue_interrupt(fNotifyEndpoint, fNotifyBuffer,
|
||||
kNotifyBufferSize, _NotifyCallback, this);
|
||||
if(result != B_OK) {
|
||||
TRACE_ALWAYS("Error of requesting notify interrupt:%#010x\n", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
fNonBlocking = (flags & O_NONBLOCK) == O_NONBLOCK;
|
||||
fOpen = true;
|
||||
return result;
|
||||
@@ -357,11 +362,9 @@ DavicomDevice::Control(uint32 op, void *buffer, size_t length)
|
||||
{
|
||||
switch (op) {
|
||||
case ETHER_INIT:
|
||||
TRACE_ALWAYS("ETHER_INIT\n");
|
||||
return B_OK;
|
||||
|
||||
case ETHER_GETADDR:
|
||||
TRACE_ALWAYS("ETHER_GETADDR\n");
|
||||
memcpy(buffer, &fMACAddress, sizeof(fMACAddress));
|
||||
return B_OK;
|
||||
|
||||
@@ -392,7 +395,6 @@ DavicomDevice::Control(uint32 op, void *buffer, size_t length)
|
||||
return B_OK;
|
||||
|
||||
case ETHER_GET_LINK_STATE:
|
||||
TRACE_ALWAYS("ETHER_GET_LINK_STATE\n");
|
||||
return GetLinkState((ether_link_state *)buffer);
|
||||
#endif
|
||||
|
||||
@@ -431,10 +433,10 @@ DavicomDevice::Removed()
|
||||
status_t
|
||||
DavicomDevice::SetupDevice(bool deviceReplugged)
|
||||
{
|
||||
/* First of all, we need to know the MAC address */
|
||||
ether_address address;
|
||||
status_t result = ReadMACAddress(&address);
|
||||
if(result != B_OK) {
|
||||
TRACE_ALWAYS("Error reading MAC address:%#010x\n", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -443,45 +445,18 @@ DavicomDevice::SetupDevice(bool deviceReplugged)
|
||||
address.ebyte[3], address.ebyte[4], address.ebyte[5]);
|
||||
|
||||
if(deviceReplugged) {
|
||||
// this might be the same device that was replugged - read the MAC
|
||||
// address (which should be at the same index) to make sure
|
||||
// this might be the same device that was replugged - read the MAC address
|
||||
// (which should be at the same index) to make sure
|
||||
if(memcmp(&address, &fMACAddress, sizeof(address)) != 0) {
|
||||
TRACE_ALWAYS("Cannot replace device with MAC address:"
|
||||
"%02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
fMACAddress.ebyte[0], fMACAddress.ebyte[1],
|
||||
fMACAddress.ebyte[2], fMACAddress.ebyte[3],
|
||||
fMACAddress.ebyte[4], fMACAddress.ebyte[5]);
|
||||
"%02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
fMACAddress.ebyte[0], fMACAddress.ebyte[1], fMACAddress.ebyte[2],
|
||||
fMACAddress.ebyte[3], fMACAddress.ebyte[4], fMACAddress.ebyte[5]);
|
||||
return B_BAD_VALUE; // is not the same
|
||||
}
|
||||
} else
|
||||
fMACAddress = address;
|
||||
|
||||
|
||||
/* Read the product ID, vendor ID, and chip revision (not used so far, but
|
||||
I feel the quirks coming in sooner or later !) */
|
||||
|
||||
uint16 vidpid[3];
|
||||
vidpid[2] = 0; // We overwrite only the fist byte of this one.
|
||||
|
||||
result = _ReadRegister(VID, 5, vidpid);
|
||||
if (result != B_OK)
|
||||
TRACE_ALWAYS("Error reading CHIPR: %#010x.\n", result);
|
||||
else
|
||||
TRACE_ALWAYS("Chip %#04x:%#04x revision %d\n", vidpid[0], vidpid[1],
|
||||
vidpid[2]);
|
||||
|
||||
// setup state notifications (we need this to get linkup/linkdown events)
|
||||
result = gUSBModule->queue_interrupt(fNotifyEndpoint, fNotifyBuffer,
|
||||
kNotifyBufferSize, _NotifyCallback, this);
|
||||
if(result != B_OK) {
|
||||
TRACE_ALWAYS("Error of requesting notify interrupt:%#010x\n", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// TODO enable "wakeup" at the device level or we'll never get anything !
|
||||
// TODO check if link was already up before enabling interrupts. If so, we
|
||||
// need to notify the network stack right now.
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -557,41 +532,34 @@ DavicomDevice::_SetupEndpoints()
|
||||
int writeEndpoint = -1;
|
||||
|
||||
for(size_t ep = 0; ep < interface->endpoint_count; ep++) {
|
||||
usb_endpoint_descriptor *epd = interface->endpoint[ep].descr;
|
||||
|
||||
// Is it an interrupt enpoint ?
|
||||
if((epd->attributes & USB_ENDPOINT_ATTR_MASK)
|
||||
== USB_ENDPOINT_ATTR_INTERRUPT) {
|
||||
notifyEndpoint = ep;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Is it a bulk one ?
|
||||
if((epd->attributes & USB_ENDPOINT_ATTR_MASK) != USB_ENDPOINT_ATTR_BULK) {
|
||||
TRACE_ALWAYS("Error: USB endpoint type %#04x is unknown.\n",
|
||||
epd->attributes);
|
||||
continue;
|
||||
}
|
||||
usb_endpoint_descriptor *epd = interface->endpoint[ep].descr;
|
||||
if((epd->attributes & USB_ENDPOINT_ATTR_MASK) == USB_ENDPOINT_ATTR_INTERRUPT) {
|
||||
notifyEndpoint = ep;
|
||||
continue;
|
||||
}
|
||||
|
||||
// If so, which direction ?
|
||||
if((epd->endpoint_address & USB_ENDPOINT_ADDR_DIR_IN)
|
||||
== USB_ENDPOINT_ADDR_DIR_IN) {
|
||||
readEndpoint = ep;
|
||||
continue;
|
||||
}
|
||||
if((epd->attributes & USB_ENDPOINT_ATTR_MASK) != USB_ENDPOINT_ATTR_BULK) {
|
||||
TRACE_ALWAYS("Error: USB endpoint type %#04x is unknown.\n", epd->attributes);
|
||||
continue;
|
||||
}
|
||||
|
||||
if((epd->endpoint_address & USB_ENDPOINT_ADDR_DIR_OUT)
|
||||
== USB_ENDPOINT_ADDR_DIR_OUT) {
|
||||
writeEndpoint = ep;
|
||||
continue;
|
||||
}
|
||||
if((epd->endpoint_address & USB_ENDPOINT_ADDR_DIR_IN)
|
||||
== USB_ENDPOINT_ADDR_DIR_IN) {
|
||||
readEndpoint = ep;
|
||||
continue;
|
||||
}
|
||||
|
||||
if((epd->endpoint_address & USB_ENDPOINT_ADDR_DIR_OUT)
|
||||
== USB_ENDPOINT_ADDR_DIR_OUT) {
|
||||
writeEndpoint = ep;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Did we find all the needed endpoints ?
|
||||
if (notifyEndpoint == -1 || readEndpoint == -1 || writeEndpoint == -1) {
|
||||
TRACE_ALWAYS("Error: not all USB endpoints were found: "
|
||||
"notify:%d; read:%d; write:%d\n", notifyEndpoint, readEndpoint,
|
||||
writeEndpoint);
|
||||
"notify:%d; read:%d; write:%d\n",
|
||||
notifyEndpoint, readEndpoint, writeEndpoint);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
@@ -608,8 +576,7 @@ DavicomDevice::_SetupEndpoints()
|
||||
status_t
|
||||
DavicomDevice::ReadMACAddress(ether_address_t *address)
|
||||
{
|
||||
status_t result = _ReadRegister(PAR, sizeof(ether_address),
|
||||
(uint8*)address);
|
||||
status_t result = _ReadRegister(PAR, sizeof(ether_address), (uint8*)address);
|
||||
if(result != B_OK) {
|
||||
TRACE_ALWAYS("Error of reading MAC address:%#010x\n", result);
|
||||
return result;
|
||||
@@ -720,6 +687,7 @@ DavicomDevice::_NotifyCallback(void *cookie, int32 status, void *data,
|
||||
*/
|
||||
}
|
||||
|
||||
// parse data in overriden class
|
||||
device->OnNotify(actualLength);
|
||||
|
||||
// schedule next notification buffer
|
||||
@@ -733,10 +701,9 @@ status_t
|
||||
DavicomDevice::StartDevice()
|
||||
{
|
||||
uint8 registerValue = 0;
|
||||
status_t result;
|
||||
|
||||
|
||||
/* disable loopback */
|
||||
result = _ReadRegister(NCR, 1, ®isterValue);
|
||||
status_t result = _ReadRegister(NCR, 1, ®isterValue);
|
||||
if (result != B_OK) {
|
||||
TRACE_ALWAYS("Error reading NCR: %#010x.\n", result);
|
||||
return result;
|
||||
@@ -769,7 +736,7 @@ DavicomDevice::StartDevice()
|
||||
TRACE_ALWAYS("Error reading GPCR: %#010x.\n", result);
|
||||
return result;
|
||||
}
|
||||
registerValue |= GPCR_GEP_CNTL0;
|
||||
registerValue &= GPCR_GEP_CNTL0;
|
||||
result = _Write1Register(GPCR, registerValue);
|
||||
if (result != B_OK) {
|
||||
TRACE_ALWAYS("Error writing %#02X to GPCR: %#010x.\n", registerValue, result);
|
||||
@@ -820,7 +787,7 @@ DavicomDevice::OnNotify(uint32 actualLength)
|
||||
TRACE("Link is now up at %s Mb/s\n",
|
||||
(fNotifyBuffer[0] & NSR_SPEED) ? "10" : "100");
|
||||
} else
|
||||
TRACE("Link is now down.\n");
|
||||
TRACE("Link is now down");
|
||||
}
|
||||
|
||||
if (rxOverflow)
|
||||
@@ -859,7 +826,7 @@ DavicomDevice::GetLinkState(ether_link_state *linkState)
|
||||
linkState->media |= IFM_ACTIVE;
|
||||
result = _ReadRegister(NCR, 1, ®isterValue);
|
||||
if (result != B_OK) {
|
||||
TRACE_ALWAYS("Error reading NCR register: %s\n",strerror(result));
|
||||
TRACE_ALWAYS("Error reading NCR register! %x\n",result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,8 +23,7 @@
|
||||
|
||||
class DavicomDevice {
|
||||
public:
|
||||
DavicomDevice(usb_device device,
|
||||
const char *description);
|
||||
DavicomDevice(usb_device device, const char *description);
|
||||
virtual ~DavicomDevice();
|
||||
|
||||
status_t InitCheck() { return fStatus; };
|
||||
@@ -55,10 +54,8 @@ static void _NotifyCallback(void *cookie, int32 status,
|
||||
|
||||
status_t _SetupEndpoints();
|
||||
|
||||
status_t _ReadRegister(uint8 reg, size_t size,
|
||||
void* buffer);
|
||||
status_t _WriteRegister(uint8 reg, size_t size,
|
||||
uint8* buffer);
|
||||
status_t _ReadRegister(uint8 reg, size_t size, uint8* buffer);
|
||||
status_t _WriteRegister(uint8 reg, size_t size, uint8* buffer);
|
||||
status_t _Write1Register(uint8 reg, uint8 buffer);
|
||||
|
||||
static const int kFrameSize = 1518;
|
||||
|
||||
@@ -35,9 +35,9 @@ char *gDeviceNames[MAX_DEVICES + 1];
|
||||
usb_module_info *gUSBModule = NULL;
|
||||
|
||||
usb_support_descriptor gSupportedDevices[] = {
|
||||
{ 0, 0, 0, 0x0fe6, 0x8101}, // "Supereal SR9600"
|
||||
{ 0, 0, 0, 0x0fe6, 0x8101}, // "Sunrising JP108"
|
||||
{ 0, 0, 0, 0x07aa, 0x9601}, // "Corega FEther USB-TXC"
|
||||
{ 0, 0, 0, 0x0a46, 0x9601}, // "Davicom DM9601"
|
||||
{ 0, 0, 0, 0x0a46, 0x9601}, // "Davicom USB-100"
|
||||
{ 0, 0, 0, 0x0a46, 0x6688}, // "ZT6688 USB NIC"
|
||||
{ 0, 0, 0, 0x0a46, 0x0268}, // "ShanTou ST268 USB NIC"
|
||||
{ 0, 0, 0, 0x0a46, 0x8515}, // "ADMtek ADM8515 USB NIC"
|
||||
@@ -67,22 +67,14 @@ create_davicom_device(usb_device device)
|
||||
#define IDS(__vendor, __product) (((__vendor) << 16) | (__product))
|
||||
|
||||
switch(IDS(deviceDescriptor->vendor_id, deviceDescriptor->product_id)) {
|
||||
case IDS(0x0fe6, 0x8101):
|
||||
return new DavicomDevice(device, "Sunrising JP108");
|
||||
case IDS(0x07aa, 0x9601):
|
||||
return new DavicomDevice(device, "Corega FEther USB-TXC");
|
||||
case IDS(0x0a46, 0x9601):
|
||||
return new DavicomDevice(device, "Davicom USB-100");
|
||||
case IDS(0x0a46, 0x6688):
|
||||
return new DavicomDevice(device, "ZT6688 USB NIC");
|
||||
case IDS(0x0a46, 0x0268):
|
||||
return new DavicomDevice(device, "ShanTou ST268 USB NIC");
|
||||
case IDS(0x0a46, 0x8515):
|
||||
return new DavicomDevice(device, "ADMtek ADM8515 USB NIC");
|
||||
case IDS(0x0a47, 0x9601):
|
||||
return new DavicomDevice(device, "Hirose USB-100");
|
||||
case IDS(0x0a46, 0x9000):
|
||||
return new DavicomDevice(device, "DM9000E");
|
||||
case IDS(0x0fe6, 0x8101): return new DavicomDevice(device, "Sunrising JP108");
|
||||
case IDS(0x07aa, 0x9601): return new DavicomDevice(device, "Corega FEther USB-TXC");
|
||||
case IDS(0x0a46, 0x9601): return new DavicomDevice(device, "Davicom USB-100");
|
||||
case IDS(0x0a46, 0x6688): return new DavicomDevice(device, "ZT6688 USB NIC");
|
||||
case IDS(0x0a46, 0x0268): return new DavicomDevice(device, "ShanTou ST268 USB NIC");
|
||||
case IDS(0x0a46, 0x8515): return new DavicomDevice(device, "ADMtek ADM8515 USB NIC");
|
||||
case IDS(0x0a47, 0x9601): return new DavicomDevice(device, "Hirose USB-100");
|
||||
case IDS(0x0a46, 0x9000): return new DavicomDevice(device, "DM9000E");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user