⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbd_scsi.c

📁 F:worksip2440a board可启动u-boot-like.tar.gz F:worksip2440a board可启动u-boot-like.tar.gz
💻 C
📖 第 1 页 / 共 2 页
字号:
	return;}void usbd_scsi_com_modesense_flexible(usbd_mass_instance *ma){	switch (ma->cbw.CBWCB[2] & 0xc0) {		case 0x00:	/* current */		case 0x80:	/* default */			ma->buff[ma->buff_ptr++] = 0x05; /* page 5 */			ma->buff[ma->buff_ptr++] = 0x1e; /* length */			ma->buff[ma->buff_ptr++] = 0x0f; /* Transfer rate = 0x0fa0 */			ma->buff[ma->buff_ptr++] = 0xa0;			ma->buff[ma->buff_ptr++] = ma->media.NoOfHead;			ma->buff[ma->buff_ptr++] = ma->media.SectorPerTrack;			ma->buff[ma->buff_ptr++] = (unsigned char)((ma->media.BytePerSector & 0xff00) >> 8);			ma->buff[ma->buff_ptr++] = (unsigned char)(ma->media.BytePerSector & 0xff);			ma->buff[ma->buff_ptr++] = (unsigned char)((ma->media.NoOfCylinder & 0xff00) >> 8);			ma->buff[ma->buff_ptr++] = (unsigned char)(ma->media.NoOfCylinder & 0xff);			ma->buff_ptr += 0x16;			break;		default:	/* changeable */			ma->buff[ma->buff_ptr++] = 0x05; /* page 5 */			ma->buff[ma->buff_ptr++] = 0x1e; /* length */			ma->buff_ptr += 0x1e;			break;	}	return;}char usbd_scsi_com_inquiry(usbd_mass_instance *ma){	unsigned char len;		debugvs(1, "%s : %s - SCSI Inquiry\n", __FILE__, __FUNCTION__);	if (ma->cbw.CBWCB[1] & 0x01) {		usbd_scsi_set_error(ma, SCSI_ERROR_InvalidFieldCdb, 0);		ma->state = SEND_CSW;		return CSW_STATUS_CommandFailed;	}		usbd_scsi_clear_buff(ma);	ma->buff[0] = 0;	/* Direct-access device */	ma->buff[1] = 0x80;	/* Removable deice */	ma->buff[2] = 2;	/* Version - ANSI X3.131:1994 (SCSI-2) */	ma->buff[3] = 2;	/* Response data format - Standard */	ma->buff[4] = 0x5b;	/* Additional length */	ma->buff[5] = 0;	/* Not support SCC */	usbd_scsi_strcpy(&ma->buff[8], SCSI_STRING_MANUFACTURER, 28);	len = ma->cbw.CBWCB[4];	if (len > 0x60) len = 0x60;	ma->buff_length = len;	return usbd_scsi_command_end_send(ma);}char usbd_scsi_com_readformatcapacities(usbd_mass_instance *ma){	unsigned long lba;		debugvs(1, "%s : %s - SCSI ReadFormatCapacities\n", __FILE__, __FUNCTION__);	usbd_media_probe(ma);	if (ma->media.status == ABSENT) {		usbd_scsi_set_error(ma, SCSI_ERROR_MediumNotPresent, 0);		ma->state = SEND_CSW;		return CSW_STATUS_CommandFailed;	}	lba = ma->media.total_sector - 1;	usbd_scsi_put_bigendian(ma->buff, 0, 4);	/* Capacity List Header */	usbd_scsi_put_bigendian(ma->buff + 4, lba, 4);	/* Number of Blocks */	ma->buff[8] = 0x02;				/* Descriptor type = Foratted Media */	usbd_scsi_put_bigendian(ma->buff + 9, 0x200, 3);	/* Block Length */	ma->buff_ptr = 0;	ma->buff_length = 12;		debugvs(2, "%s : %s - SCSI ReadFormatCapacities : Report %ld Sectors\n", __FILE__, __FUNCTION__, lba);	return usbd_scsi_command_end_send(ma);}char usbd_scsi_com_readcapacity(usbd_mass_instance *ma){	unsigned long lba;		debugvs(1, "%s : %s - SCSI ReadCapacity\n", __FILE__, __FUNCTION__);	usbd_media_probe(ma);	if (ma->media.status == ABSENT) {		usbd_scsi_set_error(ma, SCSI_ERROR_MediumNotPresent, 0);		ma->state = SEND_CSW;		return CSW_STATUS_CommandFailed;	}	debugvs(2, "%s : %s - SCSI ReadCapacity PMI %d\n", __FILE__, __FUNCTION__, ma->cbw.CBWCB[8] & 0x01);	if (ma->cbw.CBWCB[8] & 0x01) {/* PMI == 1 */		lba = usbd_scsi_get_bigendian(&ma->cbw.CBWCB[2], 4);		if (!usbd_scsi_check_lba(ma, lba)) {			ma->state = SEND_CSW;			return CSW_STATUS_CommandFailed;		}	}	else {/* PMI == 0 */		lba = ma->media.total_sector - 1;	}	usbd_scsi_put_bigendian(ma->buff, lba, 4);	usbd_scsi_put_bigendian(ma->buff + 4, 0x200, 4);	ma->buff_ptr = 0;	ma->buff_length = 8;	debugvs(2, "%s : %s - SCSI ReadCapacity : Report %ld Sectors\n", __FILE__, __FUNCTION__, lba);	return usbd_scsi_command_end_send(ma);}char usbd_scsi_com_read(usbd_mass_instance *ma){	unsigned short cnt;	char ret;		debugvs(1, "%s : %s - SCSI Read\n", __FILE__, __FUNCTION__);	ma->state = MASS_TRANS;	ret = usbd_scsi_check_media(ma);	if (ret != CSW_STATUS_CommandPassed) {		ma->state = SEND_CSW;		return ret;	}	if (ma->cbw.CBWCB[0] == SCSI_ComRead6) {		ma->lba = (usbd_scsi_get_bigendian(&ma->cbw.CBWCB[1], 3) & 0x1fffff);		ma->req_sector_count = ma->cbw.CBWCB[4];		if (!ma->req_sector_count) ma->req_sector_count = 0x100;	}	else {		ma->lba = usbd_scsi_get_bigendian(&ma->cbw.CBWCB[2], 4);		ma->req_sector_count = usbd_scsi_get_bigendian(&ma->cbw.CBWCB[7], 2);	}		debugvs(2, "%s : %s - SCSI Read : LBA %08lx Sector count %04x\n", __FILE__, __FUNCTION__, ma->lba, ma->req_sector_count);	if (!usbd_scsi_check_lba(ma, ma->lba + ma->req_sector_count)) {		debugvs(2, "%s : %s - SCSI Read : LBA address out of range\n", __FILE__, __FUNCTION__);		ma->state = SEND_CSW;		return CSW_STATUS_CommandFailed;	}	if (ma->req_sector_count == 0) {		ma->state = SEND_CSW;		return CSW_STATUS_CommandPassed;	}	for (cnt = 0; cnt < ma->req_sector_count; cnt++) {		usbd_media_read(ma);		ma->buff_length = ma->media.BytePerSector;		ma->buff_ptr = 0;		usbd_scsi_send_data_wait(ma);		ma->lba++;	}	return usbd_scsi_command_noerror_end(ma);}char usbd_scsi_com_write(usbd_mass_instance *ma){	unsigned short cnt;	char ret;		debugvs(1, "%s : %s - SCSI Write\n", __FILE__, __FUNCTION__);	ma->state = MASS_RECV;	ret = usbd_scsi_check_media(ma);	if (ret != CSW_STATUS_CommandPassed) {		ma->state = SEND_CSW;		return ret;	}	if (ma->cbw.CBWCB[0] == SCSI_ComWrite6) {		ma->lba = (usbd_scsi_get_bigendian(&ma->cbw.CBWCB[1], 3) & 0x1fffff);		ma->req_sector_count = ma->cbw.CBWCB[4];		if (!ma->req_sector_count) ma->req_sector_count = 0x100;	}	else {		ma->lba = usbd_scsi_get_bigendian(&ma->cbw.CBWCB[2], 4);		ma->req_sector_count = usbd_scsi_get_bigendian(&ma->cbw.CBWCB[7], 2);	}	debugvs(2, "%s : %s - SCSI Write : LBA %08lx Sector count %04x\n", __FILE__, __FUNCTION__, ma->lba, ma->req_sector_count);	if (!usbd_scsi_check_lba(ma, ma->lba + ma->req_sector_count)) {		debugvs(2, "%s : %s - SCSI Write : LBA address out of range\n", __FILE__, __FUNCTION__);		ma->state = SEND_CSW;		return CSW_STATUS_CommandFailed;	}	if (ma->req_sector_count == 0) {		ma->state = SEND_CSW;		return CSW_STATUS_CommandPassed;	}	for (cnt = 0; cnt < ma->req_sector_count; cnt++) {		ma->buff_ptr = 0;		ma->buff_length = ma->media.BytePerSector;		usbd_scsi_recv_data_wait(ma);		usbd_media_write(ma);		ma->lba++;	}	return usbd_scsi_command_noerror_end(ma);}char usbd_scsi_command_noerror_end(usbd_mass_instance *ma){	ma->state = SEND_CSW;	usbd_scsi_set_error(ma, SCSI_ERROR_NoError, 0);	return CSW_STATUS_CommandPassed;}char usbd_scsi_command_end_send(usbd_mass_instance *ma){	ma->state = MASS_TRANS;	if (usbd_scsi_send_data_wait(ma)) {		ma->state = SEND_CSW;		usbd_scsi_set_error(ma, SCSI_ERROR_NoError, 0);		return CSW_STATUS_CommandPassed;	}	ma->state = SEND_CSW;	return CSW_STATUS_PhaseError;}int usbd_scsi_send_data_wait(usbd_mass_instance *ma){	int len, flag, temp;	len = 0;	flag = FALSE;	while (ma->state == MASS_TRANS) {		usbdmass_check_control_int();		if (ma->usb_reset == TRUE) {			flag = FALSE;			break;		}		if (usbd_24x0_chk_ep1_stall()) {			flag = FALSE;			break;		}		if (usbd_24x0_chk_ep1_busy()) continue;		if (flag == TRUE) {			ma->buff_ptr += len;			ma->csw.dCSWDataResidue -= len;			if (ma->buff_ptr == ma->buff_length) break;		}		temp = ma->buff_length - ma->buff_ptr;		len = (temp > EP2_PKT_SIZE) ? EP2_PKT_SIZE : temp;		usbd_24x0_write_fifo(ma->buff + ma->buff_ptr, len, INDEX_EP1);		usbd_24x0_set_ep1_in_pkt_ready();		debughd(3, ma->buff + ma->buff_ptr, len);		flag = TRUE;	}	return flag;}int usbd_scsi_recv_data_wait(usbd_mass_instance *ma){	int flag;	unsigned char len;	flag = FALSE;	while (ma->state == MASS_RECV) {		usbdmass_check_control_int();		if (ma->usb_reset == TRUE) {			debugvs(2, "%s : %s - SCSI recv data : USB Reset\n", __FILE__, __FUNCTION__);			flag = FALSE;			break;		}		if (usbd_24x0_chk_ep2_stall()) {			debugvs(2, "%s : %s - SCSI recv data : ep2 stall\n", __FILE__, __FUNCTION__);			flag = FALSE;			break;		}		if (!usbd_24x0_isr_ep2_chk()) continue;		len = usbd_24x0_read_fifo(ma->buff + ma->buff_ptr, INDEX_EP2);		debughd(3, ma->buff + ma->buff_ptr, len);		ma->buff_ptr += len;		ma->csw.dCSWDataResidue -= len;		usbd_24x0_clr_ep2_out_pkt_ready();		if (ma->buff_ptr == ma->buff_length) break;		flag = TRUE;	}	return flag;}char usbd_scsi_check_media(usbd_mass_instance *ma){	usbd_media_probe(ma);	switch (ma->media.status) {		case ABSENT:			usbd_scsi_set_error(ma, SCSI_ERROR_MediumNotPresent, 0);			return CSW_STATUS_CommandFailed;		case CHANGED:			usbd_scsi_set_error(ma, SCSI_ERROR_MediumChanged, 0);			ma->media.status = PRESENT;			return CSW_STATUS_CommandFailed;		case PRESENT:		default:			break;	}	usbd_scsi_set_error(ma, SCSI_ERROR_NoError, 0);	return CSW_STATUS_CommandPassed;}int usbd_scsi_check_lba(usbd_mass_instance *ma, unsigned long lba){	if (lba > ma->media.total_sector) {		usbd_scsi_set_error(ma, SCSI_ERROR_AddressOutOfRange, ma->media.total_sector);		return FALSE;	}	return TRUE;}void usbd_scsi_set_error(usbd_mass_instance *ma, int error_no, unsigned long error_info){	ma->scsi_error = error_no;	ma->scsi_error_info = error_info;	return;}unsigned long usbd_scsi_get_bigendian(unsigned char *ptr, int len){	int i;	unsigned long ret_value;		ret_value = 0;	for (i = 0; i < len; i++) {		ret_value = ret_value << 8;		ret_value += *ptr;		ptr++;	}	return ret_value;}void usbd_scsi_put_bigendian(unsigned char *ptr, unsigned long value, int len){	int i;		for (i = 3; i >= 0; i--) {		if (i < len) {			ptr[i] = (unsigned char)(value & 0xff);			value = value >> 8;		}	}	return;}void usbd_scsi_strcpy(char *dest, char *src, int len){	int i;	for (i = 0; i < len; i++) dest[i] = src[i];	return;}void usbd_scsi_clear_buff(usbd_mass_instance *ma){	int i;	for (i = 0; i < MASS_BUFF_SIZE; i++) ma->buff[i] = 0;	ma->buff_ptr = 0;	return;}#endif /* CONFIG_AESOP_USBDMASS */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -