How to access vendorID and ProductID in an USB Interface FD?

This forum is for general developer support questions.
Post Reply
User avatar
abalaban
Beta Tester
Beta Tester
Posts: 456
Joined: Mon Dec 20, 2010 2:09 pm
Location: France
Contact:

How to access vendorID and ProductID in an USB Interface FD?

Post by abalaban »

I wonder how I would be able to able to access vendorID and productID of the device from inside an Interface FD ? The entry point of my FD is RunInterface() which receives a Startup message with an Interface descriptor without information of the vendor and product IDs. I've looked toward USBIntGetConfiguration() but I'm not sure it's the way to go.
AmigaOne X1000 running AOS 4 beta
AmigaOne XE/G4
Amiga 1200/PPC 603e + BVision PPC
User avatar
tonyw
AmigaOS Core Developer
AmigaOS Core Developer
Posts: 1479
Joined: Wed Mar 09, 2011 1:36 pm
Location: Sydney, Australia

Re: How to access vendorID and ProductID in an USB Interface

Post by tonyw »

The supported way would be to use expansion.library calls. But expansion.lib only works on PCI devices AFAIK, it might not deal with all USB controllers.

Here is a way of finding out if a given vendor/device exists (not quite what you wanted but it might help).

ExpansionBase = IExec->OpenLibrary ("expansion.library", 53L);
IExpansion = (struct ExpansionIFace *)(IExec->GetInterface ((struct Library *)ExpansionBase, "main", 1, NULL));
IPCI = (struct PCIIFace *)(IExec->GetInterface ((struct Library *)ExpansionBase, "pci", 1, NULL));
pcidev = IPCI->FindDeviceTags (FDT_VendorID, VendorID,
FDT_DeviceID, DeviceID,
// FDT_Index, N,
TAG_DONE);

pcidev is non-NULL if the search was successful. You can also add a counter N in the tags, to return the Nth entry.
Having pcidev, you can read the Config registers; the first two 16-bit words are the Vendor and DeviceID. If you already have pcidev (or some equivalent), you may be able to look up the config registers using that. The worst that can happen is that it will crash or give a machine check exception.
cheers
tony
User avatar
abalaban
Beta Tester
Beta Tester
Posts: 456
Joined: Mon Dec 20, 2010 2:09 pm
Location: France
Contact:

Re: How to access vendorID and ProductID in an USB Interface

Post by abalaban »

@Tony thank you for the answer but that's not exactly what I'm looking for.

In fact I'm trying to write an usbfd that will be automatically instanciated by the USB stack when products from a given vendor is plugged in. As such I wrote an fdclass according to that: try to load my driver in interface mode for the given vendor (try to look the overview from usbfd autodoc). Normally the USB stack can provide access to all those information however it seems that in interface mode I can only access to my own interface informations not the whole device information.
That's bad because I wanted to be able to support several product of this vendor in the same driver (only a few subtle differences exists in those different products which can be dealt with using simple switch at strategic places) but for this I need access to the vendor and product ID's...

EDIT: I don't think expansion.library would be of any use here, but I'll give it a look anyway, we never know...
AmigaOne X1000 running AOS 4 beta
AmigaOne XE/G4
Amiga 1200/PPC 603e + BVision PPC
User avatar
tonyw
AmigaOS Core Developer
AmigaOS Core Developer
Posts: 1479
Joined: Wed Mar 09, 2011 1:36 pm
Location: Sydney, Australia

Re: How to access vendorID and ProductID in an USB Interface

Post by tonyw »

Do you have the latest USB documentation?

The latest I have is dated 11th Aout 2011.
cheers
tony
User avatar
abalaban
Beta Tester
Beta Tester
Posts: 456
Joined: Mon Dec 20, 2010 2:09 pm
Location: France
Contact:

Re: How to access vendorID and ProductID in an USB Interface

Post by abalaban »

I think I do, but can't confirm. I have at least the one included in the SDK, haven't check if, as a betatester, I had an update or not. Anyway, are you asking this because you saw an answer to my problem?

Oh and I tried and experimented that GetConfiguration() method as I anticipated it unfortunately does not give me access to device and vendor IDs, only information about the current interface. :/
AmigaOne X1000 running AOS 4 beta
AmigaOne XE/G4
Amiga 1200/PPC 603e + BVision PPC
User avatar
LyleHaze
AmigaOS Core Developer
AmigaOS Core Developer
Posts: 525
Joined: Sat Jun 18, 2011 4:06 pm
Location: North Florida, near the Big Bend

Re: How to access vendorID and ProductID in an USB Interface

Post by LyleHaze »

Abalaban,
I can help.
I have a short prog here that will probably show what you're looking for.

This is NOT a "proper" program, it's just a short hack for sniffing around for unclaimed USB interfaces.

This is also my first attempt at using the "hidden" tags to prevent ugly code dumps. Wish me luck.
Hidden Text - Click to Show :

Code: Select all

/*
** sniff.c
**
** makefile:
** Sniff : sniff.c
**	gcc -o Sniff sniff.c
**
** gives some details on any unclaimed USB devices
**
*/

#include <proto/exec.h>
#include <proto/usbsys.h>
#include <usb/usb.h>
#include <stdio.h>

struct USBBusStringDesc
{
	struct USBBusDscHead	Head;
	UWORD	string[];
};

struct Library *USBSysBase = NULL;
struct USBSysIFace *IUSBSys = NULL;
struct IORequest *usbopenreq = NULL;
struct USBIOReq *usbio = NULL;
struct MsgPort *mp = NULL;

int openall(void);
void closeall(void);
void detaildeviceraw(struct UsbRawInterface *);

int main(int argc, char **argv)
{
    struct UsbRawInterface *prevrawifc, *rawifc;
    struct UsbInterface *ifc;
    int class = 0xFF;
    int subclass = 0xFF;
    uint8 waste[255];

    prevrawifc = NULL;
    ifc = NULL;

    if(0 != openall())
    {
        printf("openall() Failed\n");
        return(-1);
    }

    for(class=0;class<256;class++)
    {
        for(subclass=0;subclass<256;subclass++)
        {
            do
            {
                rawifc = IUSBSys->USBFindInterface(prevrawifc,USBA_Class,class,USBA_Subclass,subclass,TAG_END);
                if(prevrawifc)
                {
                    IUSBSys->USBUnlockInterface(prevrawifc);
                }
                if(rawifc)
                {
                    detaildeviceraw(rawifc);
                    fgets((STRPTR)waste,255,stdin);
                }
                prevrawifc = rawifc;
            }while(rawifc);
        }
    }
    closeall();
    return(0);
}

int openall(void)
{
    int8 error;

    mp = IExec->CreateMsgPort();
    if(mp == NULL)
    {
        printf("CreateMsgPort() failed\n");
        return(-1);
    }

    usbopenreq=IExec->CreateIORequest(mp,sizeof(struct IORequest));
    if(usbopenreq == NULL)
    {
        printf("CreateIORequest failed\n");
        closeall();
        return(-1);
    }

    error=IExec->OpenDevice("usbsys.device",0,usbopenreq,0);
    if(error)
    {
        printf("OpenDevice() failed\n");
        closeall();
        return(-1);
    }
    USBSysBase = (struct Library *)usbopenreq->io_Device;
    IUSBSys =(struct USBSysIFace *)IExec->GetInterface(USBSysBase,"main",1,NULL);
    if(IUSBSys == NULL)
    {
        printf("GetInterface() failed\n");
        closeall();
        return(-1);
    }    
    usbio = IUSBSys->USBAllocRequestA(usbopenreq,NULL);
    if(usbio == NULL)
    {
        printf("USBAllocRequestA() failed\n");
        closeall();
        return(-1);        
    }
    return(0);  //success
}

void closeall(void)
{
    if(usbio)
        IUSBSys->USBFreeRequest(usbio);
    if(IUSBSys)
        IExec->DropInterface((struct Interface *)IUSBSys);
    if(USBSysBase)
        IExec->CloseDevice(usbopenreq);
    if(usbopenreq)
        IExec->DeleteIORequest(usbopenreq);
    if(mp)
        IExec->DeleteMsgPort(mp);
}

void detaildeviceraw(struct UsbRawInterface *rifc)
{
    struct USBBusDevDsc *devdsc = NULL;
    struct USBBusIntDsc *intdsc = NULL;
    struct USBBusStringDesc *strdsc = NULL;
    LONG nameindex = 0;
    uint8 buffer[255];
    
    printf("Found unclaimed interface:\n");

    IUSBSys->USBGetRawInterfaceAttrs(rifc,USBA_DeviceDesc,(ULONG)&devdsc,TAG_END);
    if(devdsc != NULL)
    {
        printf("Device USB Protocol    0X%4.4X\n",LE_WORD(devdsc->dd_USBVer));
        printf("Device Class           0X%2.2X\n",devdsc->dd_Class);
        printf("Device Subclass        0X%2.2X\n",devdsc->dd_Subclass);
        printf("Device Protocol        0X%2.2X\n",devdsc->dd_Protocol);
        printf("Device Max Endpoint 0 packet size 0X%2.2X\n",devdsc->dd_MaxPacketSize0);
        printf("Device Vendor ID       0X%4.4X\n",LE_WORD(devdsc->dd_VendorID));
        printf("Device Product         0X%4.4X\n",LE_WORD(devdsc->dd_Product));
        printf("Device Release Number  0X%4.4X\n",LE_WORD(devdsc->dd_DevVer));

        strdsc=NULL;
        IUSBSys->USBGetRawInterfaceAttrs(rifc,USBA_VendorName,(ULONG)&strdsc,TAG_END);
        if(strdsc)
        {
            if(stringdesc2string(strdsc,buffer,255))
            {
                printf("Vendor Name %s\n",buffer);
            }
            IUSBSys->USBFreeDescriptors((struct USBBusDscHead *)strdsc);
        }

        strdsc=NULL;
        IUSBSys->USBGetRawInterfaceAttrs(rifc,USBA_ProductName,(ULONG)&strdsc,TAG_END);
        if(strdsc)
        {
            if(stringdesc2string(strdsc,buffer,255))
            {
                printf("Product Name %s\n",buffer);
            }
            IUSBSys->USBFreeDescriptors((struct USBBusDscHead *)strdsc);
        }

        strdsc=NULL;
        IUSBSys->USBGetRawInterfaceAttrs(rifc,USBA_SerialName,(ULONG)&strdsc,TAG_END);
        if(strdsc)
        {
            if(stringdesc2string(strdsc,buffer,255))
            {
                printf("Serial Name %s\n",buffer);
            }
            IUSBSys->USBFreeDescriptors((struct USBBusDscHead *)strdsc);
        }

        strdsc=NULL;
        IUSBSys->USBGetRawInterfaceAttrs(rifc,USBA_InterfaceName,(ULONG)&strdsc,TAG_END);
        if(strdsc)
        {
            if(stringdesc2string(strdsc,buffer,255))
            {
                printf("Interface Name %s\n",buffer);
            }
            IUSBSys->USBFreeDescriptors((struct USBBusDscHead *)strdsc);
        }

        printf("Device Configurations %2.2X\n",devdsc->dd_NumConfigs);
        IUSBSys->USBFreeDescriptors((struct USBBusDscHead *)&devdsc);
    }
    else
    {
        printf("result equals zero\n");
    }
    IUSBSys->USBGetRawInterfaceAttrs(rifc,USBA_InterfaceDesc,(ULONG)&intdsc,TAG_END);
    if(intdsc != NULL)
    {
        printf("Interface ID           0X%2.2X\n",intdsc->id_InterfaceID);
        printf("Interface AltSetting   0X%2.2X\n",intdsc->id_AltSetting);
        printf("Interface NumEndPoints 0X%2.2X\n",intdsc->id_NumEndPoints);
        printf("Interface Class        0X%2.2X\n",intdsc->id_Class);
        printf("Interface Subclass     0X%2.2X\n",intdsc->id_Subclass);
        printf("Interface Protocol     0X%2.2X\n",intdsc->id_Protocol);
        IUSBSys->USBFreeDescriptors((struct USBBusDscHead *)&intdsc);
    }

}

int stringdesc2string(struct USBBusStringDesc *sd,char *buffer,int maxlen)
{
    int retval = 0;
    int nameindex;
    
    if(sd)
    {
        retval = (sd->Head.dh_Length - 2) / 2;
        if(retval >= maxlen)
        {
            retval = maxlen - 1;
        }
        for(nameindex=0;nameindex<retval;nameindex++)
        {
            buffer[nameindex]=(UBYTE)LE_WORD(sd->string[nameindex]);
        }
        buffer[nameindex]=0;
    }
    return(retval);
}
I hope it helps,
Lyle
User avatar
abalaban
Beta Tester
Beta Tester
Posts: 456
Joined: Mon Dec 20, 2010 2:09 pm
Location: France
Contact:

Re: How to access vendorID and ProductID in an USB Interface

Post by abalaban »

Thank you, it seems to be what I was looking for! That's a strange workaround, but anyway it does what I want, so...
AmigaOne X1000 running AOS 4 beta
AmigaOne XE/G4
Amiga 1200/PPC 603e + BVision PPC
User avatar
LyleHaze
AmigaOS Core Developer
AmigaOS Core Developer
Posts: 525
Joined: Sat Jun 18, 2011 4:06 pm
Location: North Florida, near the Big Bend

Re: How to access vendorID and ProductID in an USB Interface

Post by LyleHaze »

My code was cleaned up and brought up to date by Tjitte 'OldFart' de Wolff.

It's much better than it was.. Still for the same purpose, to find and detail unclaimed USB interfaces.
Thank You, Mr. de Wolff!

His revised program is here:
USBSniff.c :

Code: Select all

/*
** sniff.c
**
** gives some details on any unclaimed USB devices
**
*/

#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/usbsys.h>
#include <usb/usb.h>
#include <stdio.h>

struct USBBusStringDesc
{
	struct USBBusDscHead Head;
	UWORD string[];
};

struct USBSysIFace *IUSBSys;

#define ELSE_ERROR(Text) else IDOS->Printf("Failed to %s\n", Text)

void detaildeviceraw(struct UsbRawInterface *);

int main(int argc, char **argv)
{
	int RC = RETURN_FAIL;

	struct MsgPort *mp = IExec->AllocSysObjectTags(ASOT_PORT, TAG_END);

	if (mp)
	{
		struct IORequest *usbopenreq = IExec->AllocSysObjectTags(ASOT_IOREQUEST, ASOIOR_ReplyPort, mp, TAG_END);

		if (usbopenreq)
		{
			if (IExec->OpenDevice("usbsys.device", 0, usbopenreq, 0) == 0)
			{
				IUSBSys = (struct USBSysIFace *)IExec->GetInterface((struct Library *)usbopenreq->io_Device, "main", 1, NULL);

				struct USBIOReq *usbio = IUSBSys->USBAllocRequestA(usbopenreq, NULL);

				if (usbio)
				{
					uint8 waste[255];
					uint8 class = 0;
					IDOS->Printf("=== Start of scan ===\n");

					do
					{
						uint8 subclass = 0;

						do
						{
							struct UsbRawInterface *rawifc = IUSBSys->USBFindInterface(NULL, USBA_Class, class,
								USBA_Subclass, subclass,
								TAG_END),
								*prevrawifc;
								while (rawifc)
								{
									detaildeviceraw(rawifc);

									fgets((STRPTR)waste, 255, stdin);

									prevrawifc = rawifc;
									rawifc = IUSBSys->USBFindInterface(rawifc, USBA_Class, class,
										USBA_Subclass, subclass,
										TAG_END);
									IUSBSys->USBUnlockInterface(prevrawifc);
								}

								subclass++;
						} while (subclass);

						class++;
					} while (class);

					RC = RETURN_OK;
					IDOS->Printf("=== Scan finished ===\n");
					IUSBSys->USBFreeRequest(usbio);
				}
				ELSE_ERROR("Allocate Request (USB)");

				IExec->CloseDevice(usbopenreq);
			}
			ELSE_ERROR("Open Device");

			IExec->FreeSysObject(ASOT_IOREQUEST, usbopenreq);
		}
		ELSE_ERROR("Allocate SysObject (ASOT_IOREQUEST)");

		IExec->FreeSysObject(ASOT_PORT, mp);
	}
	ELSE_ERROR("Allocate SysObject (ASOT_PORT)");

	return RC;
}

void detaildeviceraw(struct UsbRawInterface *rifc)
{
	struct USBBusDevDsc *devdsc = NULL;
	struct USBBusIntDsc *intdsc = NULL;
	struct USBBusStringDesc *strdsc = NULL;
	LONG nameindex = 0;
	uint8 buffer[255];

	IDOS->Printf("Found unclaimed interface:\n");

	IUSBSys->USBGetRawInterfaceAttrs(rifc,USBA_DeviceDesc,(ULONG)&devdsc,TAG_END);
	if(devdsc != NULL)
	{
		IDOS->Printf("Device USB Protocol 0X%4.4X\n",LE_WORD(devdsc->dd_USBVer));
		IDOS->Printf("Device Class 0X%2.2X\n",devdsc->dd_Class);
		IDOS->Printf("Device Subclass 0X%2.2X\n",devdsc->dd_Subclass);
		IDOS->Printf("Device Protocol 0X%2.2X\n",devdsc->dd_Protocol);
		IDOS->Printf("Device Max Endpoint 0 packet size 0X%2.2X\n",devdsc->dd_MaxPacketSize0);
		IDOS->Printf("Device Vendor ID 0X%4.4X\n",LE_WORD(devdsc->dd_VendorID));
		IDOS->Printf("Device Product 0X%4.4X\n",LE_WORD(devdsc->dd_Product));
		IDOS->Printf("Device Release Number 0X%4.4X\n",LE_WORD(devdsc->dd_DevVer));

		strdsc=NULL;
		IUSBSys->USBGetRawInterfaceAttrs(rifc,USBA_VendorName,(ULONG)&strdsc,TAG_END);
		if(strdsc)
		{
			if(stringdesc2string(strdsc,buffer,255))
			{
				IDOS->Printf("Vendor Name %s\n",buffer);
			}
			IUSBSys->USBFreeDescriptors((struct USBBusDscHead *)strdsc);
		}

		strdsc=NULL;
		IUSBSys->USBGetRawInterfaceAttrs(rifc,USBA_ProductName,(ULONG)&strdsc,TAG_END);
		if(strdsc)
		{
			if(stringdesc2string(strdsc,buffer,255))
			{
				IDOS->Printf("Product Name %s\n",buffer);
			}
			IUSBSys->USBFreeDescriptors((struct USBBusDscHead *)strdsc);
		}

		strdsc=NULL;
		IUSBSys->USBGetRawInterfaceAttrs(rifc,USBA_SerialName,(ULONG)&strdsc,TAG_END);
		if(strdsc)
		{
			if(stringdesc2string(strdsc,buffer,255))
			{
				IDOS->Printf("Serial Name %s\n",buffer);
			}
			IUSBSys->USBFreeDescriptors((struct USBBusDscHead *)strdsc);
		}

		strdsc=NULL;
		IUSBSys->USBGetRawInterfaceAttrs(rifc,USBA_InterfaceName,(ULONG)&strdsc,TAG_END);
		if(strdsc)
		{
			if(stringdesc2string(strdsc,buffer,255))
			{
				IDOS->Printf("Interface Name %s\n",buffer);
			}
			IUSBSys->USBFreeDescriptors((struct USBBusDscHead *)strdsc);
		}

		IDOS->Printf("Device Configurations %2.2X\n",devdsc->dd_NumConfigs);
		IUSBSys->USBFreeDescriptors((struct USBBusDscHead *)&devdsc);
	}
	else
	{
		IDOS->Printf("result equals zero\n");
	}
	IUSBSys->USBGetRawInterfaceAttrs(rifc,USBA_InterfaceDesc,(ULONG)&intdsc,TAG_END);
	if(intdsc != NULL)
	{
		IDOS->Printf("Interface ID 0X%2.2X\n",intdsc->id_InterfaceID);
		IDOS->Printf("Interface AltSetting 0X%2.2X\n",intdsc->id_AltSetting);
		IDOS->Printf("Interface NumEndPoints 0X%2.2X\n",intdsc->id_NumEndPoints);
		IDOS->Printf("Interface Class 0X%2.2X\n",intdsc->id_Class);
		IDOS->Printf("Interface Subclass 0X%2.2X\n",intdsc->id_Subclass);
		IDOS->Printf("Interface Protocol 0X%2.2X\n",intdsc->id_Protocol);
		IUSBSys->USBFreeDescriptors((struct USBBusDscHead *)&intdsc);
	}

}

int stringdesc2string(struct USBBusStringDesc *sd,char *buffer,int maxlen)
{
	int retval = 0;
	int nameindex;

	if(sd)
	{
		retval = (sd->Head.dh_Length - 2) / 2;
		if(retval >= maxlen)
		{
			retval = maxlen - 1;
		}
		for(nameindex=0;nameindex<retval;nameindex++)
		{
			buffer[nameindex]=(UBYTE)LE_WORD(sd->string[nameindex]);
		}
		buffer[nameindex]=0;
	}

	return(retval);
}

/*
** ================================================================================================
** === End of File ================================================================================
** ================================================================================================
*/
Post Reply