PC fettling and repairs thread

Page may contain affiliate links. Please see terms for details.

Solocle

Über Member
Location
Poole
This was after turning my PC off...
Fs0vYqPWcAEhwdT?format=jpg&name=large.jpg

Was messing around with writing a USB Host Controller Driver.
 

MontyVeda

a short-tempered ill-controlled small-minded troll
Windows... just make your mind up!

fecking thing3.jpg
 

Solocle

Über Member
Location
Poole
I feel we have subtly differing ideas about "off".

ACPI G2/S5 power state. The only thing more off is G3, where you physically disconnect it from power. And the LED might still stay on, as it's running off a powered hub ^_^. But it definitely does this even when connected to the PC directly.

USB can stay powered even when the PC is off - I can charge my phone from it, for instance. Also how things such as wake-on-lan and waking on a keypress operate.

The behaviour is because I've been resetting and enumerating the USB devices, but not doing anything with them.
C++:
static void EnumerateHub(USBHub& roothb)
{
    usb_status_t status;
    if (USB_FAILED(status = roothb.Init()))
        return;
    for (size_t n = 1; n <= roothb.NumberPorts(); ++n)
    {
        if (roothb.PortConnected(n))
        {
            if (USB_FAILED(status = roothb.Reset(n)))
                continue;
            for (int i = 0; i < roothb.HubDepth(); ++i)
                kputs(u"  ");
            kprintf(u"Reset Port %d\n", n);
            UsbDeviceInfo* rootSlot;
            if (USB_FAILED(status = roothb.AssignSlot(n, rootSlot, USB_DEVICE_INVALIDSPEED, nullptr))) continue;
            //Now we get device descriptor
            volatile usb_device_descriptor* devdesc = GetDeviceDescriptor(rootSlot, 8);
            if (!devdesc)
                continue;

            size_t exp = devdesc->bMaxPacketSize0;
            size_t def = rootSlot->OperatingPacketSize();
            size_t pktsz = exp;
            if (devdesc->bcdUSB >> 16 > 2)
                pktsz = pow2(exp);


            if (pktsz != def)
            {
                //kprintf(u"Max packet size %d does not match default %d (exp:%d)\n", pktsz, def, exp);
                if (USB_FAILED(rootSlot->UpdatePacketSize(pktsz)))
                {
                    continue;
                }
            }

            //kprintf(u"Device descriptor length %d\n", devdesc->bLength);
            devdesc = GetDeviceDescriptor(rootSlot, devdesc->bLength);  

            rootSlot->SetDeviceDescriptor((usb_device_descriptor*)devdesc);

            if (!devdesc)
                continue;

            volatile wchar_t* devstr;
            if (devdesc->iManufacturer != 0)
            {
                //Get device string
                devstr = GetDeviceString(rootSlot, devdesc->iManufacturer);
                if(devstr)
                    kprintf(u"   Device vendor %s\n", ++devstr);
            }
            if (devdesc->iProduct != 0)
            {
                //Get device string
                devstr = GetDeviceString(rootSlot, devdesc->iProduct);
                if (devstr)
                    kprintf(u"   %s\n", ++devstr);

            }
            kprintf_a("   Device %x:%x class %x:%x:%x USB version %x\n", devdesc->idVendor, devdesc->idProduct, devdesc->bDeviceClass, devdesc->bDeviceSublass, devdesc->bDeviceProtocol, devdesc->bcdUSB);

            if (devdesc->bDeviceClass == 0x09)
            {
                NormalUsbHub* hub = new NormalUsbHub(rootSlot);
                EnumerateHub(*hub);
            }

        }
    }
}
IMG_6982.jpeg
 

MontyVeda

a short-tempered ill-controlled small-minded troll
I seem to remember a similar problem with a similar printer. Basically, it's now too old for the driver installed to work properly, and there are no later ones. Despite my words about the Canon above, I'll probably be in the same boat before long.

aye, no new drivers on the Kodak site so I'll try the following:

Look into disabling that WSD Print Device which (AIUT) is its own printer driver
Completely delete the drivers and reinstall them in case the installed driver is somehow corrupted.
See if there's any third party drivers I could use.

I might have more luck from my laptop, but that's also W10, or failing that, transfer whatever i want to print to an SD card and print from that.
 
aye, no new drivers on the Kodak site so I'll try the following:

Look into disabling that WSD Print Device which (AIUT) is its own printer driver
Completely delete the drivers and reinstall them in case the installed driver is somehow corrupted.
See if there's any third party drivers I could use.

I might have more luck from my laptop, but that's also W10, or failing that, transfer whatever i want to print to an SD card and print from that.
All good plans, hope it works!
 
Location
Cheshire
ACPI G2/S5 power state. The only thing more off is G3, where you physically disconnect it from power. And the LED might still stay on, as it's running off a powered hub ^_^. But it definitely does this even when connected to the PC directly.

USB can stay powered even when the PC is off - I can charge my phone from it, for instance. Also how things such as wake-on-lan and waking on a keypress operate.

The behaviour is because I've been resetting and enumerating the USB devices, but not doing anything with them.
C++:
static void EnumerateHub(USBHub& roothb)
{
    usb_status_t status;
    if (USB_FAILED(status = roothb.Init()))
        return;
    for (size_t n = 1; n <= roothb.NumberPorts(); ++n)
    {
        if (roothb.PortConnected(n))
        {
            if (USB_FAILED(status = roothb.Reset(n)))
                continue;
            for (int i = 0; i < roothb.HubDepth(); ++i)
                kputs(u"  ");
            kprintf(u"Reset Port %d\n", n);
            UsbDeviceInfo* rootSlot;
            if (USB_FAILED(status = roothb.AssignSlot(n, rootSlot, USB_DEVICE_INVALIDSPEED, nullptr))) continue;
            //Now we get device descriptor
            volatile usb_device_descriptor* devdesc = GetDeviceDescriptor(rootSlot, 8);
            if (!devdesc)
                continue;

            size_t exp = devdesc->bMaxPacketSize0;
            size_t def = rootSlot->OperatingPacketSize();
            size_t pktsz = exp;
            if (devdesc->bcdUSB >> 16 > 2)
                pktsz = pow2(exp);


            if (pktsz != def)
            {
                //kprintf(u"Max packet size %d does not match default %d (exp:%d)\n", pktsz, def, exp);
                if (USB_FAILED(rootSlot->UpdatePacketSize(pktsz)))
                {
                    continue;
                }
            }

            //kprintf(u"Device descriptor length %d\n", devdesc->bLength);
            devdesc = GetDeviceDescriptor(rootSlot, devdesc->bLength);  

            rootSlot->SetDeviceDescriptor((usb_device_descriptor*)devdesc);

            if (!devdesc)
                continue;

            volatile wchar_t* devstr;
            if (devdesc->iManufacturer != 0)
            {
                //Get device string
                devstr = GetDeviceString(rootSlot, devdesc->iManufacturer);
                if(devstr)
                    kprintf(u"   Device vendor %s\n", ++devstr);
            }
            if (devdesc->iProduct != 0)
            {
                //Get device string
                devstr = GetDeviceString(rootSlot, devdesc->iProduct);
                if (devstr)
                    kprintf(u"   %s\n", ++devstr);

            }
            kprintf_a("   Device %x:%x class %x:%x:%x USB version %x\n", devdesc->idVendor, devdesc->idProduct, devdesc->bDeviceClass, devdesc->bDeviceSublass, devdesc->bDeviceProtocol, devdesc->bcdUSB);

            if (devdesc->bDeviceClass == 0x09)
            {
                NormalUsbHub* hub = new NormalUsbHub(rootSlot);
                EnumerateHub(*hub);
            }

        }
    }
}
View attachment 685277

I got a D at computer studies not a C++ lol
 

Solocle

Über Member
Location
Poole
I got a D at computer studies not a C++ lol

That's the high level procedure. The nitty gritty of communicating with the USB host controller looks more like this:
C++:
static uint8_t xhci_interrupt(size_t vector, void* info)
{
    XHCI* inf = reinterpret_cast<XHCI*>(info);
    if (inf->event_available)
    {
        signal_semaphore(inf->event_available, 1);
    }
    if(!inf->interrupt_msi)
        inf->Operational.USBSTS.EINT = 1;
    inf->Runtime.Interrupter(0).IMAN.InterruptPending = 1;
    inf->Runtime.Interrupter(0).IMAN.InterruptEnable = 1;
    return 1;
}

static void xhci_pci_baseaddr(pci_address* addr, XHCI*& cinfo)
{
    paddr_t baseaddr;
    uint64_t barsize;
    //Enable interrupts, memory space, and bus mastering
    uint64_t commstat;
    read_pci_config(addr->segment, addr->bus, addr->device, addr->function, 1, 32, &commstat);
    commstat |= (1 << 10);    //Mask pinned interrupts
    commstat |= 0x6;        //Memory space and bus mastering
    write_pci_config(addr->segment, addr->bus, addr->device, addr->function, 1, 32, commstat);
    //Write FLADJ incase BIOS didn't
    write_pci_config(addr->segment, addr->bus, addr->device, addr->function, 0x61, 8, 0x20);
    baseaddr = read_pci_bar(addr->segment, addr->bus, addr->device, addr->function, 0, &barsize);
    void* mapped_controller = find_free_paging(barsize);
    if (!paging_map(mapped_controller, baseaddr, barsize, PAGE_ATTRIBUTE_WRITABLE | PAGE_ATTRIBUTE_NO_CACHING))
    {
        kprintf(u"Mapping failed\n");
    }
    cinfo = new XHCI(mapped_controller);
    uint32_t vector = PciAllocateMsi(addr->segment, addr->bus, addr->device, addr->function, 1, &xhci_interrupt, cinfo);
    if (vector == -1)
    {
        kprintf(u"Error: no MSI(-X) support\n");
    }
    else
    {
        cinfo->set_msi_mode(true);
    }
}
 
Location
Cheshire
Big day for us pc gamers today ... a new graphics card released the 4070 ... ridiculous prices of course so no intention of fettlin' anything new for some time. Top end ones at 740 quid for a 4th tier card, so thats doubled since 2016. What a joke.
 

HMS_Dave

Grand Old Lady
Big day for us pc gamers today ... a new graphics card released the 4070 ... ridiculous prices of course so no intention of fettlin' anything new for some time. Top end ones at 740 quid for a 4th tier card, so thats doubled since 2016. What a joke.

Yes, absolutely crazy. We're back in the 90s.... I paid something like 200 quid for and rx590 about 4 years ago. My son still uses that card to this day.
 

ColinJ

Puzzle game procrastinator!
Yes, absolutely crazy. We're back in the 90s....

Hmm... :whistle:

My 5th computer was 'the beast' - it had twin 3.5" floppies, a CD drive, a small hard drive, 8 MB RAM, a slow 486 processor, VGA graphics, a 14" crt monitor and it cost... £2,000!!! :eek:
That was around 1990. It was a LOT of money to me at the time, but I earned that back many times over working from home on the PC for a year or two.
 

HMS_Dave

Grand Old Lady
Hmm... :whistle:


That was around 1990. It was a LOT of money to me at the time, but I earned that back many times over working from home on the PC for a year or two.

Well indeed. £2000 in 1990 adjust for inflation is over £4500. We're still in a much better place today, but we were also in a much better place in 2015 in terms of value for money. I used to work for a company selling Aaeon SBC's to companies building health equipment for the NHS and a company called Vicon Motion Systems in Oxford who made camera systems from satellites to bespoke business systems. These SBC's were only 486 powered but were ridculously priced they were still selling them in 2001/2 with 486 chips at insane prices because of a lack of competition and a monopoly on the product. These days the choice is seemingly endless and you can get SBCs for the price of a weekly shop... I suppose we could argue similar is going on in the GPU market.
 

Jody

Stubborn git
Big day for us pc gamers today ... a new graphics card released the 4070 ... ridiculous prices of course so no intention of fettlin' anything new for some time. Top end ones at 740 quid for a 4th tier card, so thats doubled since 2016. What a joke.

Just had a quick google and most of the TI's are £850 odd :ohmy:
 
Top Bottom