int kue_load_fw(struct kue_softc *sc) { usb_device_descriptor_t dd; usbd_status err; struct kue_firmware *fw; u_char *buf; size_t buflen; DPRINTFN(1,("%s: %s: enter\n", sc->kue_dev.dv_xname, __func__)); /* * First, check if we even need to load the firmware. * If the device was still attached when the system was * rebooted, it may already have firmware loaded in it. * If this is the case, we don't need to do it again. * And in fact, if we try to load it again, we'll hang, * so we have to avoid this condition if we don't want * to look stupid. * * We can test this quickly by checking the bcdRevision * code. The NIC will return a different revision code if * it's probed while the firmware is still loaded and * running. */ if (usbd_get_device_desc(sc->kue_udev, &dd)) return (EIO); if (UGETW(dd.bcdDevice) >= KUE_WARM_REV) { printf("%s: warm boot, no firmware download\n", sc->kue_dev.dv_xname); return (0); } err = loadfirmware("kue", &buf, &buflen); if (err) { printf("%s: failed loadfirmware of file %s: errno %d\n", sc->kue_dev.dv_xname, "kue", err); return (err); } fw = (struct kue_firmware *)buf; printf("%s: cold boot, downloading firmware\n", sc->kue_dev.dv_xname); /* Load code segment */ DPRINTFN(1,("%s: kue_load_fw: download code_seg\n", sc->kue_dev.dv_xname)); err = kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SEND_SCAN, 0, (void *)&fw->data[0], ntohl(fw->codeseglen)); if (err) { printf("%s: failed to load code segment: %s\n", sc->kue_dev.dv_xname, usbd_errstr(err)); free(buf, M_DEVBUF); return (EIO); } /* Load fixup segment */ DPRINTFN(1,("%s: kue_load_fw: download fix_seg\n", sc->kue_dev.dv_xname)); err = kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SEND_SCAN, 0, (void *)&fw->data[ntohl(fw->codeseglen)], ntohl(fw->fixseglen)); if (err) { printf("%s: failed to load fixup segment: %s\n", sc->kue_dev.dv_xname, usbd_errstr(err)); free(buf, M_DEVBUF); return (EIO); } /* Send trigger command. */ DPRINTFN(1,("%s: kue_load_fw: download trig_seg\n", sc->kue_dev.dv_xname)); err = kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SEND_SCAN, 0, (void *)&fw->data[ntohl(fw->codeseglen) + ntohl(fw->fixseglen)], ntohl(fw->trigseglen)); if (err) { printf("%s: failed to load trigger segment: %s\n", sc->kue_dev.dv_xname, usbd_errstr(err)); free(buf, M_DEVBUF); return (EIO); } free(buf, M_DEVBUF); usbd_delay_ms(sc->kue_udev, 10); /* * Reload device descriptor. * Why? The chip without the firmware loaded returns * one revision code. The chip with the firmware * loaded and running returns a *different* revision * code. This confuses the quirk mechanism, which is * dependent on the revision data. */ (void)usbd_reload_device_desc(sc->kue_udev); DPRINTFN(1,("%s: %s: done\n", sc->kue_dev.dv_xname, __func__)); /* Reset the adapter. */ kue_reset(sc); return (0); }
Static int kue_load_fw(struct kue_softc *sc) { usb_device_descriptor_t dd; usbd_status err; DPRINTFN(1,("%s: %s: enter\n", USBDEVNAME(sc->kue_dev), __func__)); /* * First, check if we even need to load the firmware. * If the device was still attached when the system was * rebooted, it may already have firmware loaded in it. * If this is the case, we don't need to do it again. * And in fact, if we try to load it again, we'll hang, * so we have to avoid this condition if we don't want * to look stupid. * * We can test this quickly by checking the bcdRevision * code. The NIC will return a different revision code if * it's probed while the firmware is still loaded and * running. */ if (usbd_get_device_desc(sc->kue_udev, &dd)) return (EIO); if (UGETW(dd.bcdDevice) == KUE_WARM_REV) { printf("%s: warm boot, no firmware download\n", USBDEVNAME(sc->kue_dev)); return (0); } printf("%s: cold boot, downloading firmware\n", USBDEVNAME(sc->kue_dev)); /* Load code segment */ DPRINTFN(1,("%s: kue_load_fw: download code_seg\n", USBDEVNAME(sc->kue_dev))); /*XXXUNCONST*/ err = kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SEND_SCAN, 0, __UNCONST(kue_code_seg), sizeof(kue_code_seg)); if (err) { printf("%s: failed to load code segment: %s\n", USBDEVNAME(sc->kue_dev), usbd_errstr(err)); return (EIO); } /* Load fixup segment */ DPRINTFN(1,("%s: kue_load_fw: download fix_seg\n", USBDEVNAME(sc->kue_dev))); /*XXXUNCONST*/ err = kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SEND_SCAN, 0, __UNCONST(kue_fix_seg), sizeof(kue_fix_seg)); if (err) { printf("%s: failed to load fixup segment: %s\n", USBDEVNAME(sc->kue_dev), usbd_errstr(err)); return (EIO); } /* Send trigger command. */ DPRINTFN(1,("%s: kue_load_fw: download trig_seg\n", USBDEVNAME(sc->kue_dev))); /*XXXUNCONST*/ err = kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SEND_SCAN, 0, __UNCONST(kue_trig_seg), sizeof(kue_trig_seg)); if (err) { printf("%s: failed to load trigger segment: %s\n", USBDEVNAME(sc->kue_dev), usbd_errstr(err)); return (EIO); } usbd_delay_ms(sc->kue_udev, 10); /* * Reload device descriptor. * Why? The chip without the firmware loaded returns * one revision code. The chip with the firmware * loaded and running returns a *different* revision * code. This confuses the quirk mechanism, which is * dependent on the revision data. */ (void)usbd_reload_device_desc(sc->kue_udev); DPRINTFN(1,("%s: %s: done\n", USBDEVNAME(sc->kue_dev), __func__)); /* Reset the adapter. */ kue_reset(sc); return (0); }