Пример #1
0
/* 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

}