int cdfs_cdda_file_read(struct inode * inode, char * buf, size_t count, unsigned start, int raw) { unsigned stop=start+count; int status=0; if (raw) //For audio CD raw=0, CDDA will not enter here unless using -option, let raw=1 { //Audio CD will not enter here status=cdfs_copy_from_cd(inode->i_sb, inode->i_ino, start, stop, buf); } else { //#define WAV_HEADER_SIZE 44 @ all.h //PRINT("david: start=%d, stop=%d\n",start,stop); if (start < WAV_HEADER_SIZE) { if (stop > WAV_HEADER_SIZE) { //Enter here once to make the file header //david: recurrsively calling subroutine!! status=cdfs_cdda_file_read( inode, buf, WAV_HEADER_SIZE-start, start , 0 ); status=cdfs_cdda_file_read( inode, buf+WAV_HEADER_SIZE-start, stop-WAV_HEADER_SIZE, WAV_HEADER_SIZE, 0 ); } else { char temp[44]; cdfs_make_header(temp, inode->i_size); memcpy(buf, temp+start, stop-start); } } else { start -= WAV_HEADER_SIZE; stop -= WAV_HEADER_SIZE; status=cdfs_copy_from_cd(inode->i_sb, inode->i_ino, start, stop, buf); } } return status; }
void cdfs_cdda_file_read(struct inode * inode, char * buf, size_t count, unsigned start, int raw){ unsigned stop=start+count; PRINT("cdda_file_read(%x, %x, %d, %d)\n", inode, buf, count, start); if (raw) { cdfs_copy_from_cd(inode->i_sb, inode->i_ino, start, stop, buf); } else { if (start < WAV_HEADER_SIZE) { if (stop > WAV_HEADER_SIZE) { cdfs_cdda_file_read( inode, buf, WAV_HEADER_SIZE-start, start , 0 ); cdfs_cdda_file_read( inode, buf+WAV_HEADER_SIZE-start, stop-WAV_HEADER_SIZE, WAV_HEADER_SIZE, 0 ); } else { char temp[44]; cdfs_make_header(temp, inode->i_size); memcpy(buf, temp+start, stop-start); } } else { start -= WAV_HEADER_SIZE; stop -= WAV_HEADER_SIZE; cdfs_copy_from_cd(inode->i_sb, inode->i_ino, start, stop, buf); } } }
static void kcdfsd_process_request(void){ struct list_head * tmp; struct kcdfsd_req * req; struct page * page; struct inode * inode; unsigned request; while (!list_empty (&kcdfsd_req_list)){ /* Grab the next entry from the beginning of the list */ tmp = kcdfsd_req_list.next; req = list_entry (tmp, struct kcdfsd_req, req_list); list_del (tmp); page = req->page; inode = req->dentry->d_inode; request = req->request_type; if (!PageLocked(page)) #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12)) PAGE_BUG(page); #else BUG(); #endif switch (request){ case CDDA_REQUEST: case CDDA_RAW_REQUEST: { cd *this_cd = cdfs_info (inode->i_sb); char *p; track_info *this_track = &(this_cd->track[inode->i_ino]); cdfs_cdda_file_read (inode, p = (char *) kmap (page), 1 << PAGE_CACHE_SHIFT, (page->index << PAGE_CACHE_SHIFT) + ((this_track->avi) ? this_track-> avi_offset : 0), (request == CDDA_RAW_REQUEST)); if ((this_track->avi) && (this_track->avi_swab)){ int k; for (k=0; k<(1 << PAGE_CACHE_SHIFT); k+=2){ char c; c = p[k]; p[k] = p[k + 1]; p[k + 1] = c; } } } break; case CDXA_REQUEST: cdfs_copy_from_cdXA(inode->i_sb, inode->i_ino, page->index << PAGE_CACHE_SHIFT, (page->index + 1) << PAGE_CACHE_SHIFT, (char *)kmap(page)); break; case CDDATA_REQUEST: cdfs_copy_from_cddata(inode->i_sb, inode->i_ino, page->index << PAGE_CACHE_SHIFT, (page->index + 1) << PAGE_CACHE_SHIFT, (char *)kmap(page)); break; case CDHFS_REQUEST: cdfs_copy_from_cdhfs(inode->i_sb, inode->i_ino, page->index << PAGE_CACHE_SHIFT, (page->index + 1) << PAGE_CACHE_SHIFT, (char *)kmap(page)); break; } SetPageUptodate (page); kunmap (page); unlock_page (page); kfree (req); } }