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

📄 edb7312-usb.c

📁 ep9315平台下USB驱动的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
		while (l--)			*b++ = d12_ind(p);		d12_buf_clear(p);	}	return len;}/* write buffer */static int d12_buf_write(struct d12 *p, int epx, const void *buf, int len){	int i, l, l2, stat;	const unsigned char *b;	b = (const unsigned char *)buf;	if (epx == EPX_BULK_I) {		stat = d12_status_get(p, epx);		i = 2;		if (stat & D_READ_ENDP_STAT_BUF0)			i--;		if (stat & D_READ_ENDP_STAT_BUF1)			i--;		l2 = 0;		while (i-- && len) {			d12_select_endpoint(p, epx);			l = len;			if (l > EP_BULK_SIZE)				l = EP_BULK_SIZE;			d12_out2(p, CMD_WRITE_BUFFER, 0, l);			l2 += l;			len -= l;			while (l--)				d12_outd(p, *b++);			d12_buf_validate(p);		}		len = l2;	} else {		d12_select_endpoint(p, epx);		d12_out2(p, CMD_WRITE_BUFFER, 0, len);		l = len;		while (l--)			d12_outd(p, *b++);		d12_buf_validate(p);	}	return len;}/* ------------------------------------------------------------------------- *//* * USB 1.1 chapter 9 broken into tiny little pieces plus a little mass-storage */static void ep_ctrl_ack(struct d12 *p){	d12_buf_write(p, EPX_CTRL_I, 0, 0);	p->fsm_ctl = FSM_CTL_STATUS_IN;}static void ep_ctrl_write(struct d12 *p, const void *buf, int len){	struct devreq *drq;	drq = &p->drq;	if (len > drq->wLength)			/* 9.3.5: return <= */		len = drq->wLength;	if (len > MAX_DBUF)		len = MAX_DBUF;	memcpy(p->dbuf, buf, len);	p->dlen = len;	p->dptr = 0;	if (len > EP_CTRL_SIZE)		len = EP_CTRL_SIZE;	d12_buf_write(p, EPX_CTRL_I, p->dbuf, len);	p->dptr += len;	p->fsm_ctl = (p->dptr == p->dlen) ? FSM_CTL_STATUS_OUT : FSM_CTL_DATA_IN;	p->fsm_ctl_lastpkt = len;}/* --- */static int std_reserved(struct d12 *p){#ifdef DBG	printk("%s: unsupported reserved request\n", ID);#endif	return 1;}static int std_get_status(struct d12 *p){	struct devreq *drq;	int ep, epx;	unsigned char buf[2];	drq = &p->drq;	if ((drq->bmRequestType & (REQTYPE_DIR_M | REQTYPE_TYPE_M)) != (REQTYPE_DIR_IN | REQTYPE_TYPE_STANDARD))		goto err;	if (drq->wValue || (drq->wLength != 2))		goto err;	if (p->fsm_dev == FSM_DEV_DEFAULT)		goto err;	buf[0] = buf[1] = 0;	switch (drq->bmRequestType & REQTYPE_RECP_M) {	case REQTYPE_RECP_DEVICE:		if (drq->wIndex)			goto err;		buf[0] = STATUS_DEVICE_SELF_POWERED | (p->feat_wakeup ? STATUS_DEVICE_REMOTE_WAKEUP : 0);#ifdef DBG		printk("%s: get_status device --> 0x%02x 0x%02x\n", ID, buf[0], buf[1]);#endif		break;	case REQTYPE_RECP_INTERFACE:		if (p->fsm_dev == FSM_DEV_ADDRESS)			goto err;		if (drq->wIndex & 0xFF)		/* only one interface */			goto err;		#ifdef DBG		printk("%s: get_status interface --> 0x%02x 0x%02x\n", ID, buf[0], buf[1]);#endif		break;	case REQTYPE_RECP_ENDPOINT:		ep = drq->wIndex & 0x0F;		if ((ep != EP_CTRL) && (ep != EP_BULK))			goto err;		if (p->fsm_dev == FSM_DEV_ADDRESS)			if (ep != EP_CTRL)				goto err;		epx = (ep << 1) | ((drq->wIndex & 0x80) ? 1 : 0);		buf[0] = (d12_select_endpoint(p, epx) & D_SELECT_ENDP_STALL) ? STATUS_ENDPOINT_HALT : 0;#ifdef DBG		printk("%s: get_status endpoint --> 0x%02x 0x%02x\n", ID, buf[0], buf[1]);#endif		break;	default:		goto err;	}	ep_ctrl_write(p, buf, drq->wLength);	return 0;err:#ifdef DBG	printk("%s: bad get_status request\n", ID);#endif	return 1;}static int feature(struct d12 *p, int on){	struct devreq *drq;	int ep, epx;	drq = &p->drq;	if ((drq->bmRequestType & (REQTYPE_DIR_M | REQTYPE_TYPE_M)) != (REQTYPE_DIR_OUT | REQTYPE_TYPE_STANDARD))		goto err;	if (drq->wLength)		goto err;	if (p->fsm_dev == FSM_DEV_DEFAULT)		goto err;	switch (drq->bmRequestType & REQTYPE_RECP_M) {	case REQTYPE_RECP_DEVICE:		if (drq->wIndex)			goto err;		if (drq->wValue == FEATURE_DEVICE_REMOTE_WAKEUP) {			p->feat_wakeup = on;#ifdef DBG			printk("%s: %s_feature device_remote_wakeup\n", ID, on ? "set" : "clear");#endif		} else			goto err;		break;	case REQTYPE_RECP_INTERFACE:		goto err;	case REQTYPE_RECP_ENDPOINT:		ep = drq->wIndex & 0x0F;		if ((ep != EP_CTRL) && (ep != EP_BULK))			goto err;		if (p->fsm_dev == FSM_DEV_ADDRESS)			if (ep != EP_CTRL)				goto err;		epx = (ep << 1) | ((drq->wIndex & 0x80) ? 1 : 0);		if (drq->wValue == FEATURE_ENDPOINT_HALT) {			d12_status_set(p, epx, on);			if ((epx == EPX_BULK_I) && !on && (p->fsm_bulk == FSM_BULK_STALL_TO_CSW)) {				d12_buf_write(p, EPX_BULK_I, &p->csw, sizeof(struct csw));				p->fsm_bulk = FSM_BULK_IDLE;			}#ifdef DBG			printk("%s: %s_feature endpoint_halt on epx #%d\n", ID, on ? "set" : "clear", epx);#endif		} else			goto err;		break;	default:		goto err;	}	ep_ctrl_ack(p);	return 0;err:#ifdef DBG	printk("%s: bad %s_feature request\n", ID, on ? "set" : "clear");#endif	return 1;}static int std_clear_feature(struct d12 *p){	return feature(p, 0);}static int std_set_feature(struct d12 *p){	return feature(p, 1);}static int std_set_address(struct d12 *p){	struct devreq *drq;	drq = &p->drq;	if (drq->bmRequestType != (REQTYPE_DIR_OUT | REQTYPE_TYPE_STANDARD | REQTYPE_RECP_DEVICE))		goto err;	if ((drq->wValue > 127) || drq->wIndex || drq->wLength)		goto err;	switch (p->fsm_dev) {	case FSM_DEV_DEFAULT:		if (drq->wValue)			p->fsm_dev = FSM_DEV_ADDRESS;		break;	case FSM_DEV_ADDRESS:		if (!drq->wValue)			p->fsm_dev = FSM_DEV_DEFAULT;		break;	case FSM_DEV_CONFIGURED:		goto err;	}	d12_set_address_enable(p, drq->wValue, 1);#ifdef DBG	printk("%s: set_address %d\n", ID, drq->wValue);#endif	ep_ctrl_ack(p);	return 0;err:#ifdef DBG	printk("%s: bad set_address request\n", ID);#endif	return 1;}static int std_get_descriptor(struct d12 *p){	struct devreq *drq;	int type, ndx;	const void *buf;	int len;	drq = &p->drq;	if (drq->bmRequestType != (REQTYPE_DIR_IN | REQTYPE_TYPE_STANDARD | REQTYPE_RECP_DEVICE))		goto err;	type = (drq->wValue >> 8) & 0xFF;	ndx = drq->wValue & 0xFF;	switch (type) {	case DESC_TYPE_DEVICE:		if (ndx || drq->wIndex)			goto err;		buf = p->desc_dev;		len = p->desc_dev_len;#ifdef DBG		printk("%s: get_descriptor device\n", ID);#endif		break;	case DESC_TYPE_CONFIGURATION:		if (ndx || drq->wIndex)		/* only one configuration */			goto err;		buf = p->desc_cfg;		len = p->desc_cfg_len;#ifdef DBG		printk("%s: get_descriptor configuration %d\n", ID, ndx);#endif		break;	case DESC_TYPE_STRING:		if (!ndx) {			if (drq->wIndex)				goto err;		} else {			if ((ndx >= p->desc_str_max) || (drq->wIndex != DEF_LANG))				goto err;		}		buf = p->desc_str[ndx];		len = p->desc_str_len[ndx];#ifdef DBG		printk("%s: get_descriptor string %d\n", ID, ndx);#endif		break;	default:		goto err;	}	ep_ctrl_write(p, buf, len);	return 0;err:#ifdef DBG	printk("%s: bad get_descriptor request\n", ID);#endif	return 1;}static int std_set_descriptor(struct d12 *p){#ifdef DBG	printk("%s: unsupported set_descriptor request\n", ID);#endif	return 1;}static int std_get_configuration(struct d12 *p){	struct devreq *drq;	unsigned char buf[1];	drq = &p->drq;	if (drq->bmRequestType != (REQTYPE_DIR_IN | REQTYPE_TYPE_STANDARD | REQTYPE_RECP_DEVICE))		goto err;	if (drq->wValue || drq->wIndex || (drq->wLength != 1))		goto err;	switch (p->fsm_dev) {	case FSM_DEV_DEFAULT:		goto err;	case FSM_DEV_ADDRESS:		buf[0] = 0;		break;	case FSM_DEV_CONFIGURED:		buf[0] = CONFIG_VAL;		break;	}	ep_ctrl_write(p, buf, drq->wLength);#ifdef DBG	printk("%s: get_configuration --> %d\n", ID, buf[0]);#endif	return 0;err:#ifdef DBG	printk("%s: bad get_configuration request\n", ID);#endif	return 1;}static int std_set_configuration(struct d12 *p){	struct devreq *drq;	int cfg;	drq = &p->drq;	if (drq->bmRequestType != (REQTYPE_DIR_OUT | REQTYPE_TYPE_STANDARD | REQTYPE_RECP_DEVICE))		goto err;	if ((drq->wValue & 0xFF00) || drq->wIndex || drq->wLength)		goto err;	cfg = drq->wValue & 0xFF;	switch (p->fsm_dev) {	case FSM_DEV_DEFAULT:		goto err;	case FSM_DEV_ADDRESS:		if (cfg == CONFIG_VAL) {			p->fsm_dev = FSM_DEV_CONFIGURED;			p->fsm_bulk = FSM_BULK_IDLE;			d12_set_endpoint_enable(p, 1);			d12_stall_bulk(p, 0);		} else if (cfg)			goto err;		break;	case FSM_DEV_CONFIGURED:		if (!cfg) {			p->fsm_dev = FSM_DEV_ADDRESS;			p->fsm_bulk = FSM_BULK_IDLE;			d12_stall_bulk(p, 1);			d12_set_endpoint_enable(p, 0);		} else if (cfg != CONFIG_VAL)			goto err;		break;	}	ep_ctrl_ack(p);#ifdef DBG	printk("%s: set_configuration %d\n", ID, cfg);#endif	return 0;err:#ifdef DBG	printk("%s: bad set_configuration request\n", ID);#endif	return 1;}static int std_get_interface(struct d12 *p){	struct devreq *drq;	unsigned char buf[1];	drq = &p->drq;	if (drq->bmRequestType != (REQTYPE_DIR_IN | REQTYPE_TYPE_STANDARD | REQTYPE_RECP_INTERFACE))		goto err;	if (drq->wValue || (drq->wLength != 1))		goto err;	switch (p->fsm_dev) {	case FSM_DEV_DEFAULT:	case FSM_DEV_ADDRESS:		goto err;	case FSM_DEV_CONFIGURED:		if (!(drq->wIndex & 0xFF))	/* only one interface / alternative setting */			buf[0] = 0;		else			goto err;		break;	}	ep_ctrl_write(p, buf, drq->wLength);#ifdef DBG	printk("%s: get_interface --> %d\n", ID, buf[0]);#endif	return 0;err:#ifdef DBG	printk("%s: bad get_interface request\n", ID);#endif	return 1;}static int std_set_interface(struct d12 *p){	struct devreq *drq;	drq = &p->drq;	if (drq->bmRequestType != (REQTYPE_DIR_OUT | REQTYPE_TYPE_STANDARD | REQTYPE_RECP_INTERFACE))		goto err;	if (drq->wLength)		goto err;	switch (p->fsm_dev) {	case FSM_DEV_DEFAULT:	case FSM_DEV_ADDRESS:		goto err;	case FSM_DEV_CONFIGURED:		if ((drq->wIndex & 0xFF) || drq->wValue)	/* only one interface / alternative setting */			goto err;		d12_stall_bulk(p, 0);		break;	}	ep_ctrl_ack(p);#ifdef DBG	printk("%s: set_interface %d\n", ID, drq->wIndex & 0xFF);#endif	return 0;err:#ifdef DBG	printk("%s: bad set_interface request\n", ID);#endif	return 1;}static int std_synch_frame(struct d12 *p){#ifdef DBG	printk("%s: unsupported synch_frame request\n", ID);#endif	return 1;}/* --- */static int cls_mass_storage_reset(struct d12 *p){	struct devreq *drq;	drq = &p->drq;	if (drq->bmRequestType != (REQTYPE_DIR_OUT | REQTYPE_TYPE_CLASS | REQTYPE_RECP_INTERFACE))		goto err;	if (drq->wValue || drq->wLength)		goto err;	if (drq->wIndex)			/* only one interface */		goto err;	p->fsm_bulk = FSM_BULK_IDLE;	ep_ctrl_ack(p);#ifdef DBG	printk("%s: set_interface %d\n", ID, drq->wIndex & 0xFF);#endif	return 0;err:#ifdef DBG	printk("%s: bad (class) mass_storage_reset request\n", ID);#endif	return 1;}static int cls_get_max_lun(struct d12 *p){	struct devreq *drq;	unsigned char buf[1];	drq = &p->drq;	if (drq->bmRequestType != (REQTYPE_DIR_IN | REQTYPE_TYPE_CLASS | REQTYPE_RECP_INTERFACE))		goto err;	if (drq->wValue || (drq->wLength != 1))		goto err;	if (drq->wIndex)			/* only one interface */		goto err;	buf[0] = p->max_lun - 1;	ep_ctrl_write(p, buf, drq->wLength);#ifdef DBG	printk("%s: (class) get_max_lun --> %d\n", ID, buf[0]);#endif	return 0;err:#ifdef DBG	printk("%s: bad (class) get_max_lun request\n", ID);#endif	return 1;}/* --- */#define MAX_REQ_STANDARD 13static int (* const T_STD_SETUP[MAX_REQ_STANDARD])(struct d12 *) = {	std_get_status,	std_clear_feature,	std_reserved,	std_set_feature,	std_reserved,	std_set_address,	std_get_descriptor,	std_set_descriptor,	std_get_configuration,	std_set_configuration,	std_get_interface,	std_set_interface,	std_synch_frame};#define MAX_REQ_CLASS 2static int (* const T_CLS_SETUP[MAX_REQ_CLASS])(struct d12 *) = {	cls_mass_storage_reset,	cls_get_max_lun};/* ------------------------------------------------------------------------- *//* * bulk and quazi-SCSI */#define BULK_NONE		0#define BULK_OUT		0#define BULK_IN			1#define SCHD_ERR_PHASE		1#define SCHD_ERR_INVALID_CDB	2#define SCHD_ERR_INVALID_LBA	3static void ep_bulk_write(struct d12 *p, const void *buf, int len){	if (p->bxferptr + len > p->bxferlen)		len = p->bxferlen - p->bxferptr;	if (len > MAX_CHUNKBUF)		len = MAX_CHUNKBUF;	p->bbuf = (unsigned char *)buf;	p->blen = len;	p->bptr = 0;	len = d12_buf_write(p, EPX_BULK_I, p->bbuf, len);	p->bptr += len;	p->bxferptr += len;	p->fsm_bulk = FSM_BULK_DATA_IN;}static void ep_bulk_read(struct d12 *p, void *buf, int len){	if (p->bxferptr + len > p->bxferlen)		len = p->bxferlen - p->bxferptr;	if (len > MAX_CHUNKBUF)		len = MAX_CHUNKBUF;	p->bbuf = (unsigned char *)buf;	p->blen = len;	p->bptr = 0;	if (p->fsm_bulk == FSM_BULK_DATA_OUT_WAIT) {		len = d12_buf_read(p, EPX_BULK_O, p->bbuf, len);		p->bptr += len;		p->bxferptr += len;	}	p->fsm_bulk = FSM_BULK_DATA_OUT;}/* --- */static int bulk_xfer_chk(struct d12 *p, int dir, int len){	struct cbw *cbw;	struct csw *csw;	int h, hi;	cbw = &p->cbw;	csw = &p->csw;	h = cbw->dCBWDataTransferLength;	hi = cbw->bmCBWFlags & CBW_FLAGS_DIR_IN;	p->bxferlen = p->bxferptr = 0;	if (dir == BULK_IN) {			/* Di */		if (!h)				/* Hn < Di */			goto phaserr;		else if (hi) {			/* Hi ? Di */			if (h >= len)		/* Hi >= Di */				p->bxferlen = len;			else 			/* Hi < Di */				goto phaserr;		} else				/* Ho <> Di */			goto phaserr;	} else if (len) {			/* Do */		if (!h)				/* Hn < Do */			goto phaserr;		else if (hi)			/* Hi <> Do */			goto phaserr;		else {				/* Ho ? Do */			if (h >= len)		/* Ho >= Do */				p->bxferlen = len;			else			/* Ho < Do */				goto phaserr;		}	}	return 0;phaserr:	csw->bCSWStatus = CSW_STAT_PHASE_ERROR;	csw->dCSWDataResidue = h;	return SCHD_ERR_PHASE;}static int bulk_xfer(struct d12 *p, int dir, const void *buf, int len){	int r;	r = bulk_xfer_chk(p, dir, len);	if (!r && len) {		if (dir == BULK_IN)			ep_bulk_write(p, buf, len);		else			ep_bulk_read(p, (void *)buf, len);	}

⌨️ 快捷键说明

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