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

📄 edb7312-usb.c

📁 ep9315平台下USB驱动的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
	return r;}static void csw_write(struct d12 *p){	struct cbw *cbw;	struct csw *csw;	cbw = &p->cbw;	csw = &p->csw;	csw->dCSWDataResidue = cbw->dCBWDataTransferLength - p->bxferptr;	if (csw->dCSWDataResidue) {		if (cbw->bmCBWFlags & CBW_FLAGS_DIR_IN) {			d12_status_set(p, EPX_BULK_I, 1);			p->fsm_bulk = FSM_BULK_STALL_TO_CSW;			return;		} else			d12_status_set(p, EPX_BULK_O, 1);	}	d12_buf_write(p, EPX_BULK_I, &p->csw, sizeof(struct csw));	p->fsm_bulk = FSM_BULK_IDLE;}/* --- */static int lba_chk(struct d12 *p, int lun, __u32 lba, __u32 blks){	if (lba >= p->atd_lba_capacity[lun])		return 1;	if (lba + blks > p->atd_lba_capacity[lun])		return 1;	p->scsi_lba = lba;	p->scsi_blks = blks;	return 0;}static void scsi_sense_set(struct d12 *p, int skey, int asc){	unsigned char *b;	b = p->scsi_sense;	memset (b, 0, MAX_SCSI_DATA_SENSE);	b[0] = 0x70;				/* current error */	b[2] = skey;	b[7] = MAX_SCSI_DATA_SENSE - 8;	b[12] = (asc >> 8) & 0xFF;	b[13] = (asc >> 0) & 0xFF;}static void scsi_sense_lba_set(struct d12 *p, __u32 lba, int asc){	unsigned char *b;	p->csw.bCSWStatus = CSW_STAT_FAILED;	scsi_sense_set(p, SCSI_SKEY_MEDIUM_ERROR, asc);	b = p->scsi_sense;	b[0] |= 0x80;				/* valid */	put_32be(b + 3, lba);			/* information */}static int scsi_cmd_request_sense(struct d12 *p, int lun){	int r;	r = bulk_xfer(p, BULK_IN, p->scsi_sense, MAX_SCSI_DATA_SENSE);	scsi_sense_set(p, SCSI_SKEY_NO_SENSE, SCSI_ASC_NO);	return r;}static int scsi_cmd_test_unit_ready(struct d12 *p, int lun){	if (p->atd_stat[lun] & ATD_STAT_READY) {		scsi_sense_set(p, SCSI_SKEY_NO_SENSE, SCSI_ASC_NO);	} else {		p->csw.bCSWStatus = CSW_STAT_FAILED;		scsi_sense_set(p, SCSI_SKEY_NOT_READY, SCSI_ASC_LOGICAL_UNIT_NOT_READY);	}	return bulk_xfer(p, BULK_NONE, 0, 0);}static int scsi_cmd_inquiry(struct d12 *p, int lun){	unsigned char *b, *t;	b = p->cbw.CBWCB;	t = p->tmp;	memset(t, 0, MAX_SCSI_DATA_INQUIRY);	if ((b[1] & 0x03) || b[2])		/* no CmdDT & EVPD support */		goto err;	else {					/* standard *///		t[0] = 0x00;			/* peripheral connected, direct-access device */		t[1] = 0x80;			/* RMB = 1 */		t[2] = 0x02;		t[3] = 0x02;		t[4] = MAX_SCSI_DATA_INQUIRY - 5;		memcpy(t + 8, p->scsi_str_vendor[lun], 8);		memcpy(t + 16, p->scsi_str_product[lun], 16);		memcpy(t + 32, p->scsi_str_revision[lun], 4);	}	scsi_sense_set(p, SCSI_SKEY_NO_SENSE, SCSI_ASC_NO);	return bulk_xfer(p, BULK_IN, t, MAX_SCSI_DATA_INQUIRY);err:	return SCHD_ERR_INVALID_CDB;}static int scsi_cmd_read_capacity10(struct d12 *p, int lun){	unsigned char *b, *t;	b = p->cbw.CBWCB;	t = p->tmp;	memset(t, 0, MAX_SCSI_DATA_CAPACITY10);	if ((b[1] & 0x01) || (b[8] & 0x01))	/* RELADR & PMI */		goto err;	put_32be(t + 0, p->atd_lba_capacity[lun] - 1);	/* last LBA */	put_32be(t + 4, p->atd_blk[lun]);		/* block size */	scsi_sense_set(p, SCSI_SKEY_NO_SENSE, SCSI_ASC_NO);	return bulk_xfer(p, BULK_IN, t, MAX_SCSI_DATA_CAPACITY10);err:	return SCHD_ERR_INVALID_CDB;}static int scsi_cmd_read_capacity16(struct d12 *p, int lun){	unsigned char *b, *t;	b = p->cbw.CBWCB;	t = p->tmp;	memset(t, 0, MAX_SCSI_DATA_CAPACITY16);	if (((b[1] & 0x1F) != 0x10) || (b[14] & 0x03))	/* RELADR & PMI */		goto err;	put_64be(t + 0, p->atd_lba_capacity[lun] - 1);	/* last LBA */	put_32be(t + 8, p->atd_blk[lun]);		/* block size */	scsi_sense_set(p, SCSI_SKEY_NO_SENSE, SCSI_ASC_NO);	return bulk_xfer(p, BULK_IN, t, MAX_SCSI_DATA_CAPACITY16);err:	return SCHD_ERR_INVALID_CDB;}static void bhd_read(struct d12 *p, int lun, int len){	volatile struct dioreq *dio;	int blks;	dio = &p->dio;	blks = (p->scsi_blks > p->atd_chunkblk[lun]) ? p->atd_chunkblk[lun] : p->scsi_blks;	if (blks) {		dio->cmd = DIO_CMD_READ;		dio->lun = lun;		dio->lba = p->scsi_lba;		dio->blks = blks;		dio->buf = p->chunkbuf;		up(&p->wait_dio_cmd);		p->scsi_lba += blks;		p->scsi_blks -= blks;	}}static int do_read(struct d12 *p, int lun, __u32 lba, __u32 blks){	volatile struct dioreq *dio;	int r;	if (lba_chk(p, lun, lba, blks))		goto lbaerr;	scsi_sense_set(p, SCSI_SKEY_NO_SENSE, SCSI_ASC_NO);	dio = &p->dio;	r = bulk_xfer_chk(p, BULK_IN, blks * p->atd_blk[lun]);	if (!r && blks) {		p->bhd = bhd_read;		if (blks > p->atd_chunkblk[lun])			blks = p->atd_chunkblk[lun];		dio->cmd = DIO_CMD_READ;		dio->lun = lun;		dio->lba = lba;		dio->blks = blks;		dio->buf = p->chunkbuf;		up(&p->wait_dio_cmd);		p->scsi_lba += blks;		p->scsi_blks -= blks;	}	return r;lbaerr:	return SCHD_ERR_INVALID_LBA;}static int scsi_cmd_read6(struct d12 *p, int lun){	unsigned char *b;	__u32 lba, blks;	b = p->cbw.CBWCB;	lba = get_u32be(b + 0) & 0x001FFFFF;	blks = b[4];	if (!blks)		blks = 256;	return do_read(p, lun, lba, blks);}static int scsi_cmd_read10(struct d12 *p, int lun){	unsigned char *b;	__u32 lba, blks;	b = p->cbw.CBWCB;	if (b[1] & 0x01)			/* RELADR */		goto err;	lba = get_u32be(b + 2);	blks = get_u16be(b + 7);	return do_read(p, lun, lba, blks);err:	return SCHD_ERR_INVALID_CDB;}static int scsi_cmd_read12(struct d12 *p, int lun){	unsigned char *b;	__u32 lba, blks;	b = p->cbw.CBWCB;	if (b[1] & 0x01)			/* RELADR */		goto err;	lba = get_u32be(b + 2);	blks = get_u32be(b + 6);	return do_read(p, lun, lba, blks);err:	return SCHD_ERR_INVALID_CDB;}static int scsi_cmd_read16(struct d12 *p, int lun){	unsigned char *b;	__u32 lba, blks;	b = p->cbw.CBWCB;	if (b[1] & 0x01)			/* RELADR */		goto err;	lba = get_u64be(b + 2);	blks = get_u32be(b + 10);	return do_read(p, lun, lba, blks);err:	return SCHD_ERR_INVALID_CDB;}static void bhd_write(struct d12 *p, int lun, int len){	volatile struct dioreq *dio;	int blks;	dio = &p->dio;	blks = len / p->atd_blk[lun];	if (blks) {		p->scsi_lba += blks;		p->scsi_blks -= blks;		dio->cmd = DIO_CMD_WRITE;		dio->lun = lun;		dio->lba = p->scsi_lba - blks;		dio->blks = blks;		dio->nblks = p->scsi_blks;		dio->buf = p->chunkbuf;		up(&p->wait_dio_cmd);	}}static int do_write(struct d12 *p, int lun, __u32 lba, __u32 blks){	int r;	if (lba_chk(p, lun, lba, blks))		goto lbaerr;	scsi_sense_set(p, SCSI_SKEY_NO_SENSE, SCSI_ASC_NO);	r = bulk_xfer_chk(p, BULK_OUT, blks * p->atd_blk[lun]);	if (!r && blks) {		p->bhd = bhd_write;		ep_bulk_read(p, p->chunkbuf, blks * p->atd_blk[lun]);	}	return r;lbaerr:	return SCHD_ERR_INVALID_LBA;}static int scsi_cmd_write6(struct d12 *p, int lun){	unsigned char *b;	__u32 lba, blks;	b = p->cbw.CBWCB;	lba = get_u32be(b + 0) & 0x001FFFFF;	blks = b[4];	if (!blks)		blks = 256;	return do_write(p, lun, lba, blks);}static int scsi_cmd_write10(struct d12 *p, int lun){	unsigned char *b;	__u32 lba, blks;	b = p->cbw.CBWCB;	if (b[1] & 0x01)			/* RELADR */		goto err;	lba = get_u32be(b + 2);	blks = get_u16be(b + 7);	return do_write(p, lun, lba, blks);err:	return SCHD_ERR_INVALID_CDB;}static int scsi_cmd_write12(struct d12 *p, int lun){	unsigned char *b;	__u32 lba, blks;	b = p->cbw.CBWCB;	if (b[1] & 0x01)			/* RELADR */		goto err;	lba = get_u32be(b + 2);	blks = get_u32be(b + 6);	return do_write(p, lun, lba, blks);err:	return SCHD_ERR_INVALID_CDB;}static int scsi_cmd_write16(struct d12 *p, int lun){	unsigned char *b;	__u32 lba, blks;	b = p->cbw.CBWCB;	if (b[1] & 0x01)			/* RELADR */		goto err;	lba = get_u64be(b + 2);	blks = get_u32be(b + 10);	return do_write(p, lun, lba, blks);err:	return SCHD_ERR_INVALID_CDB;}static int do_verify(struct d12 *p, int lun, __u32 lba, __u32 blks){	volatile struct dioreq *dio;	int r;	if (lba_chk(p, lun, lba, blks))		goto lbaerr;	scsi_sense_set(p, SCSI_SKEY_NO_SENSE, SCSI_ASC_NO);	dio = &p->dio;	r = bulk_xfer_chk(p, BULK_NONE, 0);	if (!r && blks) {		p->cswdelay = 1;		dio->cmd = DIO_CMD_VERIFY;		dio->lun = lun;		dio->lba = lba;		dio->blks = blks;		up(&p->wait_dio_cmd);	}	return r;lbaerr:	return SCHD_ERR_INVALID_LBA;}static int scsi_cmd_verify10(struct d12 *p, int lun){	unsigned char *b;	__u32 lba, blks;	b = p->cbw.CBWCB;	if (b[1] & 0x07)			/* BLKVFY, BYTCHK & RELADR */		goto err;	lba = get_u32be(b + 2);	blks = get_u16be(b + 7);	return do_verify(p, lun, lba, blks);err:	return SCHD_ERR_INVALID_CDB;}static int scsi_cmd_verify12(struct d12 *p, int lun){	unsigned char *b;	__u32 lba, blks;	b = p->cbw.CBWCB;	if (b[1] & 0x07)			/* BLKVFY, BYTCHK & RELADR */		goto err;	lba = get_u32be(b + 2);	blks = get_u32be(b + 6);	return do_verify(p, lun, lba, blks);err:	return SCHD_ERR_INVALID_CDB;}static int scsi_cmd_verify16(struct d12 *p, int lun){	unsigned char *b;	__u32 lba, blks;	b = p->cbw.CBWCB;	if (b[1] & 0x07)			/* BLKVFY, BYTCHK & RELADR */		goto err;	lba = get_u64be(b + 2);	blks = get_u32be(b + 10);	return do_verify(p, lun, lba, blks);err:	return SCHD_ERR_INVALID_CDB;}/* --- */struct scsi_cmd_hd {	int len;	int (*hd)(struct d12 *, int);};static const struct scsi_cmd_hd T_SCSI_HD[256] = {	{6,	scsi_cmd_test_unit_ready},	/* 0x00 */	{0,	0},				/* 0x01 */	{0,	0},				/* 0x02 */	{0,	scsi_cmd_request_sense},	/* 0x03 */	{0,	0},				/* 0x04 */	{0,	0},				/* 0x05 */	{0,	0},				/* 0x06 */	{0,	0},				/* 0x07 */	{6,	scsi_cmd_read6},		/* 0x08 */	{0,	0},				/* 0x09 */	{6,	scsi_cmd_write6},		/* 0x0A */	{0,	0},				/* 0x0B */	{0,	0},				/* 0x0C */	{0,	0},				/* 0x0D */	{0,	0},				/* 0x0E */	{0,	0},				/* 0x0F */	{0,	0},				/* 0x10 */	{0,	0},				/* 0x11 */	{6,	scsi_cmd_inquiry},		/* 0x12 */	{0,	0},				/* 0x13 */	{0,	0},				/* 0x14 */	{0,	0},				/* 0x15 */	{0,	0},				/* 0x16 */	{0,	0},				/* 0x17 */	{0,	0},				/* 0x18 */	{0,	0},				/* 0x19 */	{0,	0},				/* 0x1A */	{0,	0},				/* 0x1B */	{0,	0},				/* 0x1C */	{0,	0},				/* 0x1D */	{0,	0},				/* 0x1E */	{0,	0},				/* 0x1F */	{0,	0},				/* 0x20 */	{0,	0},				/* 0x21 */	{0,	0},				/* 0x22 */	{0,	0},				/* 0x23 */	{0,	0},				/* 0x24 */	{10,	scsi_cmd_read_capacity10},	/* 0x25 */	{0,	0},				/* 0x26 */	{0,	0},				/* 0x27 */	{10,	scsi_cmd_read10},		/* 0x28 */	{0,	0},				/* 0x29 */	{10,	scsi_cmd_write10},		/* 0x2A */	{0,	0},				/* 0x2B */	{0,	0},				/* 0x2C */	{0,	0},				/* 0x2D */	{0,	0},				/* 0x2E */	{10,	scsi_cmd_verify10},		/* 0x2F */	{0,	0},				/* 0x30 */	{0,	0},				/* 0x31 */	{0,	0},				/* 0x32 */	{0,	0},				/* 0x33 */	{0,	0},				/* 0x34 */	{0,	0},				/* 0x35 */	{0,	0},				/* 0x36 */	{0,	0},				/* 0x37 */	{0,	0},				/* 0x38 */	{0,	0},				/* 0x39 */	{0,	0},				/* 0x3A */	{0,	0},				/* 0x3B */	{0,	0},				/* 0x3C */	{0,	0},				/* 0x3D */	{0,	0},				/* 0x3E */	{0,	0},				/* 0x3F */	{0,	0},				/* 0x40 */	{0,	0},				/* 0x41 */	{0,	0},				/* 0x42 */	{0,	0},				/* 0x43 */	{0,	0},				/* 0x44 */	{0,	0},				/* 0x45 */	{0,	0},				/* 0x46 */	{0,	0},				/* 0x47 */	{0,	0},				/* 0x48 */	{0,	0},				/* 0x49 */	{0,	0},				/* 0x4A */	{0,	0},				/* 0x4B */	{0,	0},				/* 0x4C */	{0,	0},				/* 0x4D */	{0,	0},				/* 0x4E */	{0,	0},				/* 0x4F */	{0,	0},				/* 0x50 */	{0,	0},				/* 0x51 */	{0,	0},				/* 0x52 */	{0,	0},				/* 0x53 */	{0,	0},				/* 0x54 */	{0,	0},				/* 0x55 */	{0,	0},				/* 0x56 */	{0,	0},				/* 0x57 */	{0,	0},				/* 0x58 */	{0,	0},				/* 0x59 */	{0,	0},				/* 0x5A */	{0,	0},				/* 0x5B */	{0,	0},				/* 0x5C */	{0,	0},				/* 0x5D */	{0,	0},				/* 0x5E */	{0,	0},				/* 0x5F */	{0,	0},				/* 0x60 */	{0,	0},				/* 0x61 */	{0,	0},				/* 0x62 */	{0,	0},				/* 0x63 */	{0,	0},				/* 0x64 */	{0,	0},				/* 0x65 */	{0,	0},				/* 0x66 */	{0,	0},				/* 0x67 */	{0,	0},				/* 0x68 */	{0,	0},				/* 0x69 */	{0,	0},				/* 0x6A */	{0,	0},				/* 0x6B */	{0,	0},				/* 0x6C */	{0,	0},				/* 0x6D */	{0,	0},				/* 0x6E */	{0,	0},				/* 0x6F */	{0,	0},				/* 0x70 */	{0,	0},				/* 0x71 */	{0,	0},				/* 0x72 */	{0,	0},				/* 0x73 */	{0,	0},				/* 0x74 */	{0,	0},				/* 0x75 */	{0,	0},				/* 0x76 */	{0,	0},				/* 0x77 */	{0,	0},				/* 0x78 */	{0,	0},				/* 0x79 */	{0,	0},				/* 0x7A */	{0,	0},				/* 0x7B */	{0,	0},				/* 0x7C */	{0,	0},				/* 0x7D */	{0,	0},				/* 0x7E */	{0,	0},				/* 0x7F */	{0,	0},				/* 0x80 */	{0,	0},				/* 0x81 */	{0,	0},				/* 0x82 */	{0,	0},				/* 0x83 */	{0,	0},				/* 0x84 */	{0,	0},				/* 0x85 */	{0,	0},				/* 0x86 */	{0,	0},				/* 0x87 */	{16,	scsi_cmd_read16},		/* 0x88 */	{0,	0},				/* 0x89 */	{16,	scsi_cmd_write16},		/* 0x8A */	{0,	0},				/* 0x8B */	{0,	0},				/* 0x8C */	{0,	0},				/* 0x8D */	{0,	0},				/* 0x8E */	{16,	scsi_cmd_verify16},		/* 0x8F */	{0,	0},				/* 0x90 */	{0,	0},				/* 0x91 */	{0,	0},				/* 0x92 */	{0,	0},				/* 0x93 */	{0,	0},				/* 0x94 */	{0,	0},				/* 0x95 */	{0,	0},				/* 0x96 */	{0,	0},				/* 0x97 */	{0,	0},				/* 0x98 */	{0,	0},				/* 0x99 */	{0,	0},				/* 0x9A */	{0,	0},				/* 0x9B */	{0,	0},				/* 0x9C */	{0,	0},				/* 0x9D */	{16,	scsi_cmd_read_capacity16},	/* 0x9E */	{0,	0},				/* 0x9F */	{0,	0},				/* 0xA0 */	{0,	0},				/* 0xA1 */	{0,	0},				/* 0xA2 */	{0,	0},				/* 0xA3 */	{0,	0},				/* 0xA4 */	{0,	0},				/* 0xA5 */	{0,	0},				/* 0xA6 */	{0,	0},				/* 0xA7 */	{12,	scsi_cmd_read12},		/* 0xA8 */	{0,	0},				/* 0xA9 */	{12,	scsi_cmd_write12},		/* 0xAA */	{0,	0},				/* 0xAB */	{0,	0},				/* 0xAC */	{0,	0},				/* 0xAD */	{0,	0},				/* 0xAE */	{12,	scsi_cmd_verify12},		/* 0xAF */	{0,	0},				/* 0xB0 */	{0,	0},				/* 0xB1 */	{0,	0},				/* 0xB2 */	{0,	0},				/* 0xB3 */	{0,	0},				/* 0xB4 */	{0,	0},				/* 0xB5 */	{0,	0},				/* 0xB6 */	{0,	0},				/* 0xB7 */	{0,	0},				/* 0xB8 */	{0,	0},				/* 0xB9 */	{0,	0},				/* 0xBA */	{0,	0},				/* 0xBB */	{0,	0},				/* 0xBC */	{0,	0},				/* 0xBD */	{0,	0},				/* 0xBE */	{0,	0},				/* 0xBF */	{0,	0},				/* 0xC0 */	{0,	0},				/* 0xC1 */	{0,	0},				/* 0xC2 */	{0,	0},				/* 0xC3 */	{0,	0},				/* 0xC4 */	{0,	0},				/* 0xC5 */	{0,	0},				/* 0xC6 */	{0,	0},				/* 0xC7 */	{0,	0},				/* 0xC8 */	{0,	0},				/* 0xC9 */	{0,	0},				/* 0xCA */	{0,	0},				/* 0xCB */	{0,	0},				/* 0xCC */	{0,	0},				/* 0xCD */	{0,	0},				/* 0xCE */	{0,	0},				/* 0xCF */	{0,	0},				/* 0xD0 */	{0,	0},				/* 0xD1 */	{0,	0},				/* 0xD2 */	{0,	0},				/* 0xD3 */	{0,	0},				/* 0xD4 */	{0,	0},				/* 0xD5 */	{0,	0},				/* 0xD6 */	{0,	0},				/* 0xD7 */	{0,	0},				/* 0xD8 */	{0,	0},				/* 0xD9 */	{0,	0},				/* 0xDA */	{0,	0},				/* 0xDB */	{0,	0},				/* 0xDC */	{0,	0},				/* 0xDD */	{0,	0},				/* 0xDE */	{0,	0},				/* 0xDF */	{0,	0},				/* 0xE0 */	{0,	0},				/* 0xE1 */	{0,	0},				/* 0xE2 */	{0,	0},				/* 0xE3 */	{0,	0},				/* 0xE4 */	{0,	0},				/* 0xE5 */	{0,	0},				/* 0xE6 */	{0,	0},				/* 0xE7 */	{0,	0},				/* 0xE8 */	{0,	0},				/* 0xE9 */	{0,	0},				/* 0xEA */	{0,	0},				/* 0xEB */	{0,	0},				/* 0xEC */	{0,	0},				/* 0xED */	{0,	0},				/* 0xEE */	{0,	0},				/* 0xEF */	{0,	0},				/* 0xF0 */	{0,	0},				/* 0xF1 */	{0,	0},				/* 0xF2 */	{0,	0},				/* 0xF3 */	{0,	0},				/* 0xF4 */	{0,	0},				/* 0xF5 */	{0,	0},				/* 0xF6 */	{0,	0},				/* 0xF7 */	{0,	0},				/* 0xF8 */	{0,	0},				/* 0xF9 */	{0,	0},				/* 0xFA */	{0,	0},				/* 0xFB */	{0,	0},				/* 0xFC */	{0,	0},				/* 0xFD */	{0,	0},				/* 0xFE */	{0,	0}				/* 0xFF */};/* ------------------------------------------------------------------------- *//* * interrupt handler and supporting functions */static void ep0_rx(struct d12 *p){	struct devreq *drq;	int stat, len, req;	stat = d12_read_last_trans(p, EPX_CTRL_O);	if (!(stat & D_READ_LTRNS_SUCCESS))

⌨️ 快捷键说明

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