int cdfs_read_raw_frame2(struct super_block * sb, int lba, unsigned char *buf,unsigned int data_size) { /* struct cdrom_msf *msf; msf = (struct cdrom_msf*) buf; msf->cdmsf_min0 = (lba + CD_MSF_OFFSET) / CD_FRAMES / CD_SECS; msf->cdmsf_sec0 = (lba + CD_MSF_OFFSET) / CD_FRAMES % CD_SECS; msf->cdmsf_frame0 = (lba + CD_MSF_OFFSET) % CD_FRAMES; if(data_size==2048) { PRINTC("david0213: data_size==2048, using CDROMREADMODE2\n"); return cdfs_ioctl(sb, CDROMREADMODE2, (unsigned long)msf); } else { PRINTC("david0213: data_size!=2048, using CDROMREADRAW\n"); return cdfs_ioctl(sb, CDROMREADRAW, (unsigned long)msf); //david 1014 } */ static struct cdrom_generic_command cgc; static struct request_sense buffer2; unsigned char *frame; int ret; memset(&cgc, 0, sizeof(cgc)); if(data_size==2048) { PRINTC("david0213: data_size==2048, using CDROMREADMODE2\n"); frame = kmalloc(CD_FRAMESIZE_RAW, GFP_KERNEL); if (!frame) { printk("memory allocation failed in cdfs_read_raw_frame2\n"); return 0; } cgc.sense = &buffer2; cgc.buffer = frame; cgc.buflen=CD_FRAMESIZE_RAW; cgc.data_direction=CGC_DATA_READ; cgc.quiet = 1; cgc.stat = 1; cgc.cmd[0]=GPCMD_READ_CD; cgc.cmd[1]= 0<<2; cgc.cmd[2]=(lba>>24)&0xff; // MSB cgc.cmd[3]=(lba>>16)&0xff; cgc.cmd[4]=(lba>>8 )&0xff; cgc.cmd[5]=(lba )&0xff; // LSB cgc.cmd[8]=1; //Transfer length in blocks LSB cgc.cmd[9]=0xf8; ret=cdfs_ioctl( sb, CDROM_SEND_PACKET, (unsigned int)&cgc ); if (!ret) memcpy(buf, frame+16, CD_FRAMESIZE_RAW0); kfree(frame); return(ret); }
int cdfs_read_cd(struct super_block *s, struct cdrom_read_audio *cdda, char* buff) { static struct cdrom_generic_command cgc; static struct request_sense buffer2; int ret; int sector; ret=0; sector=(*cdda).addr.lba; cgc.sense = &buffer2; cgc.buffer = buff; cgc.buflen=CD_FRAMESIZE_RAW_Q; cgc.data_direction=CGC_DATA_READ; cgc.quiet = 1; cgc.stat = 1; cgc.cmd[0]=GPCMD_READ_CD; //cgc.cmd[1]=1<<2; //Expected Sector Type cgc.cmd[1]=0; cgc.cmd[2]=(sector>>24)&0xff; //Sector MSB cgc.cmd[3]=(sector>>16)&0xff; //Sector cgc.cmd[4]=(sector>>8 )&0xff; //Sector cgc.cmd[5]=(sector )&0xff; //Sector LSB cgc.cmd[6]=0; //Transfer length in blocks MSB cgc.cmd[7]=0; //Transfer length in blocks cgc.cmd[8]=1; //Transfer length in blocks LSB //cgc.cmd[9]=1<<4; cgc.cmd[9]=0xf8; #ifdef CONFIG_USE_CDDA_SUBCHANNEL cgc.cmd[10]=2; #else cgc.cmd[10]=0; #endif cgc.cmd[11]=0; //printk("Reading sector %2d ST\n",sector); ret=cdfs_ioctl( s, CDROM_SEND_PACKET, (unsigned int)&cgc ); //printk("buff[2352]=0x%x buff[2353]=0x%x\n",buff[2352],buff[2353]); //buff[2352]|=0x10; //printk("buff[2352]=0x%x buff[2353]=0x%x\n",buff[2352],buff[2353]); //printk("Reading sector %2d SP and ret=%d asc=%d ascq=%d\n",sector,ret,(cgc.sense)->asc,(cgc.sense)->ascq); return ret; }
void cdfs_copy_from_cd(struct super_block * sb, int inode, unsigned int start, unsigned int stop, char * buf){ int start_sector, start_byte, stop_sector, stop_byte, sector; int status; struct cdrom_read_audio cdda; unsigned int read_size=CD_FRAMESIZE_RAW; cd * this_cd = cdfs_info(sb); unsigned start_lba=this_cd->track[inode].start_lba; /* cache */ char * temp, * temp2; char * temp_start; int temp_length; PRINT("copy_from_cd(%x, %d, %d, %d, %x)\n", sb, inode, start, stop, buf); temp = this_cd->cache; start_sector = start/read_size; start_byte = start%read_size; stop_sector = stop/read_size; stop_byte = stop%read_size; start_sector += start_lba; stop_sector += start_lba; if (!stop_byte) { /* empty frame */ stop_sector -= 1; stop_byte = CD_FRAMESIZE_RAW; } PRINT("%d[%d-%d] -> 0x%x...0x%x ... (%d,%d),(%d,%d)\n", inode, start, stop, (int)buf, (int)buf+stop-start, start_sector,start_byte,stop_sector,stop_byte); cdda.addr_format = CDROM_LBA; cdda.nframes = CACHE_SIZE; cdda.buf = temp; // testen of eindadres>CD for (sector=start_sector; sector<=stop_sector; sector++){ PRINT("cache holds [%d-%d], we want sector=%d\n", this_cd->cache_sector, this_cd->cache_sector+CACHE_SIZE-1, sector); if (!((this_cd->cache_sector<=sector) && (sector<this_cd->cache_sector+CACHE_SIZE))) { PRINT("reading sector %d from CD\n", sector); this_cd->cache_sector = cdda.addr.lba = sector; status = cdfs_ioctl(sb, CDROMREADAUDIO, (unsigned long)&cdda); if (status) { printk("copy_from_cd(%d) ioctl failed: %d\n", cdda.addr.lba, status); return; } } else { PRINT("getting sector %d from cache\n", sector); } temp2=temp+(sector-this_cd->cache_sector)*CD_FRAMESIZE_RAW; if (sector==start_sector) { temp_start = temp2+start_byte; if (sector!=stop_sector) temp_length = read_size-start_byte; else temp_length = stop_byte-start_byte; } else if (sector==stop_sector) { temp_start = temp2; temp_length = stop_byte; } else { temp_start = temp2; temp_length = read_size; } PRINT("memcpy(0x%x, %x, %d)\n",(int)buf, (int)temp_start, temp_length); memcpy(buf, (char*)temp_start, temp_length); buf += temp_length; } }
static struct super_block * cdfs_mount(struct super_block *sb, void *data, int silent){ kdev_t dev = sb->s_dev; int i, j, t; struct cdrom_tochdr hdr; #else static int cdfs_fill_super(struct super_block *sb, void *data, int silent){ int i, t; #endif struct cdrom_tocentry entry; int no_audio=0, no_data=0; cd * this_cd; struct inode *retinode; PRINT("cdfs_mount\n"); #ifdef OLD_KERNEL MOD_INC_USE_COUNT; set_blocksize(dev, CD_FRAMESIZE); // voor bread met ide-cd #else sb_set_blocksize(sb, CD_FRAMESIZE); // voor bread met ide-cd #endif sb->s_blocksize = CD_FRAMESIZE; sb->s_blocksize_bits = 11; if (!(this_cd = cdfs_info(sb) = kmalloc(sizeof(cd), GFP_KERNEL))){ #ifdef OLD_KERNEL MOD_DEC_USE_COUNT; return NULL; #else return -ENOMEM; #endif } this_cd->mode = MODE; this_cd->gid = GID; this_cd->uid = UID; this_cd->single = FALSE; this_cd->raw_audio = 0; this_cd->toc_scsi = FALSE; // Initialize cache for maximum sector size if (!(this_cd->cache = kmalloc(CD_FRAMESIZE_RAWER*CACHE_SIZE, GFP_KERNEL))) { #ifdef OLD_KERNEL MOD_DEC_USE_COUNT; return NULL; #else kfree(cdfs_info(sb)); return -ENOMEM; #endif } // Cache is still invalid this_cd->cache_sector = -CACHE_SIZE; cdfs_parse_options((char *) data, this_cd); /* Populate CD info with '.' and '..' */ strcpy(this_cd->track[1].name, "."); this_cd->track[1].start_lba=0; strcpy(this_cd->track[2].name, ".."); this_cd->track[2].start_lba=0; this_cd->nr_iso_sessions = 0; this_cd->size = 0; if (this_cd->toc_scsi){ if (cdfs_toc_read_full(sb)){ printk("TOC read failed\n"); #ifdef OLD_KERNEL MOD_DEC_USE_COUNT; return NULL; #else goto invalid; #endif } } else { //if (cdfs_ioctl(sb, CDROMREADTOCHDR, (unsigned long)&hdr)){ if (cdfs_toc_read(sb)){ printk("cdfs_toc_read failed\n"); #ifdef OLD_KERNEL MOD_DEC_USE_COUNT; return NULL; #else goto invalid; #endif } } PRINT("CD contains %d tracks\n", this_cd->tracks); /* Collect track info */ entry.cdte_format = CDROM_LBA; for (t=this_cd->tracks; t>=0; t--) { i = T2I(t); // j = this_cd->tracks-i; // entry.cdte_track = (t==this_cd->tracks) ? CDROM_LEADOUT : t+1; // PRINT("Read track %d/%d/%d\n", entry.cdte_track, t, i); // if (cdfs_ioctl(sb, CDROMREADTOCENTRY, (unsigned long)&entry)){ // printk("ioctl(CDROMREADTOCENTRY) failed\n"); // MOD_DEC_USE_COUNT; // return NULL; // } // this_cd->track[i].start_lba = entry.cdte_addr.lba; // this_cd->track[i].stop_lba = this_cd->track[i+1].start_lba - 1; this_cd->track[i].track_size = this_cd->track[i+1].start_lba - this_cd->track[i].start_lba; /* in sectors! */ PRINT("Start[%d]: %d\n", i, this_cd->track[i].start_lba); if (t!=this_cd->tracks) { /* all tracks but the LEADOUT */ if (this_cd->track[i].type==DATA) { //int track=i; no_data++; this_cd->track[i].iso_info = cdfs_get_iso_info(sb, i); if (this_cd->track[i].iso_info) { this_cd->track[i].time = cdfs_constructtime((char*)&(this_cd->track[i].iso_info->creation_date)); this_cd->track[i].iso_size = cdfs_constructsize((char*)&(this_cd->track[i].iso_info->volume_space_size)) * CD_FRAMESIZE; if (!this_cd->single) this_cd->track[i].iso_size += this_cd->track[i].start_lba * CD_FRAMESIZE; this_cd->track[i].track_size *= CD_FRAMESIZE; this_cd->track[i].size = this_cd->track[i+1].start_lba * CD_FRAMESIZE; sprintf(this_cd->track[i].name, this_cd->single ? DATA_NAME_SINGLE : DATA_NAME_ISO, t+1); this_cd->lba_iso_sessions[this_cd->nr_iso_sessions].start = this_cd->track[i].start_lba; this_cd->lba_iso_sessions[this_cd->nr_iso_sessions].stop = this_cd->track[i].iso_size/CD_FRAMESIZE; this_cd->nr_iso_sessions++; cdfs_get_hfs_info(sb, i); // possibly also a HFS } else { // DATA, but no ISO -> either HFS or VideoCD if (cdfs_get_hfs_info(sb, i)==-1){ printk("CHECKING VIDEOCD!!\n"); cdfs_get_XA_info(sb, i); this_cd->track[i].time = 0; this_cd->track[i].iso_size = 0; this_cd->track[i].track_size = (this_cd->track[i].track_size-1) * this_cd->track[i].xa_data_size; this_cd->track[i].size = this_cd->track[i].track_size; sprintf(this_cd->track[i].name, DATA_NAME_VCD, no_data); } else { // HFS, no ISO, no VideoCD -> remove track this_cd->track[i].iso_info = NULL; this_cd->track[i].type = 0; } } } else { no_audio++; this_cd->track[i].iso_info = NULL; this_cd->track[i].type = AUDIO; this_cd->track[i].time = get_seconds(); this_cd->track[i].iso_size = 0; this_cd->track[i].track_size = this_cd->track[i].track_size * CD_FRAMESIZE_RAW + ((this_cd->raw_audio==0)?WAV_HEADER_SIZE:0); this_cd->track[i].size = this_cd->track[i].track_size; this_cd->track[i].avi = 0; sprintf(this_cd->track[i].name, (this_cd->raw_audio)? RAW_AUDIO_NAME:AUDIO_NAME, t+1); if (this_cd->raw_audio) { /* read the first sector. */ struct cdrom_read_audio cdda; int status,k,j,prevk=0; char* buf; buf=kmalloc(CD_FRAMESIZE_RAW*2,GFP_KERNEL); if(buf==NULL) { printk(FSNAME ": kmalloc failed in root.c !\n"); return(-ENOMEM); } for (j=0;j<10;j++) { cdda.addr_format = CDROM_LBA; cdda.nframes = 1; cdda.buf = buf+CD_FRAMESIZE_RAW; cdda.addr.lba = this_cd->track[i].start_lba+j; status = cdfs_ioctl(sb,CDROMREADAUDIO,(unsigned long)&cdda); if (status) { printk("cdfs_ioctl(CDROMREADAUDIO,%d) ioctl failed: %d\n", cdda.addr.lba, status); goto out; } /* search the first non-zero byte */ for (k=0;k<CD_FRAMESIZE_RAW;k++) if (buf[k+CD_FRAMESIZE_RAW]) break; if (k<=CD_FRAMESIZE_RAW-4) break; prevk=k; if (k<CD_FRAMESIZE_RAW) for (k=0;k<CD_FRAMESIZE_RAW;k++) buf[k]=buf[k+CD_FRAMESIZE_RAW]; } if (j==10) goto out; if ((j!=0)&&(prevk!=CD_FRAMESIZE_RAW)) { k=prevk; j--; } else k+=CD_FRAMESIZE_RAW; this_cd->track[i].avi_offset = j*CD_FRAMESIZE_RAW+k-CD_FRAMESIZE_RAW; if ((buf[k]=='R')&&(buf[k+1]=='I')&& (buf[k+2]=='F')&&(buf[k+3]=='F')) { this_cd->track[i].avi = 1; this_cd->track[i].avi_swab = 0; } else if ((buf[k]=='I')&&(buf[k+1]=='R')&& (buf[k+2]=='F')&&(buf[k+3]=='F')) { this_cd->track[i].avi = 1; this_cd->track[i].avi_swab = 1; } if (this_cd->track[i].avi) { if ((this_cd->track[i].avi_offset&1)!=0) { printk("AVI offset is not even, error\n"); this_cd->track[i].avi=0; } else { this_cd->track[i].track_size -= this_cd->track[i].avi_offset; sprintf(this_cd->track[i].name, AVI_AUDIO_NAME, t+1); } } out: kfree(buf); } } // Calculate total CD size this_cd->size += this_cd->track[i].track_size; PRINT("Track %2d: (%dB)\n", t, this_cd->track[i].size); } // else CDROM_LEADOUT } PRINT("CD ends at %d\n", this_cd->track[this_cd->tracks].start_lba); /* take care to get disc id after the toc has been read. JP, 29-12-2001 */ this_cd->discid = discid(this_cd); //////////////////////////////// /* Check if CD is bootable */ if (this_cd->track[T2I(0)].type==DATA) cdfs_check_bootable(sb); /* Check for an HFS partition in the first data track */ /*if (no_data) { i=T2I(0); while (i<T2I(this_cd->tracks)) { if (this_cd->track[i].type==DATA) break; i++; } cdfs_get_hfs_info(sb, i); } */ PRINT("%d audio tracks and %d data tracks => %dbytes\n", no_audio, no_data, this_cd->size); sb->s_magic = CDFS_MAGIC; sb->s_flags |= MS_RDONLY; sb->s_op = &cdfs_ops; /* always get inode status */ #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,24) retinode=cdfs_iget(sb, 0); #else retinode=iget(sb, 0); #endif if ( IS_ERR(retinode) ) return PTR_ERR(retinode); PRINT("retinode = %ld\n", retinode->i_ino); sb->s_root = d_alloc_root(retinode); cdfs_proc_cd = this_cd; #ifdef OLD_KERNEL return sb; #else return 0; invalid: kfree(this_cd->cache); kfree(cdfs_info(sb)); return -EINVAL; #endif }