static void _flushData(int fd) { int rd = 0; struct itimerval ti, oti; char buf[1024]; int len = 1023; int count = 200; usleep(d4RdTimeout); /* for error handling in case of timeout */ timeoutGot = 0; /* set errno to 0 in order to get correct informations */ /* in case of error */ errno = 0; if (debugD4) fprintf(stderr, "flush data: length: %i\n", len); do { usleep(d4RdTimeout); SET_TIMER(ti,oti, d4RdTimeout); rd = read(fd, buf, len); if (debugD4) fprintf(stderr, "flush: read: %i %s\n", rd, rd < 0 && errno != 0 ?strerror(errno) : ""); RESET_TIMER(ti,oti); count--; } while ( count > 0 && (rd > 0 || (rd < 0 && errno == EAGAIN))); }
int xfer(uint32_t *data_) { uint32_t data = *data_; int i; //WAIT_WITH_TIMEOUT(!(GBA_IN&(1<<MISO_BIT)), 25600, goto error); cli(); RESET_TIMER(); for (i=0;i<32;i++) { GBA_OUT &= ~((1<<CLK_BIT) | (1<<MOSI_BIT)); GBA_OUT |= ((data>>31)&1)<<MOSI_BIT; WAIT_TIMER(); GBA_OUT |= (1<<CLK_BIT); data<<=1; data |= (GBA_IN>>MISO_BIT)&1; WAIT_TIMER(); } sei(); *data_ = data; return 0; error: return -1; }
int main(int argc, char* argv[]) { wp_index* index; if(argc < 2) { fprintf(stderr, "Usage: %s <filename>+\n", argv[0]); return -1; } DIE_IF_ERROR(wp_index_create(&index, "index")); //wp_index_dumpinfo(index, stdout); printf("starting...\n"); unsigned long total_bytes = 0; unsigned long chunk_bytes = 0; START_TIMER(total); START_TIMER(chunk); for(int i = 1; i < argc; i++) { FILE* f = fopen(argv[i], "r"); if(f == NULL) { fprintf(stderr, "can't open %s: %s\n", argv[i], strerror(errno)); break; } uint64_t doc_id; wp_entry* entry = wp_entry_new(); DIE_IF_ERROR(wp_entry_add_file(entry, "body", f)); DIE_IF_ERROR(wp_index_add_entry(index, entry, &doc_id)); DIE_IF_ERROR(wp_entry_free(entry)); fclose(f); struct stat fstat; stat(argv[i], &fstat); total_bytes += fstat.st_size; chunk_bytes += fstat.st_size; MARK_TIMER(chunk); if(TIMER_MS(chunk) > 1000) { MARK_TIMER(total); #define STUFF(k, t) k / 1024, t / 1000.0, ((float)(k) / 1024.0) / ((float)(t) / 1000.0) fprintf(stderr, "processed %5luk in %3.1fs = %6.1fk/s. total: %5luk in %5.1fs = %6.1fk/s\n", STUFF(chunk_bytes, TIMER_MS(chunk)), STUFF(total_bytes, TIMER_MS(total))); RESET_TIMER(chunk); chunk_bytes = 0; } } //po = MMAP_OBJ(segment.postings, postings_list); // may have moved //fprintf(stderr, "after: segment has %d docs and %d postings\n", po->num_docs, po->num_postings); MARK_TIMER(total); fprintf(stderr, "In total, processed %luk in %.1fs = %.1fk/s\n", STUFF(total_bytes, TIMER_MS(total))); DIE_IF_ERROR(wp_index_unload(index)); return 0; }
int main(int argc, char* argv[]) { if(argc < 2) { fprintf(stderr, "Usage: %s <filename>+\n", argv[0]); return -1; } fprintf(stderr, "starting...\n"); new_query = 1; unsigned long total_bytes = 0; unsigned long chunk_bytes = 0; START_TIMER(total); START_TIMER(chunk); for(int i = 1; i < argc; i++) { FILE* f = fopen(argv[i], "r"); if(f == NULL) { fprintf(stderr, "can't open %s: %s\n", argv[i], strerror(errno)); break; } parse_file(f); fclose(f); struct stat fstat; stat(argv[i], &fstat); total_bytes += fstat.st_size; chunk_bytes += fstat.st_size; MARK_TIMER(chunk); if(TIMER_MS(chunk) > 1000) { MARK_TIMER(total); #define STUFF(k, t) k / 1024, t / 1000.0, ((float)(k) / 1024.0) / ((float)(t) / 1000.0) fprintf(stderr, "processed %5luk in %3.1fs = %6.1fk/s. total: %5luk in %5.1fs = %6.1fk/s\n", STUFF(chunk_bytes, TIMER_MS(chunk)), STUFF(total_bytes, TIMER_MS(total))); RESET_TIMER(chunk); chunk_bytes = 0; } } MARK_TIMER(total); fprintf(stderr, "In total, processed %luk in %.1fs = %.1fk/s\n", STUFF(total_bytes, TIMER_MS(total))); return 0; }
static int ps2cdvd_reset(struct cdrom_device_info *cdi) { unsigned long flags; save_flags(flags); cli(); ps2sif_lock(ps2cdvd_lock, "cdvd_reset"); RESET_TIMER(); #ifdef CONFIG_PS2_SBIOS_VER_CHECK if (0x0201 <= sbios(SB_GETVER, NULL)) ps2cdvdcall_reset(); #else ps2cdvdcall_reset(); #endif invalidate_discinfo(); ps2cdvd_state = ps2cdvd_enter(STAT_WAIT_DISC); ps2sif_unlock(ps2cdvd_lock); restore_flags(flags); return 0; }
static srcentry_t *create_srcentry(u_int32 source) { srcentry_t *node; srcentry_t *prev; if (search_srclist(source, &prev) == TRUE) return prev; node = calloc(1, sizeof(srcentry_t)); if (!node) { logit(LOG_WARNING, 0, "Memory allocation error for srcentry %s", inet_fmt(source, s1, sizeof(s1))); return NULL; } node->address = source; /* Free the memory if there is error getting the iif and * the next hop (upstream) router. */ if (set_incoming(node, PIM_IIF_SOURCE) == FALSE) { free(node); return NULL; } RESET_TIMER(node->timer); node->mrtlink = NULL; node->cand_rp = NULL; node->next = prev->next; prev->next = node; node->prev = prev; if (node->next) node->next->prev = node; IF_DEBUG(DEBUG_MFC) { logit(LOG_DEBUG, 0, "create source entry, source %s", inet_fmt(source, s1, sizeof(s1))); } return node; }
static void ps2cdvd_cleanup() { DPRINT(DBG_VERBOSE, "cleanup\n"); ps2sif_lock(ps2cdvd_lock, "cdvd_cleanup"); RESET_TIMER(); if (initialized & INIT_LABELBUF) { DPRINT(DBG_VERBOSE, "free labelbuf %p\n", labelbuf); kfree(labelbuf); } if (initialized & INIT_DATABUF) { DPRINT(DBG_VERBOSE, "free databuf %p\n", ps2cdvd_databufx); kfree(ps2cdvd_databufx); } #if 0 if (initialized & INIT_IOPSIDE) ps2cdvd_cleanupiop(); #endif if (initialized & INIT_BLKDEV) { DPRINT(DBG_VERBOSE, "unregister block device\n"); unregister_blkdev(MAJOR_NR, "ps2cdvd"); } if (initialized & INIT_CDROM) { DPRINT(DBG_VERBOSE, "unregister cdrom\n"); unregister_cdrom(&ps2cdvd_info); } blksize_size[MAJOR_NR] = NULL; initialized = 0; ps2sif_unlock(ps2cdvd_lock); }
void init_pim_mrt(void) { /* TODO: delete any existing routing table */ /* Initialize the source list */ /* The first entry has address 'INADDR_ANY' and is not used */ /* The order is the smallest address first. */ srclist = (srcentry_t *)calloc(1, sizeof(srcentry_t)); if (!srclist) logit(LOG_ERR, 0, "Ran out of memory in init_pim_mrt()"); srclist->next = NULL; srclist->prev = NULL; srclist->address = INADDR_ANY_N; srclist->mrtlink = NULL; srclist->incoming = NO_VIF; srclist->upstream = NULL; srclist->metric = 0; srclist->preference = 0; RESET_TIMER(srclist->timer); srclist->cand_rp = NULL; /* Initialize the group list */ /* The first entry has address 'INADDR_ANY' and is not used */ /* The order is the smallest address first. */ grplist = (grpentry_t *)calloc(1, sizeof(grpentry_t)); if (!grplist) logit(LOG_ERR, 0, "Ran out of memory in init_pim_mrt()"); grplist->next = NULL; grplist->prev = NULL; grplist->rpnext = NULL; grplist->rpprev = NULL; grplist->group = INADDR_ANY_N; grplist->rpaddr = INADDR_ANY_N; grplist->mrtlink = NULL; grplist->active_rp_grp = NULL; grplist->grp_route = NULL; }
static mrtentry_t *alloc_mrtentry(srcentry_t *src, grpentry_t *grp) { mrtentry_t *mrt; u_int16 i, *timer; u_int8 vif_numbers; mrt = calloc(1, sizeof(mrtentry_t)); if (!mrt) { logit(LOG_WARNING, 0, "alloc_mrtentry(): out of memory"); return NULL; } /* * grpnext, grpprev, srcnext, srcprev will be setup when we link the * mrtentry to the source and group chains */ mrt->source = src; mrt->group = grp; mrt->incoming = NO_VIF; VIFM_CLRALL(mrt->joined_oifs); VIFM_CLRALL(mrt->leaves); VIFM_CLRALL(mrt->pruned_oifs); VIFM_CLRALL(mrt->asserted_oifs); VIFM_CLRALL(mrt->oifs); mrt->upstream = NULL; mrt->metric = 0; mrt->preference = 0; mrt->pmbr_addr = INADDR_ANY_N; #ifdef RSRR mrt->rsrr_cache = NULL; #endif /* RSRR */ /* XXX: TODO: if we are short in memory, we can reserve as few as possible * space for vif timers (per group and/or routing entry), but then everytime * when a new interfaces is configured, the router will be restarted and * will delete the whole routing table. The "memory is cheap" solution is * to reserve timer space for all potential vifs in advance and then no * need to delete the routing table and disturb the forwarding. */ #ifdef SAVE_MEMORY mrt->vif_timers = (u_int16 *)calloc(1, sizeof(u_int16) * numvifs); mrt->vif_deletion_delay = (u_int16 *)calloc(1, sizeof(u_int16) * numvifs); vif_numbers = numvifs; #else mrt->vif_timers = (u_int16 *)calloc(1, sizeof(u_int16) * total_interfaces); mrt->vif_deletion_delay = (u_int16 *)calloc(1, sizeof(u_int16) * total_interfaces); vif_numbers = total_interfaces; #endif /* SAVE_MEMORY */ if (!mrt->vif_timers || !mrt->vif_deletion_delay) { logit(LOG_WARNING, 0, "alloc_mrtentry(): out of memory"); FREE_MRTENTRY(mrt); return NULL; } /* Reset the timers */ for (i = 0, timer = mrt->vif_timers; i < vif_numbers; i++, timer++) RESET_TIMER(*timer); for (i = 0, timer = mrt->vif_deletion_delay; i < vif_numbers; i++, timer++) RESET_TIMER(*timer); mrt->flags = MRTF_NEW; RESET_TIMER(mrt->timer); RESET_TIMER(mrt->jp_timer); RESET_TIMER(mrt->rs_timer); RESET_TIMER(mrt->assert_timer); RESET_TIMER(mrt->assert_rate_timer); mrt->kernel_cache = NULL; return mrt; }
static int _readData(int fd, unsigned char *buf, int len) { int rd = 0; int total = 0; int toGet = 0; unsigned char header[6]; struct timeval beg, end; long dt; struct itimerval ti, oti; /* set errno to 0 in order to get correct informations */ /* in case of error */ errno = 0; /* read the first 6 bytes */ gettimeofday(&beg, NULL); while ( total < 6 ) { SET_TIMER(ti,oti, d4RdTimeout); rd = read(fd, header+total, 6-total); RESET_TIMER(ti,oti); if ( rd <= 0 ) { gettimeofday(&end, NULL); dt = (end.tv_sec - beg.tv_sec) * 1000; dt += (end.tv_usec - beg.tv_usec) / 1000; if ( dt > d4RdTimeout*3 ) { if ( debugD4 ) fprintf(stderr,"Timeout at _readData(), dt = %ld ms\n", dt); return -1; break; } continue; } else { total += rd; } } if ( debugD4 ) printHexValues("Recv: ",header,total); if ( total == 6 ) { toGet = (header[2] >> 8) + header[3] - 6; if (debugD4) fprintf(stderr, "toGet: %i\n", toGet); if (toGet > len) return -1; total = 0; gettimeofday(&beg, NULL); while ( total < toGet ) { SET_TIMER(ti,oti, d4RdTimeout); rd = read(fd, buf+total, toGet-total); RESET_TIMER(ti,oti); if ( rd <= 0 ) { gettimeofday(&end, NULL); dt = (end.tv_sec - beg.tv_sec) * 1000; dt += (end.tv_usec - beg.tv_usec) / 1000; if ( dt > d4RdTimeout*3 ) { if ( debugD4 ) fprintf(stderr,"Timeout at _readData(), dt = %ld ms\n",dt); return -1; break; } continue; } else { total += rd; } } if ( debugD4 ) printHexValues("Recv: ",buf,total); return total; }
int readAnswer(int fd, unsigned char *buf, int len) { int rd = 0; int total = 0; struct timeval beg, end; struct itimerval ti, oti; long dt; int count = 0; int first_read = 1; /* wait a little bit before reading an answer */ usleep(d4RdTimeout); /* for error handling in case of timeout */ timeoutGot = 0; /* set errno to 0 in order to get correct informations */ /* in case of error */ errno = 0; gettimeofday(&beg, NULL); if (debugD4) fprintf(stderr, "length: %i\n", len); while ( total < len ) { SET_TIMER(ti,oti, d4RdTimeout); rd = read(fd, buf+total, len-total); if (debugD4) { if (first_read) { fprintf(stderr, "read: "); first_read = 0; } if (rd < 0) { fprintf(stderr, "%i %s\n", rd, errno != 0 ?strerror(errno) : ""); first_read = 1; } else fprintf(stderr, "%i ", rd); } RESET_TIMER(ti,oti); if ( rd <= 0 ) { gettimeofday(&end, NULL); dt = (end.tv_sec - beg.tv_sec) * 1000; dt += (end.tv_usec - beg.tv_usec) / 1000; if ( dt > d4RdTimeout * 2 ) { if ( debugD4 ) fprintf(stderr,"Timeout 1 at readAnswer() rcv %d bytes\n",total); timeoutGot = 1; break; } count++; if ( count >= 100 ) { timeoutGot = 1; if ( rd == 0 ) errno = -1; /* tell that there is an abnormal condition */ break; } errno = 0; } else { total += rd; if ( total > 3 ) { /* the bytes idx 2 and 3 contain the length */ /* in case of errors this may differ from */ /* the expected lenght. Setting len to this */ /* value will avoid waiting for timeout */ len = (buf[2] << 8) + buf[3]; len = (len > sizeof(buf))?sizeof(buf) - 1:len; } } usleep(d4RdTimeout); } if ( debugD4 ) { # if PTIME gettimeofday(&end, NULL); # endif fprintf(stderr, "total: %i\n", total); printHexValues("Recv: ",buf,total); # if PTIME dt = (end.tv_sec - beg.tv_sec) * 1000000; dt += end.tv_usec - beg.tv_usec; fprintf(stderr,"Read time %5.3f s\n",(double)dt/1000000); # endif } if ( timeoutGot ) { if ( debugD4 ) fprintf(stderr,"Timeout 2 at readAnswer()\n"); return -1; } return total; }
static int writeCmd(int fd, unsigned char *cmd, int len) { int w; int i = 0; struct itimerval ti, oti; # if PTIME struct timeval beg, end; long dt; # endif if ( debugD4 ) { printCmdType(cmd); # if PTIME gettimeofday(&beg, NULL); # endif if ( cmd[0] == 0 && cmd[1] == 0 ) { printHexValues("Send: ", cmd, len); } else { printHexValues("Send: ", cmd, 6); } } usleep(1); /* according to Glen Steward, this will solve problems */ /* for the cartridge exchange with the Stylus Color 580 */ timeoutGot = 0; errno = 0; while ( i < len ) { SET_TIMER(ti,oti,d4WrTimeout); w = SafeWrite(fd, cmd+i,len-i); RESET_TIMER(ti,oti); if ( w < 0 ) { if ( debugD4 ) { perror("Write error"); } i= -1; break; } else i += w; } if ( debugD4 ) { # if PTIME gettimeofday(&end, NULL); dt = (end.tv_sec - beg.tv_sec) * 1000000; dt += end.tv_usec - beg.tv_usec; fprintf(stderr,"Write time %5.3f s\n",(double)dt/1000000); # endif } if ( timeoutGot ) return -1; return i; }
void stop_vif(mifi_t vifi) { struct uvif *v; struct listaddr *a; register pim_nbr_entry_t *n; register pim_nbr_entry_t *next; struct vif_acl *acl; /* * TODO: make sure that the kernel viftable is * consistent with the daemon table */ v = &uvifs[vifi]; if (!(v->uv_flags & MIFF_REGISTER)) { k_leave(pim6_socket, &allpim6routers_group.sin6_addr, v->uv_ifindex); k_leave(mld6_socket, &allrouters_group.sin6_addr, v->uv_ifindex); /* * Discard all group addresses. (No need to tell kernel; * the k_del_vif() call will clean up kernel state.) */ while (v->uv_groups != NULL) { a = v->uv_groups; v->uv_groups = a->al_next; /* reset all the timers */ if (a->al_query) { timer_clearTimer(a->al_query); } if (a->al_comp) { timer_clearTimer(a->al_comp); } if (a->al_timerid) { timer_clearTimer(a->al_timerid); } /* frees all the related sources */ while (a->sources != NULL) { struct listaddr *curr = a->sources; a->sources = a->sources->al_next; free((char *)curr); } a->sources = NULL; /* discard the group */ free((char *)a); } v->uv_groups = NULL; } /* * TODO: inform (eventually) the neighbors I am going down by sending * PIM_HELLO with holdtime=0 so someone else should become a DR. */ /* TODO: dummy! Implement it!! Any problems if don't use it? */ delete_vif_from_mrt(vifi); /* * Delete the interface from the kernel's vif structure. */ k_del_vif(mld6_socket, vifi); v->uv_flags = (v->uv_flags & ~VIFF_QUERIER & ~VIFF_NONBRS) | VIFF_DOWN; if (!(v->uv_flags & MIFF_REGISTER)) { RESET_TIMER(v->uv_pim_hello_timer); RESET_TIMER(v->uv_jp_timer); RESET_TIMER(v->uv_gq_timer); for (n = v->uv_pim_neighbors; n != NULL; n = next) { /* Free the space for each neighbour */ next = n->next; delete_pim6_nbr(n); } v->uv_pim_neighbors = NULL; } if (v->uv_querier != NULL) { free(v->uv_querier); v->uv_querier = NULL; } /* I/F address list */ { struct phaddr *pa, *pa_next; for (pa = v->uv_addrs; pa; pa = pa_next) { pa_next = pa->pa_next; free(pa); } } v->uv_addrs = NULL; v->uv_linklocal = NULL; /* uv_linklocal must be in uv_addrs */ /* TODO: currently not used */ /* The Access Control List (list with the scoped addresses) */ while (v->uv_acl != NULL) { acl = v->uv_acl; v->uv_acl = acl->acl_next; free((char *)acl); } vifs_down = TRUE; IF_DEBUG(DEBUG_IF) log_msg(LOG_DEBUG, 0, "%s goes down, vif #%u out of service", v->uv_name, vifi); }
static void ps2cdvd_state_machine(struct ps2cdvd_event* ev) { unsigned long flags; int old_state = ps2cdvd_state; int new_state = ps2cdvd_state; struct sbr_common_arg *carg = ev->arg; DPRINT(DBG_STATE, "state: %s event: %s\n", ps2cdvd_getstatestr(old_state), ps2cdvd_geteventstr(ev->type)); save_flags(flags); cli(); switch (ps2cdvd_state) { case STAT_WAIT_DISC: switch (ev->type) { case EV_START: case EV_TIMEOUT: if (ps2cdvd_lowlevel_lock() < 0) { /* waiting for unlock... */ RESET_TIMER(); SET_TIMER(HZ * ps2cdvd_check_interval); } else { new_state = STAT_INIT_TRAYSTAT; } break; case EV_INTR: } break; case STAT_INIT_TRAYSTAT: switch (ev->type) { case EV_START: case EV_TIMEOUT: break; case EV_INTR: { if (carg->result != 0) { new_state = STAT_WAIT_DISC; } else { new_state = STAT_CHECK_DISCTYPE; } } break; } break; case STAT_CHECK_DISCTYPE: switch (ev->type) { case EV_START: case EV_TIMEOUT: break; case EV_INTR: disc_type = carg->result; DPRINT(DBG_INFO, "ps2cdvd_getdisctype()='%s', %d\n", ps2cdvd_getdisctypestr(disc_type), disc_type); switch (disc_type) { case SCECdPS2CDDA: /* PS2 CD DA */ case SCECdPS2CD: /* PS2 CD */ case SCECdPSCDDA: /* PS CD DA */ case SCECdPSCD: /* PS CD */ case SCECdCDDA: /* CD DA */ case SCECdPS2DVD: /* PS2 DVD */ case SCECdDVDV: /* DVD video */ new_state = STAT_INIT_CHECK_READY; break; case SCECdDETCTDVDD: /* DVD-dual detecting */ case SCECdDETCTDVDS: /* DVD-single detecting */ case SCECdDETCTCD: /* CD detecting */ case SCECdDETCT: /* detecting */ case SCECdNODISC: /* no disc */ new_state = disc_locked ? STAT_INVALID_DISC : STAT_WAIT_DISC; break; case SCECdIllgalMedia: /* illegal media */ case SCECdUNKNOWN: /* unknown */ printk(KERN_CRIT "ps2cdvd: illegal media\n"); new_state = disc_locked ? STAT_INVALID_DISC : STAT_WAIT_DISC; break; } break; } break; case STAT_INIT_CHECK_READY: switch (ev->type) { case EV_START: case EV_TIMEOUT: break; case EV_INTR: prev_read = jiffies; if (carg->result == SCECdComplete) { switch (disc_type) { case SCECdPS2CDDA: /* PS2 CD DA */ case SCECdPS2CD: /* PS2 CD */ case SCECdPSCDDA: /* PS CD DA */ case SCECdPSCD: /* PS CD */ case SCECdCDDA: /* CD DA */ new_state = STAT_TOC_READ; media_mode = SCECdCD; break; case SCECdPS2DVD: /* PS2 DVD */ case SCECdDVDV: /* DVD video */ new_state = STAT_SET_MMODE; media_mode = SCECdDVD; break; default: printk(KERN_CRIT "ps2cdvd: internal error at %s(%d)\n", __FILE__, __LINE__); new_state = disc_locked ? STAT_INVALID_DISC : STAT_WAIT_DISC; break; } } else { new_state = STAT_WAIT_DISC; } break; } break; case STAT_TOC_READ: switch (ev->type) { case EV_START: case EV_TIMEOUT: break; case EV_INTR: if (carg->result < 0) { DPRINT(DBG_DIAG, "gettoc() failed\n"); new_state = disc_locked ? STAT_INVALID_DISC : STAT_WAIT_DISC; } else { struct ps2cdvd_tocentry *toc; toc_valid = 1; toc = (struct ps2cdvd_tocentry *)tocbuf; leadout_start = msftolba(decode_bcd(toc[2].abs_msf[0]), decode_bcd(toc[2].abs_msf[1]), decode_bcd(toc[2].abs_msf[2])); #ifdef PS2CDVD_DEBUG if (ps2cdvd_debug & DBG_INFO) { struct sbr_cdvd_gettoc_arg *arg = carg->arg; if (arg->media == 0) { ps2cdvd_tocdump(DBG_LOG_LEVEL "ps2cdvd: ", (struct ps2cdvd_tocentry *)tocbuf); } else { /* * we have no interrest in DVD Physical format information ps2cdvd_hexdump(tocbuf, len); */ } } #endif new_state = STAT_SET_MMODE; } break; } break; case STAT_SET_MMODE: switch (ev->type) { case EV_START: case EV_TIMEOUT: break; case EV_INTR: if (carg->result == 0) { DPRINT(DBG_DIAG, "set_mmode() failed\n"); new_state = disc_locked ? STAT_INVALID_DISC : STAT_WAIT_DISC; } else { switch (disc_type) { case SCECdPS2DVD: /* PS2 DVD */ case SCECdPS2CDDA: /* PS2 CD DA */ case SCECdPS2CD: /* PS2 CD */ case SCECdPSCDDA: /* PS CD DA */ case SCECdPSCD: /* PS CD */ new_state = STAT_LABEL_READ; break; case SCECdDVDV: /* DVD video */ case SCECdCDDA: /* CD DA */ if (disc_locked && disc_lock_key_valid) { new_state = STAT_LABEL_READ; } else { disc_changed++; new_state = STAT_READY; } break; default: printk(KERN_CRIT "ps2cdvd: internal error at %s(%d)\n", __FILE__, __LINE__); new_state = disc_locked ? STAT_INVALID_DISC : STAT_WAIT_DISC; break; } break; } } break; case STAT_LABEL_READ: switch (ev->type) { case EV_START: case EV_TIMEOUT: break; case EV_INTR: new_state = STAT_LABEL_READ_ERROR_CHECK; break; } break; case STAT_LABEL_READ_ERROR_CHECK: switch (ev->type) { case EV_START: case EV_TIMEOUT: break; case EV_INTR: if (carg->result != SCECdErNO) { DPRINT(DBG_DIAG, "error: %s, code=0x%02x\n", ps2cdvd_geterrorstr(carg->result), carg->result); if (disc_locked && disc_lock_key_valid) { printk(KERN_CRIT "ps2cdvd: =============================\n"); printk(KERN_CRIT "ps2cdvd: wrong disc. \n"); printk(KERN_CRIT "ps2cdvd: =============================\n"); if (!ps2cdvd_wrong_disc_retry) { INIT_REQUEST; while (CURRENT) end_request(0); disc_changed++; } } new_state = disc_locked ? STAT_INVALID_DISC : STAT_WAIT_DISC; } else { unsigned long sum; #ifdef PS2CDVD_DEBUG struct iso_primary_descriptor *label; label = (struct iso_primary_descriptor*)labelbuf; if (ps2cdvd_debug & DBG_INFO) { printk(DBG_LOG_LEVEL "ps2cdvd: "); print_isofsstr(label->system_id, sizeof(label->system_id)); print_isofsstr(label->volume_id, sizeof(label->volume_id)); print_isofsstr(label->volume_set_id, sizeof(label->volume_set_id)); print_isofsstr(label->publisher_id, sizeof(label->publisher_id)); print_isofsstr(label->application_id, sizeof(label->application_id)); printk("\n"); /* ps2cdvd_hexdump(DBG_LOG_LEVEL "ps2cdvd: ", labelbuf, 2048); */ } #endif label_valid = 1; DPRINT(DBG_DLOCK, "label is valid\n"); sum = checksum((u_long*)labelbuf, 2048/sizeof(u_long)); if (disc_lock_key_valid && disc_locked && disc_lock_key != sum) { printk(KERN_CRIT "ps2cdvd: =============================\n"); printk(KERN_CRIT "ps2cdvd: wrong disc. \n"); printk(KERN_CRIT "ps2cdvd: =============================\n"); if (!ps2cdvd_wrong_disc_retry) { INIT_REQUEST; while (CURRENT) end_request(0); disc_changed++; } new_state = STAT_INVALID_DISC; } else { disc_lock_key = sum; if (!disc_lock_key_valid && disc_locked) { DPRINT(DBG_DLOCK, "disc lock key=%lX\n", sum); } disc_lock_key_valid = 1; new_state = STAT_READY; } } break; } break; case STAT_READY: switch (ev->type) { case EV_TICK: if (CURRENT == NULL || ps2sif_iswaiting(ps2cdvd_lock)) { break; } /* fall through */ case EV_START: case EV_TIMEOUT: if (ps2cdvd_lowlevel_lock() < 0) { /* waiting for unlock... */ RESET_TIMER(); SET_TIMER(HZ * ps2cdvd_check_interval); break; } if (CURRENT == NULL) { if (ps2cdvd_spindown * HZ < jiffies - prev_read) { new_state = STAT_SPINDOWN; } else { /* nothing to do */ ps2cdvd_lowlevel_unlock(); RESET_TIMER(); SET_TIMER(HZ * ps2cdvd_check_interval); } } else { prev_read = jiffies; if (jiffies - prev_tray_check < HZ/2) { new_state = STAT_READ; } else { prev_tray_check = jiffies; new_state = STAT_CHECK_TRAY; } } break; case EV_INTR: break; } break; case STAT_CHECK_TRAY: switch (ev->type) { case EV_START: case EV_TIMEOUT: break; case EV_INTR: if (carg->result < 0) { new_state = STAT_ERROR; } else { struct sbr_cdvd_trayreq_arg *arg = carg->arg; if (arg->traycount != 0) { if (disc_locked) { printk(KERN_CRIT"ps2cdvd: =============================\n"); printk(KERN_CRIT"ps2cdvd: the disc is currently locked.\n"); printk(KERN_CRIT"ps2cdvd: please don't take it away!\n"); printk(KERN_CRIT"ps2cdvd: =============================\n"); } invalidate_discinfo(); new_state = STAT_CHECK_DISCTYPE; } else { if (CURRENT) { new_state = STAT_READ; } else { new_state = STAT_READY; } } } break; } break; case STAT_READ: switch (ev->type) { case EV_START: case EV_TIMEOUT: break; case EV_INTR: new_state = STAT_READ_ERROR_CHECK; break; } break; case STAT_READ_EOM_RETRY: switch (ev->type) { case EV_START: case EV_TIMEOUT: break; case EV_INTR: new_state = STAT_READ_ERROR_CHECK; break; } break; case STAT_READ_ERROR_CHECK: switch (ev->type) { case EV_START: case EV_TIMEOUT: break; case EV_INTR: if (carg->result == SCECdErNO) { /* * succeeded */ while (CURRENT != NULL && ps2cdvd_databuf_addr <= CURRENT->sector/4 && CURRENT->sector/4 < ps2cdvd_databuf_addr + ps2cdvd_databuf_size) { memcpy(CURRENT->buffer, ps2cdvd_databuf + DATA_SECT_SIZE * (CURRENT->sector/4 - ps2cdvd_databuf_addr), DATA_SECT_SIZE); end_request(1); } if (!ps2sif_iswaiting(ps2cdvd_lock) && CURRENT != NULL) { /* tiny acceleration */ new_state = STAT_READ; } else { new_state = STAT_READY; } } else if (carg->result == 0x38) { /* * sector format error */ DPRINT(DBG_DIAG, "error: sector format error, code=0x38 (ignored)\n"); memset(CURRENT->buffer, 0, DATA_SECT_SIZE); end_request(1); if (!ps2sif_iswaiting(ps2cdvd_lock) && CURRENT != NULL) { /* tiny acceleration */ new_state = STAT_READ; } else { new_state = STAT_READY; } } else if (carg->result == SCECdErEOM && ps2cdvd_databuf_addr != CURRENT->sector/4 - ps2cdvd_databuf_size + 1 && ps2cdvd_databuf_size <= CURRENT->sector/4) { /* you got End Of Media and you have not retried */ DPRINT(DBG_DIAG, "error: %s, code=0x%02x (retry...)\n", ps2cdvd_geterrorstr(carg->result), carg->result); new_state = STAT_READ_EOM_RETRY; } else { DPRINT(DBG_DIAG, "error: %s, code=0x%02x\n", ps2cdvd_geterrorstr(carg->result), carg->result); ps2cdvd_databuf_addr = -1; end_request(0); /* I/O error */ new_state = STAT_READY; } break; } break; case STAT_INVALID_DISC: switch (ev->type) { case EV_START: case EV_TIMEOUT: if (ps2cdvd_lowlevel_lock() < 0) { /* waiting for unlock... */ RESET_TIMER(); SET_TIMER(HZ * ps2cdvd_check_interval); } else { new_state = STAT_CHECK_DISCTYPE; } break; case EV_INTR: break; } break; case STAT_SPINDOWN: switch (ev->type) { case EV_START: case EV_TIMEOUT: break; case EV_INTR: if (CURRENT == NULL) { new_state = STAT_IDLE; } else { DPRINT(DBG_VERBOSE, "re-spinup...\n"); new_state = STAT_CHECK_DISCTYPE; } break; } break; case STAT_IDLE: switch (ev->type) { case EV_START: case EV_TIMEOUT: if (ps2cdvd_lowlevel_lock() < 0) { /* waiting for unlock... */ RESET_TIMER(); SET_TIMER(HZ * ps2cdvd_check_interval); } else { new_state = STAT_CHECK_DISCTYPE; } break; case EV_INTR: break; } break; case STAT_ERROR: break; default: printk(KERN_ERR "ps2cdvd: invalid state"); ps2cdvd_state = STAT_WAIT_DISC; break; } if (new_state != old_state) { struct ps2cdvd_event tick; tick.type = EV_TICK; ps2cdvd_leave(old_state); ps2cdvd_state = ps2cdvd_enter(new_state); DPRINT(DBG_STATE, " -> new state: %s\n", ps2cdvd_getstatestr(ps2cdvd_state)); if (old_state != ps2cdvd_state && ps2cdvd_state == STAT_READY) { ps2cdvd_state_machine(&tick); } wake_up_interruptible(&statq); } restore_flags(flags); } __initfunc(int ps2cdvd_init(void)) { int res; DPRINT(DBG_VERBOSE, "init: get lock\n"); if ((ps2cdvd_lock = ps2sif_getlock(PS2LOCK_CDVD)) == NULL) { printk(KERN_ERR "ps2cdvd: Can't get lock\n"); ps2cdvd_cleanup(); return -EINVAL; } ps2sif_lockqueueinit(&ps2cdvd_lock_qi); ps2cdvd_lock_qi.name = "ps2cdvd"; DPRINT(DBG_VERBOSE, "init: initialize timer\n"); init_timer(&io_timer); io_timer.function = (void(*)(u_long))ps2cdvd_timer; ps2cdvd_state = STAT_WAIT_DISC; DPRINT(DBG_VERBOSE, "init: allocate diaklabel buffer\n"); labelbuf = kmalloc(2048, GFP_KERNEL); if (labelbuf == NULL) { printk(KERN_ERR "ps2cdvd: Can't allocate buffer\n"); ps2cdvd_cleanup(); return -ENOMEM; } initialized |= INIT_LABELBUF; DPRINT(DBG_VERBOSE, "allocate buffer\n"); ps2cdvd_databufx = kmalloc(ps2cdvd_databuf_size * AUDIO_SECT_SIZE + BUFFER_ALIGNMENT, GFP_KERNEL); if (ps2cdvd_databufx == NULL) { printk(KERN_ERR "ps2cdvd: Can't allocate buffer\n"); ps2cdvd_cleanup(); return -ENOMEM; } ps2cdvd_databuf = ALIGN(ps2cdvd_databufx, BUFFER_ALIGNMENT); initialized |= INIT_DATABUF; DPRINT(DBG_VERBOSE, "init: call sbios\n"); if (ps2cdvdcall_init()) { printk(KERN_ERR "ps2cdvd: Can't initialize CD/DVD-ROM subsystem\n"); ps2cdvd_cleanup(); return -EIO; } #ifdef CONFIG_PS2_SBIOS_VER_CHECK if (0x0201 <= sbios(SB_GETVER, NULL)) ps2cdvdcall_reset(); #else ps2cdvdcall_reset(); #endif initialized |= INIT_IOPSIDE; DPRINT(DBG_VERBOSE, "init: register block device\n"); if ((res = register_blkdev(MAJOR_NR, "ps2cdvd", &cdrom_fops)) < 0) { printk(KERN_ERR "ps2cdvd: Unable to get major %d for PS2 CD/DVD-ROM\n", MAJOR_NR); ps2cdvd_cleanup(); return -EIO; } if (MAJOR_NR == 0) MAJOR_NR = res; initialized |= INIT_BLKDEV; blksize_size[MAJOR_NR] = ps2cdvd_blocksizes; hardsect_size[MAJOR_NR] = ps2cdvd_hardsectsizes; blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST; read_ahead[MAJOR_NR] = ps2cdvd_read_ahead; DPRINT(DBG_VERBOSE, "init: register cdrom\n"); ps2cdvd_info.dev = MKDEV(MAJOR_NR, 0); if (register_cdrom(&ps2cdvd_info) != 0) { printk(KERN_ERR "ps2cdvd: Cannot register PS2 CD/DVD-ROM\n"); ps2cdvd_cleanup(); return -EIO; } initialized |= INIT_CDROM; printk(KERN_INFO "PS2 CD/DVD-ROM driver\n"); if (ps2cdvd_lowlevel_lock() == 0) ps2cdvd_state = ps2cdvd_enter(STAT_INIT_TRAYSTAT); else ps2cdvd_state = ps2cdvd_enter(STAT_WAIT_DISC); return 0; }
static int ps2cdvd_enter_leave(int state, int enter) { int res_state = state; switch (state) { case STAT_WAIT_DISC: if (enter) { if (ps2cdvd_state != STAT_CHECK_DISCTYPE) invalidate_discinfo(); ps2cdvd_lowlevel_unlock(); if (CURRENT) DPRINT(DBG_DIAG, "abort all pending request\n"); while (CURRENT) end_request(0); SET_TIMER(HZ * ps2cdvd_check_interval); } else { RESET_TIMER(); } break; case STAT_INIT_TRAYSTAT: if (enter) { if (ps2cdvd_send_trayreq(SCECdTrayCheck) < 0) { DPRINT(DBG_DIAG, "send_trayreq() failed\n"); res_state = ps2cdvd_enter(STAT_ERROR); } } else { } break; case STAT_CHECK_DISCTYPE: if (enter) { disc_type = INVALID_DISCTYPE; if (ps2cdvd_send_gettype() < 0) { DPRINT(DBG_DIAG, "send_gettype() failed\n"); res_state = ps2cdvd_enter(STAT_ERROR); } } else { } break; case STAT_INIT_CHECK_READY: if (enter) { //if (ps2cdvd_send_ready(1 /* non block */) < 0) { if (ps2cdvd_send_ready(0 /* block */) < 0) { DPRINT(DBG_DIAG, "send_ready() failed\n"); res_state = ps2cdvd_enter(STAT_ERROR); } } else { } break; case STAT_TOC_READ: if (enter) { if (ps2cdvd_send_gettoc(tocbuf, sizeof(tocbuf)) < 0) { DPRINT(DBG_DIAG, "send_gettoc() failed\n"); res_state = ps2cdvd_enter(STAT_ERROR); } } else { } break; case STAT_SET_MMODE: if (enter) { DPRINT(DBG_INFO, "media mode %s\n", media_mode == SCECdCD ? "CD" : "DVD"); if (ps2cdvd_send_mmode(media_mode) < 0) { DPRINT(DBG_DIAG, "send_mmode() failed\n"); res_state = ps2cdvd_enter(STAT_ERROR); } } else { } break; case STAT_LABEL_READ: if (enter) { if (ps2cdvd_send_read(16, 1, labelbuf, &DataMode) < 0) { DPRINT(DBG_DIAG, "send_read() failed\n"); res_state = ps2cdvd_enter(STAT_ERROR); } } else { } break; case STAT_LABEL_READ_ERROR_CHECK: if (enter) { if (ps2cdvd_send_geterror() < 0) { DPRINT(DBG_DIAG, "send_geterror() failed\n"); res_state = ps2cdvd_enter(STAT_ERROR); } } else { } break; case STAT_READY: if (enter) { ps2cdvd_lowlevel_unlock(); SET_TIMER(HZ * ps2cdvd_check_interval); } else { RESET_TIMER(); } break; case STAT_CHECK_TRAY: if (enter) { if (ps2cdvd_send_trayreq(2) < 0) { DPRINT(DBG_DIAG, "send_trayreq() failed\n"); res_state = ps2cdvd_enter(STAT_ERROR); } } else { } break; case STAT_READ: if (enter) { DPRINT(DBG_READ, "REQ %p: sec=%ld n=%ld buf=%p\n", CURRENT, CURRENT->sector, CURRENT->current_nr_sectors, CURRENT->buffer); if (ps2cdvd_send_read(CURRENT->sector/4, ps2cdvd_databuf_size, ps2cdvd_databuf, &DataMode) < 0) { DPRINT(DBG_DIAG, "send_readdata() failed\n"); res_state = ps2cdvd_enter(STAT_ERROR); } else { ps2cdvd_databuf_addr = CURRENT->sector/4; } } else { } break; case STAT_READ_EOM_RETRY: if (enter) { DPRINT(DBG_READ, "REQ %p: sec=%ld n=%ld buf=%p (EOM retry)\n", CURRENT, CURRENT->sector, CURRENT->current_nr_sectors, CURRENT->buffer); if (ps2cdvd_send_read(CURRENT->sector/4 - ps2cdvd_databuf_size + 1, ps2cdvd_databuf_size, ps2cdvd_databuf, &DataMode) < 0) { DPRINT(DBG_DIAG, "send_readdata() failed\n"); res_state = ps2cdvd_enter(STAT_ERROR); } else { ps2cdvd_databuf_addr = CURRENT->sector/4 - ps2cdvd_databuf_size + 1; } } else { } break; case STAT_READ_ERROR_CHECK: if (enter) { if (ps2cdvd_send_geterror() < 0) { DPRINT(DBG_DIAG, "send_geterror() failed\n"); res_state = ps2cdvd_enter(STAT_ERROR); } } else { } break; case STAT_INVALID_DISC: if (enter) { if (!disc_locked) { DPRINT(DBG_DIAG, "attempt to enter INVALID_DISC state while !disc_locked\n"); res_state = ps2cdvd_enter(STAT_WAIT_DISC); } else { invalidate_discinfo(); ps2cdvd_lowlevel_unlock(); SET_TIMER(HZ * ps2cdvd_check_interval); } } else { RESET_TIMER(); } break; case STAT_SPINDOWN: if (enter) { if (ps2cdvd_send_stop() < 0) { DPRINT(DBG_DIAG, "send_stop() failed\n"); res_state = ps2cdvd_enter(STAT_ERROR); } } else { } break; case STAT_IDLE: if (enter) { invalidate_discinfo(); ps2cdvd_lowlevel_unlock(); } else { RESET_TIMER(); } break; case STAT_ERROR: if (enter) { invalidate_discinfo(); while (CURRENT) end_request(0); ps2cdvd_lowlevel_unlock(); } else { } break; default: printk(KERN_CRIT "ps2cdvd: INVALID STATE\n"); break; } return res_state; }