/* Download firmware into device */ static int keyspan_download_firmware(keyspan_pre_state_t *kbp) { usbser_keyspan_fw_record_t *record = NULL; /* If the firmware module exists, then download it to device. */ if (&keyspan_usa49wlc_fw) { record = keyspan_usa49wlc_fw(); } if (!record) { USB_DPRINTF_L1(DPRINT_ATTACH, kbp->kb_lh, "No firmware available for Keyspan usa49wlc" " usb-to-serial adapter. Refer to usbsksp(7D)" " for details."); return (USB_FAILURE); } /* Set bit 1 before downloading firmware. */ if (keyspan_set_reg(&kbp->kb_def_pipe, 1) != USB_SUCCESS) { USB_DPRINTF_L2(DPRINT_ATTACH, kbp->kb_lh, "keyspan_pre_attach: Set register failed."); return (USB_FAILURE); } /* Write until the last record of the firmware */ while (record->address != 0xffff) { if (keyspan_write_memory(&kbp->kb_def_pipe, record->address, (uchar_t *)record->data, record->data_len, KEYSPAN_REQ_SET) != USB_SUCCESS) { USB_DPRINTF_L2(DPRINT_ATTACH, kbp->kb_lh, "keyspan_pre_attach: download firmware failed."); return (USB_FAILURE); } record++; } /* * Set bit 0, device will be enumerated again after a while, * and then go to keyspan_attach() */ if (keyspan_set_reg(&kbp->kb_def_pipe, 0) != USB_SUCCESS) { return (USB_FAILURE); } return (USB_SUCCESS); }
/* * scsa2usb_fill_in_cbw: * Fill in a CBW request packet. This * packet is transported to the device */ static void scsa2usb_fill_in_cbw(scsa2usb_state_t *scsa2usbp, scsa2usb_cmd_t *cmd, mblk_t *mp) { int i; int len; uchar_t dir, *cdb = (uchar_t *)(&cmd->cmd_cdb); ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex)); *mp->b_wptr++ = CBW_MSB(CBW_SIGNATURE); /* CBW Signature */; *mp->b_wptr++ = CBW_MID1(CBW_SIGNATURE); *mp->b_wptr++ = CBW_MID2(CBW_SIGNATURE); *mp->b_wptr++ = CBW_LSB(CBW_SIGNATURE); *mp->b_wptr++ = CBW_LSB(cmd->cmd_tag); /* CBW Tag */ *mp->b_wptr++ = CBW_MID2(cmd->cmd_tag); *mp->b_wptr++ = CBW_MID1(cmd->cmd_tag); *mp->b_wptr++ = CBW_MSB(cmd->cmd_tag); dir = cmd->cmd_dir; len = cmd->cmd_xfercount; #ifdef SCSA2USB_BULK_ONLY_TEST if (scsa2usb_test_case_2 && (cdb[0] == SCMD_READ_CAPACITY)) { /* Host expects no data. The device wants data. Hn < Di */ scsa2usb_test_case_2 = len = 0; USB_DPRINTF_L1(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, "TEST 2: Hn < Di cdb: 0x%x len: 0x%x", cdb[0], len); } if (scsa2usb_test_case_3 && (cmd->cmd_dir == CBW_DIR_OUT)) { /* Host expects no data. The device wants data. Hn < Do */ if (cdb[0] == SCMD_WRITE_G1) { scsa2usb_test_case_3 = len = 0; USB_DPRINTF_L1(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, "TEST 3: Hn < Do cdb: 0x%x len:%x", cdb[0], len); } } if (scsa2usb_test_case_4 && (cdb[0] == SCMD_READ_G1)) { cdb[0] = 0x5e; USB_DPRINTF_L1(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, "TEST 4: Hi > Dn: changed cdb to 0x%x", cdb[0]); scsa2usb_test_case_4 = 0; } if (scsa2usb_test_case_7 && (cmd->cmd_cdb[0] == SCMD_READ_G1)) { len -= 0x10; USB_DPRINTF_L1(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, "TEST 7: Hi < Di cdb: 0x%x len: 0x%x", cdb[0], len); scsa2usb_test_case_7 = 0; } if (scsa2usb_test_case_8 && (cdb[0] == SCMD_READ_G1)) { dir = (dir == CBW_DIR_IN) ? CBW_DIR_OUT : dir; USB_DPRINTF_L1(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, "TEST 8: Hi <> Do cdb: 0x%x dir: 0x%x", cdb[0], dir); } if (scsa2usb_test_case_9 && (cdb[0] == SCMD_WRITE_G1)) { USB_DPRINTF_L1(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, "TEST 9: Ho <> Di (%x)", cdb[0]); cdb[SCSA2USB_LEN_0] = cdb[SCSA2USB_LEN_1] = 0; scsa2usb_test_case_9 = 0; } if (scsa2usb_test_case_10 && (cdb[0] == SCMD_WRITE_G1)) { dir = (dir == CBW_DIR_OUT) ? CBW_DIR_IN : dir; USB_DPRINTF_L1(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, "TEST 10: Ho <> Di cdb: 0x%x dir: 0x%x", cdb[0], dir); } /* * This case occurs when the device intends to receive * more data from the host than the host sends. */ if (scsa2usb_test_case_13) { if ((cdb[0] == SCMD_WRITE_G1) || (cdb[0] == SCMD_READ_G1)) { USB_DPRINTF_L1(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, "TEST 13: Ho < Do"); len -= 30; scsa2usb_test_case_13 = 0; } } #endif /* SCSA2USB_BULK_ONLY_TEST */ *mp->b_wptr++ = CBW_MSB(len); /* Transfer Length */ *mp->b_wptr++ = CBW_MID1(len); *mp->b_wptr++ = CBW_MID2(len); *mp->b_wptr++ = CBW_LSB(len); *mp->b_wptr++ = dir; /* Transfer Direction */ *mp->b_wptr++ = cmd->cmd_pkt->pkt_address.a_lun; /* Lun # */ *mp->b_wptr++ = cmd->cmd_actual_len; /* CDB Len */ /* Copy the CDB out */ for (i = 0; i < CBW_CDB_LEN; i++) { *mp->b_wptr++ = *cdb++; } #ifdef DUMP_CWB { int len = mp->b_wptr - mp->b_rptr; char *buf; int i; cmn_err(CE_CONT, "CWB: len=%d\n", len); buf = kmem_zalloc(512, KM_SLEEP); for (i = 0; i < len; i++) { sprintf(&buf[strlen(buf)], "%02x ", mp->b_rptr[i]); } cmn_err(CE_CONT, "%s\n", buf); kmem_free(buf, 512); } #endif }