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

📄 ide-taskfile.c

📁 at91rm9200处理器ide接口驱动程序源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	args.hobRegister[IDE_SELECT_OFFSET_HOB]  = hobfile->device_head;	args.hobRegister[IDE_CONTROL_OFFSET_HOB] = hobfile->control;	ide_init_drive_taskfile(&rq);	/* This is kept for internal use only !!! */	args.command_type = ide_cmd_type_parser (&args);	if (args.command_type != IDE_DRIVE_TASK_NO_DATA)		rq.current_nr_sectors = rq.nr_sectors = (hobfile->sector_count << 8) | taskfile->sector_count;	rq.cmd = IDE_DRIVE_TASKFILE;	rq.buffer = buf;	rq.special = &args;	return ide_do_drive_cmd(drive, &rq, ide_wait);}int ide_raw_taskfile (ide_drive_t *drive, ide_task_t *args, byte *buf){	struct request rq;	ide_init_drive_taskfile(&rq);	rq.cmd = IDE_DRIVE_TASKFILE;	rq.buffer = buf;	if (args->command_type != IDE_DRIVE_TASK_NO_DATA)		rq.current_nr_sectors = rq.nr_sectors = (args->hobRegister[IDE_NSECTOR_OFFSET_HOB] << 8) | args->tfRegister[IDE_NSECTOR_OFFSET];	rq.special = args;	return ide_do_drive_cmd(drive, &rq, ide_wait);}#ifdef CONFIG_IDE_TASK_IOCTL_DEBUGchar * ide_ioctl_verbose (unsigned int cmd){	return("unknown");}char * ide_task_cmd_verbose (byte task){	return("unknown");}#endif /* CONFIG_IDE_TASK_IOCTL_DEBUG *//* *  The taskfile glue table * *  reqtask.data_phase	reqtask.req_cmd *  			args.command_type		args.handler * *  TASKFILE_P_OUT_DMAQ	??				?? *  TASKFILE_P_IN_DMAQ	??				?? *  TASKFILE_P_OUT_DMA	??				?? *  TASKFILE_P_IN_DMA	??				?? *  TASKFILE_P_OUT	??				?? *  TASKFILE_P_IN	??				?? * *  TASKFILE_OUT_DMAQ	IDE_DRIVE_TASK_RAW_WRITE	NULL *  TASKFILE_IN_DMAQ	IDE_DRIVE_TASK_IN		NULL * *  TASKFILE_OUT_DMA	IDE_DRIVE_TASK_RAW_WRITE	NULL *  TASKFILE_IN_DMA	IDE_DRIVE_TASK_IN		NULL * *  TASKFILE_IN_OUT	??				?? * *  TASKFILE_MULTI_OUT	IDE_DRIVE_TASK_RAW_WRITE	task_mulout_intr *  TASKFILE_MULTI_IN	IDE_DRIVE_TASK_IN		task_mulin_intr * *  TASKFILE_OUT	IDE_DRIVE_TASK_RAW_WRITE	task_out_intr *  TASKFILE_OUT	IDE_DRIVE_TASK_OUT		task_out_intr * *  TASKFILE_IN		IDE_DRIVE_TASK_IN		task_in_intr *  TASKFILE_NO_DATA	IDE_DRIVE_TASK_NO_DATA		task_no_data_intr * *  			IDE_DRIVE_TASK_SET_XFER		task_no_data_intr *  			IDE_DRIVE_TASK_INVALID * */#define MAX_DMA		(256*SECTOR_WORDS)int ide_taskfile_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){	ide_task_request_t	*req_task;	ide_task_t		args;	byte *outbuf		= NULL;	byte *inbuf		= NULL;	task_ioreg_t *argsptr	= args.tfRegister;	task_ioreg_t *hobsptr	= args.hobRegister;	int err			= 0;	int tasksize		= sizeof(struct ide_task_request_s);	int taskin		= 0;	int taskout		= 0;	req_task = kmalloc(tasksize, GFP_KERNEL);	if (req_task == NULL) return -ENOMEM;	memset(req_task, 0, tasksize);	if (copy_from_user(req_task, (void *) arg, tasksize)) {		kfree(req_task);		return -EFAULT;	}	taskout = (int) req_task->out_size;	taskin  = (int) req_task->in_size;	if (taskout) {		int outtotal = tasksize;		outbuf = kmalloc(taskout, GFP_KERNEL);		if (outbuf == NULL) {			err = -ENOMEM;			goto abort;		}		memset(outbuf, 0, taskout);		if (copy_from_user(outbuf, (void *)arg + outtotal, taskout)) {			err = -EFAULT;			goto abort;		}	}	if (taskin) {		int intotal = tasksize + taskout;		inbuf = kmalloc(taskin, GFP_KERNEL);		if (inbuf == NULL) {			err = -ENOMEM;			goto abort;		}		memset(inbuf, 0, taskin);		if (copy_from_user(inbuf, (void *)arg + intotal , taskin)) {			err = -EFAULT;			goto abort;		}	}	memset(argsptr, 0, HDIO_DRIVE_TASK_HDR_SIZE);	memset(hobsptr, 0, HDIO_DRIVE_HOB_HDR_SIZE);	memcpy(argsptr, req_task->io_ports, HDIO_DRIVE_TASK_HDR_SIZE);	memcpy(hobsptr, req_task->hob_ports, HDIO_DRIVE_HOB_HDR_SIZE);	args.tf_in_flags  = req_task->in_flags;	args.tf_out_flags = req_task->out_flags;	args.data_phase   = req_task->data_phase;	args.command_type = req_task->req_cmd;#ifdef CONFIG_IDE_TASK_IOCTL_DEBUG	DTF("%s: ide_ioctl_cmd %s:  ide_task_cmd %s\n",		drive->name,		ide_ioctl_verbose(cmd),		ide_task_cmd_verbose(args.tfRegister[IDE_COMMAND_OFFSET]));#endif /* CONFIG_IDE_TASK_IOCTL_DEBUG */	switch(req_task->data_phase) {		case TASKFILE_OUT_DMAQ:		case TASKFILE_OUT_DMA:			args.prehandler = NULL;			args.handler = NULL;			args.posthandler = NULL;			err = ide_raw_taskfile(drive, &args, outbuf);			break;		case TASKFILE_IN_DMAQ:		case TASKFILE_IN_DMA:			args.prehandler = NULL;			args.handler = NULL;			args.posthandler = NULL;			err = ide_raw_taskfile(drive, &args, inbuf);			break;		case TASKFILE_IN_OUT:#if 0			args.prehandler = &pre_task_out_intr;			args.handler = &task_out_intr;			args.posthandler = NULL;			err = ide_raw_taskfile(drive, &args, outbuf);			args.prehandler = NULL;			args.handler = &task_in_intr;			args.posthandler = NULL;			err = ide_raw_taskfile(drive, &args, inbuf);			break;#else			err = -EFAULT;			goto abort;#endif		case TASKFILE_MULTI_OUT:			if (drive->mult_count) {				args.prehandler = &pre_task_out_intr;				args.handler = &task_mulout_intr;				args.posthandler = NULL;				err = ide_raw_taskfile(drive, &args, outbuf);			} else {				/* (hs): give up if multcount is not set */				printk("%s: %s Multimode Write " \					"multcount is not set\n",					 drive->name, __FUNCTION__);				err = -EPERM;				goto abort;			}			break;		case TASKFILE_OUT:			args.prehandler = &pre_task_out_intr;			args.handler = &task_out_intr;			args.posthandler = NULL;			err = ide_raw_taskfile(drive, &args, outbuf);			break;		case TASKFILE_MULTI_IN:			if (drive->mult_count) {				args.prehandler = NULL;				args.handler = &task_mulin_intr;				args.posthandler = NULL;				err = ide_raw_taskfile(drive, &args, inbuf);			} else {				/* (hs): give up if multcount is not set */				printk("%s: %s Multimode Read failure " \					"multcount is not set\n",					drive->name, __FUNCTION__);				err = -EPERM;				goto abort;			}			break;		case TASKFILE_IN:			args.prehandler = NULL;			args.handler = &task_in_intr;			args.posthandler = NULL;			err = ide_raw_taskfile(drive, &args, inbuf);			break;		case TASKFILE_NO_DATA:			args.prehandler = NULL;			args.handler = &task_no_data_intr;			args.posthandler = NULL;			err = ide_raw_taskfile(drive, &args, NULL);			break;		default:			args.prehandler = NULL;			args.handler = NULL;			args.posthandler = NULL;			err = -EFAULT;			goto abort;	}	memcpy(req_task->io_ports, &(args.tfRegister), HDIO_DRIVE_TASK_HDR_SIZE);	memcpy(req_task->hob_ports, &(args.hobRegister), HDIO_DRIVE_HOB_HDR_SIZE);	req_task->in_flags  = args.tf_in_flags;	req_task->out_flags = args.tf_out_flags;	if (copy_to_user((void *)arg, req_task, tasksize)) {		err = -EFAULT;		goto abort;	}	if (taskout) {		int outtotal = tasksize;		if (copy_to_user((void *)arg+outtotal, outbuf, taskout)) {			err = -EFAULT;			goto abort;		}	}	if (taskin) {		int intotal = tasksize + taskout;		if (copy_to_user((void *)arg+intotal, inbuf, taskin)) {			err = -EFAULT;			goto abort;		}	}abort:	kfree(req_task);	if (outbuf != NULL)		kfree(outbuf);	if (inbuf != NULL)		kfree(inbuf);	return err;}EXPORT_SYMBOL(task_read_24);EXPORT_SYMBOL(do_rw_taskfile);EXPORT_SYMBOL(do_taskfile);// EXPORT_SYMBOL(flagged_taskfile);//EXPORT_SYMBOL(ide_end_taskfile);EXPORT_SYMBOL(set_multmode_intr);EXPORT_SYMBOL(set_geometry_intr);EXPORT_SYMBOL(recal_intr);EXPORT_SYMBOL(task_no_data_intr);EXPORT_SYMBOL(task_in_intr);EXPORT_SYMBOL(task_mulin_intr);EXPORT_SYMBOL(pre_task_out_intr);EXPORT_SYMBOL(task_out_intr);EXPORT_SYMBOL(task_mulout_intr);EXPORT_SYMBOL(ide_init_drive_taskfile);EXPORT_SYMBOL(ide_wait_taskfile);EXPORT_SYMBOL(ide_raw_taskfile);EXPORT_SYMBOL(ide_pre_handler_parser);EXPORT_SYMBOL(ide_handler_parser);EXPORT_SYMBOL(ide_cmd_type_parser);EXPORT_SYMBOL(ide_taskfile_ioctl);#ifdef CONFIG_PKT_TASK_IOCTL#if 0{{ /* start cdrom */	struct cdrom_info *info = drive->driver_data;	if (info->dma) {		if (info->cmd == READ) {			info->dma = !HWIF(drive)->dmaproc(ide_dma_read, drive);		} else if (info->cmd == WRITE) {			info->dma = !HWIF(drive)->dmaproc(ide_dma_write, drive);		} else {			printk("ide-cd: DMA set, but not allowed\n");		}	}	/* Set up the controller registers. */	OUT_BYTE (info->dma, IDE_FEATURE_REG);	OUT_BYTE (0, IDE_NSECTOR_REG);	OUT_BYTE (0, IDE_SECTOR_REG);	OUT_BYTE (xferlen & 0xff, IDE_LCYL_REG);	OUT_BYTE (xferlen >> 8  , IDE_HCYL_REG);	if (IDE_CONTROL_REG)		OUT_BYTE (drive->ctl, IDE_CONTROL_REG);	if (info->dma)		(void) (HWIF(drive)->dmaproc(ide_dma_begin, drive));	if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) {		ide_set_handler (drive, handler, WAIT_CMD, cdrom_timer_expiry);		OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */		return ide_started;	} else {		OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */		return (*handler) (drive);	}} /* end cdrom */{ /* start floppy */	idefloppy_floppy_t *floppy = drive->driver_data;	idefloppy_bcount_reg_t bcount;	int dma_ok = 0;	floppy->pc=pc;		/* Set the current packet command */	pc->retries++;	pc->actually_transferred=0; /* We haven't transferred any data yet */	pc->current_position=pc->buffer;	bcount.all = IDE_MIN(pc->request_transfer, 63 * 1024);#ifdef CONFIG_BLK_DEV_IDEDMA	if (test_and_clear_bit (PC_DMA_ERROR, &pc->flags)) {		(void) HWIF(drive)->dmaproc(ide_dma_off, drive);	}	if (test_bit (PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma)		dma_ok=!HWIF(drive)->dmaproc(test_bit (PC_WRITING, &pc->flags) ? ide_dma_write : ide_dma_read, drive);#endif /* CONFIG_BLK_DEV_IDEDMA */	if (IDE_CONTROL_REG)		OUT_BYTE (drive->ctl,IDE_CONTROL_REG);	OUT_BYTE (dma_ok ? 1:0,IDE_FEATURE_REG);	/* Use PIO/DMA */	OUT_BYTE (bcount.b.high,IDE_BCOUNTH_REG);	OUT_BYTE (bcount.b.low,IDE_BCOUNTL_REG);	OUT_BYTE (drive->select.all,IDE_SELECT_REG);#ifdef CONFIG_BLK_DEV_IDEDMA	if (dma_ok) {	/* Begin DMA, if necessary */		set_bit (PC_DMA_IN_PROGRESS, &pc->flags);		(void) (HWIF(drive)->dmaproc(ide_dma_begin, drive));	}#endif /* CONFIG_BLK_DEV_IDEDMA */} /* end floppy */{ /* start tape */	idetape_tape_t *tape = drive->driver_data;#ifdef CONFIG_BLK_DEV_IDEDMA	if (test_and_clear_bit (PC_DMA_ERROR, &pc->flags)) {		printk (KERN_WARNING "ide-tape: DMA disabled, reverting to PIO\n");		(void) HWIF(drive)->dmaproc(ide_dma_off, drive);	}	if (test_bit (PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma)		dma_ok=!HWIF(drive)->dmaproc(test_bit (PC_WRITING, &pc->flags) ? ide_dma_write : ide_dma_read, drive);#endif /* CONFIG_BLK_DEV_IDEDMA */	if (IDE_CONTROL_REG)		OUT_BYTE (drive->ctl,IDE_CONTROL_REG);	OUT_BYTE (dma_ok ? 1:0,IDE_FEATURE_REG);	/* Use PIO/DMA */	OUT_BYTE (bcount.b.high,IDE_BCOUNTH_REG);	OUT_BYTE (bcount.b.low,IDE_BCOUNTL_REG);	OUT_BYTE (drive->select.all,IDE_SELECT_REG);#ifdef CONFIG_BLK_DEV_IDEDMA	if (dma_ok) {	/* Begin DMA, if necessary */		set_bit (PC_DMA_IN_PROGRESS, &pc->flags);		(void) (HWIF(drive)->dmaproc(ide_dma_begin, drive));	}#endif /* CONFIG_BLK_DEV_IDEDMA */	if (test_bit(IDETAPE_DRQ_INTERRUPT, &tape->flags)) {		ide_set_handler(drive, &idetape_transfer_pc, IDETAPE_WAIT_CMD, NULL);		OUT_BYTE(WIN_PACKETCMD, IDE_COMMAND_REG);		return ide_started;	} else {		OUT_BYTE(WIN_PACKETCMD, IDE_COMMAND_REG);		return idetape_transfer_pc(drive);	}} /* end tape */}#endifint pkt_taskfile_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){#if 0	switch(req_task->data_phase) {		case TASKFILE_P_OUT_DMAQ:		case TASKFILE_P_IN_DMAQ:		case TASKFILE_P_OUT_DMA:		case TASKFILE_P_IN_DMA:		case TASKFILE_P_OUT:		case TASKFILE_P_IN:	}#endif	return -ENOMSG;}EXPORT_SYMBOL(pkt_taskfile_ioctl);#endif /* CONFIG_PKT_TASK_IOCTL */

⌨️ 快捷键说明

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