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

📄 sr_ioctl.c

📁 GNU Mach 微内核源代码, 基于美国卡内基美隆大学的 Mach 研究项目
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <linux/kernel.h>#include <linux/sched.h>#include <linux/mm.h>#include <linux/fs.h>#include <asm/segment.h>#include <linux/errno.h>#include <linux/string.h>#include <linux/blk.h>#include "scsi.h"#include "hosts.h"#include "sr.h"#include <scsi/scsi_ioctl.h>#include <linux/cdrom.h>extern void get_sectorsize(int);extern void sr_photocd(struct inode *);#define IOCTL_RETRIES 3/* The CDROM is fairly slow, so we need a little extra time *//* In fact, it is very slow if it has to spin up first */#define IOCTL_TIMEOUT 3000static void sr_ioctl_done(Scsi_Cmnd * SCpnt){    struct request * req;        req = &SCpnt->request;    req->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */        if (req->sem != NULL) {	up(req->sem);    }}/* We do our own retries because we want to know what the specific   error code is.  Normally the UNIT_ATTENTION code will automatically   clear after one error */static int do_ioctl(int target, unsigned char * sr_cmd, void * buffer, unsigned buflength){    Scsi_Cmnd * SCpnt;    int result;    SCpnt = allocate_device(NULL, scsi_CDs[target].device, 1);    {	struct semaphore sem = MUTEX_LOCKED;	SCpnt->request.sem = &sem;	scsi_do_cmd(SCpnt,		    (void *) sr_cmd, buffer, buflength, sr_ioctl_done, 		    IOCTL_TIMEOUT, IOCTL_RETRIES);	down(&sem);    }        result = SCpnt->result;        /* Minimal error checking.  Ignore cases we know about, and report the rest. */    if(driver_byte(result) != 0)	switch(SCpnt->sense_buffer[2] & 0xf) {	case UNIT_ATTENTION:	    scsi_CDs[target].device->changed = 1;	    printk("Disc change detected.\n");	    break;	case NOT_READY: /* This happens if there is no disc in drive */	    printk("CDROM not ready.  Make sure there is a disc in the drive.\n");	    break;	case ILLEGAL_REQUEST:	  /* CDROMCLOSETRAY should not print an error for caddy drives. */	    if (!(sr_cmd[0] == START_STOP && sr_cmd[4] == 0x03))	      printk("CDROM (ioctl) reports ILLEGAL REQUEST.\n");	    break;	default:	    printk("SCSI CD error: host %d id %d lun %d return code = %03x\n", 		   scsi_CDs[target].device->host->host_no, 		   scsi_CDs[target].device->id,		   scsi_CDs[target].device->lun,		   result);	    printk("\tSense class %x, sense error %x, extended sense %x\n",		   sense_class(SCpnt->sense_buffer[0]), 		   sense_error(SCpnt->sense_buffer[0]),		   SCpnt->sense_buffer[2] & 0xf);	    	};        result = SCpnt->result;    SCpnt->request.rq_status = RQ_INACTIVE; /* Deallocate */    wake_up(&SCpnt->device->device_wait);    /* Wake up a process waiting for device*/    return result;}int sr_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg){    u_char  sr_cmd[10];        kdev_t dev = inode->i_rdev;    int result, target, err;        target = MINOR(dev);        if (target >= sr_template.nr_dev ||	!scsi_CDs[target].device) return -ENXIO;        switch (cmd)     {	/* Sun-compatible */    case CDROMPAUSE:		sr_cmd[0] = SCMD_PAUSE_RESUME;	sr_cmd[1] = scsi_CDs[target].device->lun << 5;	sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = 0;	sr_cmd[5] = sr_cmd[6] = sr_cmd[7] = 0;	sr_cmd[8] = 0;	sr_cmd[9] = 0;		result = do_ioctl(target, sr_cmd, NULL, 255);	return result;	    case CDROMRESUME:		sr_cmd[0] = SCMD_PAUSE_RESUME;	sr_cmd[1] = scsi_CDs[target].device->lun << 5;	sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = 0;	sr_cmd[5] = sr_cmd[6] = sr_cmd[7] = 0;	sr_cmd[8] = 1;	sr_cmd[9] = 0;		result = do_ioctl(target, sr_cmd, NULL, 255);		return result;	    case CDROMPLAYMSF:    {	struct cdrom_msf msf;        err = verify_area (VERIFY_READ, (void *) arg, sizeof (msf));        if (err) return err;	memcpy_fromfs(&msf, (void *) arg, sizeof(msf));		sr_cmd[0] = SCMD_PLAYAUDIO_MSF;	sr_cmd[1] = scsi_CDs[target].device->lun << 5;	sr_cmd[2] = 0;	sr_cmd[3] = msf.cdmsf_min0;	sr_cmd[4] = msf.cdmsf_sec0;	sr_cmd[5] = msf.cdmsf_frame0;	sr_cmd[6] = msf.cdmsf_min1;	sr_cmd[7] = msf.cdmsf_sec1;	sr_cmd[8] = msf.cdmsf_frame1;	sr_cmd[9] = 0;		result = do_ioctl(target, sr_cmd, NULL, 255);	return result;    }    case CDROMPLAYBLK:    {	struct cdrom_blk blk;        err = verify_area (VERIFY_READ, (void *) arg, sizeof (blk));        if (err) return err;	memcpy_fromfs(&blk, (void *) arg, sizeof(blk));		sr_cmd[0] = SCMD_PLAYAUDIO10;	sr_cmd[1] = scsi_CDs[target].device->lun << 5;	sr_cmd[2] = blk.from >> 24;	sr_cmd[3] = blk.from >> 16;	sr_cmd[4] = blk.from >> 8;	sr_cmd[5] = blk.from;	sr_cmd[6] = 0;	sr_cmd[7] = blk.len >> 8;	sr_cmd[8] = blk.len;	sr_cmd[9] = 0;		result = do_ioctl(target, sr_cmd, NULL, 255);	return result;    }		    case CDROMPLAYTRKIND:    {	struct cdrom_ti ti;        err = verify_area (VERIFY_READ, (void *) arg, sizeof (ti));        if (err) return err;	memcpy_fromfs(&ti, (void *) arg, sizeof(ti));		sr_cmd[0] = SCMD_PLAYAUDIO_TI;	sr_cmd[1] = scsi_CDs[target].device->lun << 5;	sr_cmd[2] = 0;	sr_cmd[3] = 0;	sr_cmd[4] = ti.cdti_trk0;	sr_cmd[5] = ti.cdti_ind0;	sr_cmd[6] = 0;	sr_cmd[7] = ti.cdti_trk1;	sr_cmd[8] = ti.cdti_ind1;	sr_cmd[9] = 0;		result = do_ioctl(target, sr_cmd, NULL, 255);		return result;    }	    case CDROMREADTOCHDR:    {	struct cdrom_tochdr tochdr;	char * buffer;		sr_cmd[0] = SCMD_READ_TOC;	sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5);	sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = sr_cmd[5] = 0;	sr_cmd[6] = 0;	sr_cmd[7] = 0;              /* MSB of length (12) */	sr_cmd[8] = 12;             /* LSB of length */	sr_cmd[9] = 0;		buffer = (unsigned char *) scsi_malloc(512);	if(!buffer) return -ENOMEM;		result = do_ioctl(target, sr_cmd, buffer, 12);		tochdr.cdth_trk0 = buffer[2];	tochdr.cdth_trk1 = buffer[3];		scsi_free(buffer, 512);		err = verify_area (VERIFY_WRITE, (void *) arg, sizeof (struct cdrom_tochdr));	if (err)	    return err;	memcpy_tofs ((void *) arg, &tochdr, sizeof (struct cdrom_tochdr));		return result;    }	    case CDROMREADTOCENTRY:    {	struct cdrom_tocentry tocentry;	unsigned char * buffer;	        err = verify_area (VERIFY_READ, (void *) arg, sizeof (struct cdrom_tocentry));        if (err) return err;	memcpy_fromfs (&tocentry, (void *) arg, sizeof (struct cdrom_tocentry));		sr_cmd[0] = SCMD_READ_TOC;	sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) |          (tocentry.cdte_format == CDROM_MSF ? 0x02 : 0);	sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = sr_cmd[5] = 0;	sr_cmd[6] = tocentry.cdte_track;	sr_cmd[7] = 0;             /* MSB of length (12)  */	sr_cmd[8] = 12;            /* LSB of length */	sr_cmd[9] = 0;		buffer = (unsigned char *) scsi_malloc(512);	if(!buffer) return -ENOMEM;		result = do_ioctl (target, sr_cmd, buffer, 12);	        tocentry.cdte_ctrl = buffer[5] & 0xf;	        tocentry.cdte_adr = buffer[5] >> 4;        tocentry.cdte_datamode = (tocentry.cdte_ctrl & 0x04) ? 1 : 0;	if (tocentry.cdte_format == CDROM_MSF) {	    tocentry.cdte_addr.msf.minute = buffer[9];	    tocentry.cdte_addr.msf.second = buffer[10];	    tocentry.cdte_addr.msf.frame = buffer[11];	}	else	    tocentry.cdte_addr.lba = (((((buffer[8] << 8) + buffer[9]) << 8)                                       + buffer[10]) << 8) + buffer[11];		scsi_free(buffer, 512);		err = verify_area (VERIFY_WRITE, (void *) arg, sizeof (struct cdrom_tocentry));	if (err)	    return err;	memcpy_tofs ((void *) arg, &tocentry, sizeof (struct cdrom_tocentry));		return result;    }	    case CDROMSTOP:	sr_cmd[0] = START_STOP;	sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 1;	sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;	sr_cmd[4] = 0;		result = do_ioctl(target, sr_cmd, NULL, 255);	return result;	    case CDROMSTART:	sr_cmd[0] = START_STOP;	sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 1;	sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;	sr_cmd[4] = 1;		result = do_ioctl(target, sr_cmd, NULL, 255);	return result;	    case CDROMCLOSETRAY:	sr_cmd[0] = START_STOP;	sr_cmd[1] = ((scsi_CDs[target].device -> lun) << 5);	sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;

⌨️ 快捷键说明

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