static int mcdx_transfer(struct s_drive_stuff *stuffp, char *p, int sector, int nr_sectors) /* This seems to do the actually transfer. But it does more. It keeps track of errors occurred and will (if possible) fall back to single speed on error. Return: -1 on timeout or other error else status byte (as in stuff->st) */ { int ans; ans = mcdx_xfer(stuffp, p, sector, nr_sectors); return ans; #ifdef FALLBACK if (-1 == ans) stuffp->readerrs++; else return ans; if (stuffp->readerrs && stuffp->readcmd == READ1X) { xwarn("XXX Already reading 1x -- no chance\n"); return -1; } xwarn("XXX Fallback to 1x\n"); stuffp->readcmd = READ1X; return mcdx_transfer(stuffp, p, sector, nr_sectors); #endif }
NetSocket* TCPNetworkEngine::connect(const char* uri) { if(strncmp(uri, "yc://", 5) == 0) { const char* host = uri + 5; TCPNetSocket* s = new TCPNetSocket(); s->socket = socket(PF_INET, SOCK_STREAM, 0); xerror(s->socket != SOCKET_ERROR, "Could not create a socket."); struct hostent* hostaddr = gethostbyname(host); xwarn(hostaddr->h_addr_list, "Could not retreive address for host %s", host); if(!hostaddr->h_addr_list) return NULL; struct sockaddr_in saddr; bzero(&saddr, sizeof(saddr)); saddr.sin_family = hostaddr->h_addrtype; saddr.sin_port = htons(port); #ifndef WIN32 inet_pton(hostaddr->h_addrtype, hostaddr->h_addr_list[0], &saddr.sin_addr); #else struct sockaddr_storage ss; int sslen = sizeof(ss); WSAStringToAddressA(hostaddr->h_addr_list[0], hostaddr->h_addrtype, NULL, (struct sockaddr*)&ss, &sslen); saddr.sin_addr = ((struct sockaddr_in *)&ss)->sin_addr; #endif if(::connect(s->socket, (struct sockaddr *)&saddr, sizeof(saddr) ) == SOCKET_ERROR) { xwarn(false, "Could not connect to %s", host); return NULL; } #ifdef WIN32 ULONG on=1; ioctlsocket(s->socket, FIONBIO, &on); #else fcntl(s->socket, F_SETFL, O_NONBLOCK); #endif return s; } else { xwarn(false, "Unknown protocol : %s", uri); return NULL; } }
static void __exit mcdx_exit(void) { int i; xinfo("cleanup_module called\n"); for (i = 0; i < MCDX_NDRIVES; i++) { struct s_drive_stuff *stuffp = mcdx_stuffp[i]; if (!stuffp) continue; del_gendisk(stuffp->disk); if (unregister_cdrom(&stuffp->info)) { printk(KERN_WARNING "Can't unregister cdrom mcdx\n"); continue; } put_disk(stuffp->disk); release_region(stuffp->wreg_data, MCDX_IO_SIZE); free_irq(stuffp->irq, NULL); if (stuffp->toc) { xtrace(MALLOC, "cleanup_module() free toc @ %p\n", stuffp->toc); kfree(stuffp->toc); } xtrace(MALLOC, "cleanup_module() free stuffp @ %p\n", stuffp); mcdx_stuffp[i] = NULL; kfree(stuffp); } if (unregister_blkdev(MAJOR_NR, "mcdx") != 0) { xwarn("cleanup() unregister_blkdev() failed\n"); } blk_cleanup_queue(mcdx_queue); #if !MCDX_QUIET else
void __exit mcdx_exit(void) { int i; xinfo("cleanup_module called\n"); for (i = 0; i < MCDX_NDRIVES; i++) { struct s_drive_stuff *stuffp; if (unregister_cdrom(&mcdx_info)) { printk(KERN_WARNING "Can't unregister cdrom mcdx\n"); return; } stuffp = mcdx_stuffp[i]; if (!stuffp) continue; release_region((unsigned long) stuffp->wreg_data, MCDX_IO_SIZE); free_irq(stuffp->irq, NULL); if (stuffp->toc) { xtrace(MALLOC, "cleanup_module() free toc @ %p\n", stuffp->toc); kfree(stuffp->toc); } xtrace(MALLOC, "cleanup_module() free stuffp @ %p\n", stuffp); mcdx_stuffp[i] = NULL; kfree(stuffp); } if (devfs_unregister_blkdev(MAJOR_NR, "mcdx") != 0) { xwarn("cleanup() unregister_blkdev() failed\n"); } blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR)); #if !MCDX_QUIET else xinfo("cleanup() succeeded\n");
void State::setControlledObject(Controllable* newControlledObject, int controllerID) { xwarn(true, "No GC for Controllable."); if(controlledObjects.size() <= (unsigned int)controllerID) { controlledObjects.resize(controllerID+1, NULL); } controlledObjects[controllerID] = newControlledObject; }
static int mcdx_playmsf(struct s_drive_stuff *stuffp, const struct cdrom_msf *msf) { unsigned char cmd[7] = { 0, 0, 0, 0, 0, 0, 0 }; if (!stuffp->readcmd) { xinfo("Can't play from missing disk.\n"); return -1; } cmd[0] = stuffp->playcmd; cmd[1] = msf->cdmsf_min0; cmd[2] = msf->cdmsf_sec0; cmd[3] = msf->cdmsf_frame0; cmd[4] = msf->cdmsf_min1; cmd[5] = msf->cdmsf_sec1; cmd[6] = msf->cdmsf_frame1; xtrace(PLAYMSF, "ioctl(): play %x " "%02x:%02x:%02x -- %02x:%02x:%02x\n", cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], cmd[5], cmd[6]); outsb(stuffp->wreg_data, cmd, sizeof cmd); if (-1 == mcdx_getval(stuffp, 3 * HZ, 0, NULL)) { xwarn("playmsf() timeout\n"); return -1; } stuffp->audiostatus = CDROM_AUDIO_PLAY; return 0; }
void SubScriptable::freeScript() { xwarn(isFinished(), "Trying to forcefully unload a running script : %s.", scriptSource?scriptSource->name():"Unknown script"); // Protect from dead pointer. Not fully secure, but better than nothing. if(scriptSource) { scriptContext->engine()->scriptMap().freeScript(scriptSource); delete scriptSource; } }
static int __init mcdx_init(void) { int drive; xwarn("Version 2.14(hs) \n"); xwarn("$Id: mcdx.c,v 1.21 1997/01/26 07:12:59 davem Exp $\n"); /* zero the pointer array */ for (drive = 0; drive < MCDX_NDRIVES; drive++) mcdx_stuffp[drive] = NULL; /* do the initialisation */ for (drive = 0; drive < MCDX_NDRIVES; drive++) { switch (mcdx_init_drive(drive)) { case 2: return -EIO; case 1: break; } } return 0; }
static int __init mcdx_init(void) { int drive; xwarn("Version 2.14(hs) \n"); xwarn("$Id: //BBN_Linux/Branch/Branch_for_SDK_Release_MultiChip_20111013/tclinux_phoenix/linux/drivers/cdrom/mcdx.c#1 $\n"); /* zero the pointer array */ for (drive = 0; drive < MCDX_NDRIVES; drive++) mcdx_stuffp[drive] = NULL; /* do the initialisation */ for (drive = 0; drive < MCDX_NDRIVES; drive++) { switch (mcdx_init_drive(drive)) { case 2: return -EIO; case 1: break; } } return 0; }
GameMap* State::loadMap(VFS::File* xmlFile) { ScriptableObject* obj = load(xmlFile); GameMap* m = scriptable_object_cast<GameMap*> (obj); if(m != NULL) { // Object is a map. switchMap(m); } else { // Object is not a map. if(obj != NULL) { // Destroy it. xwarn(obj, "Trying to load a non-map object as a map."); delete obj; } } return m; }
Collidable* State::loadToMap(VFS::File* xmlFile) { ScriptableObject* obj = load(xmlFile); Collidable* c = scriptable_object_cast<Collidable*> (obj); if(c != NULL) { // Object is a Collidable. m_map->addObject(c); m_map->own(c); } else { // Object is not a Collidable. if(obj != NULL) { // Destroy it. xwarn(obj, "Trying to load a non-collidable object into the map."); delete obj; } } return c; }
static void mcdx_intr(int irq, void *dev_id, struct pt_regs* regs) { struct s_drive_stuff *stuffp; unsigned char b; stuffp = mcdx_irq_map[irq]; if (stuffp == NULL ) { xwarn("mcdx: no device for intr %d\n", irq); return; } #ifdef AK2 if ( !stuffp->busy && stuffp->pending ) stuffp->int_err = 1; #endif /* AK2 */ /* get the interrupt status */ b = inb((unsigned int) stuffp->rreg_status); stuffp->introk = ~b & MCDX_RBIT_DTEN; /* NOTE: We only should get interrupts if the data we * requested are ready to transfer. * But the drive seems to generate ``asynchronous'' interrupts * on several error conditions too. (Despite the err int enable * setting during initialisation) */ /* if not ok, read the next byte as the drives status */ if (!stuffp->introk) { xtrace(IRQ, "intr() irq %d hw status 0x%02x\n", irq, b); if (~b & MCDX_RBIT_STEN) { xinfo( "intr() irq %d status 0x%02x\n", irq, inb((unsigned int) stuffp->rreg_data)); } else { xinfo( "intr() irq %d ambiguous hw status\n", irq); } } else { xtrace(IRQ, "irq() irq %d ok, status %02x\n", irq, b); } stuffp->busy = 0; wake_up_interruptible(&stuffp->busyq); }
// QC:G ObjectMold* Factory::createMold(TiXmlElement *xmlData, VFS::File* xmlFile) { Factory::moldmapping::iterator it; if(!xmlData) { return NULL; } const char* id = xmlData->Attribute("id"); const char* src = xmlData->Attribute("src"); if(src) { std::map<const char*, const char*> overrides; TiXmlAttribute* attr = xmlData->FirstAttribute(); while(attr) { if(strcmp(attr->Name(), "id")!=0 && strcmp(attr->Name(), "src")!=0) { overrides[attr->Name()] = attr->Value(); } attr = attr->Next(); } VFS::File* srcFile = VFS::openFile(src, xmlFile); ObjectMold* createdObject = loadMold(srcFile, &overrides); delete srcFile; return createdObject; } // Find the factory for this class and call it. it = moldFactories.find(xmlData->Value()); xassert(it != moldFactories.end(), "Don't know how to make molds of %s", xmlData->Value()); xassert(it->second, "NULL mold factory for class %s", xmlData->Value()); // Call the class-specific factory ObjectMold* createdObject = (this->*(it->second))(xmlData, xmlFile); createdObject->sourceFile = xmlFile->copy(); if(id) { createdObject->setObjectId(id); } xwarn(createdObject, "Warning : could not create an instance of %s", xmlData->Value() ); return createdObject; }
static size_t expand(char *buf, const char *execname, int what, size_t bl) { #ifdef __minix return 0; #else const char *p, *ep; char *bp = buf; size_t len; char name[32]; switch (what) { case 0: /* HWCAP XXX: Not yet */ case 1: /* ISALIST XXX: Not yet */ return 0; case 2: /* ORIGIN */ if (execname == NULL) xerr(1, "execname not specified in AUX vector"); if ((ep = strrchr(p = execname, '/')) == NULL) xerr(1, "bad execname `%s' in AUX vector", execname); break; case 3: /* OSNAME */ case 4: /* OSREL */ case 5: /* PLATFORM */ len = sizeof(name); if (sysctl(mib[what - 3], 2, name, &len, NULL, 0) == -1) { xwarn("sysctl"); return 0; } ep = (p = name) + len - 1; break; default: return 0; } while (p != ep && bl) *bp++ = *p++, bl--; return bp - buf; #endif }
UFB_Image *UFB_CreateImageFromFile(const char *filename) { UFB_ImageType type = UFB_GuessImageTypeFromExt(filename); switch(type) { case UFB_IT_TGA: return UFB_CreateImageFromFileTGA(filename); case UFB_IT_PNG: return UFB_CreateImageFromFilePNG(filename); case UFB_IT_JPEG: return UFB_CreateImageFromFileJPEG(filename); default: xwarn("Could not guess image type from filename '%s'", filename); return NULL; } }
// QC:G size_t VorbisPCMSource::read(void* outputBuffer, size_t outputBufferLen) { // TODO : implement loop char* buf = (char*) outputBuffer; size_t totalBytes = 0; while(outputBufferLen && !eofReached) { long bytes = ov_read(&of, buf, outputBufferLen, 0, 2, 1, §ion); if(bytes == OV_HOLE || bytes == OV_EBADLINK || bytes == OV_EINVAL) { xwarn(false, "Problem while reading %s.", f->name()); return 0; } else if(bytes == 0) { eofReached = true; return 0; } totalBytes += bytes; outputBufferLen -= bytes; buf += bytes; } return totalBytes; }
UFB_Image *UFB_CreateImageFromFileTGA(const char *filename) { TGA_Image tgaimg = TGA_LoadFromFile(filename); xassert(tgaimg.error == 0, "Error loading tga image '%s'", filename); if(tgaimg.yorigin == 0) xwarn("Tga image will be flipped, save with origin at upper-left corner!"); UFB_Image *img; if(tgaimg.bpp == 32) { img = UFB_ConvertRGBA32PixelsToImage(tgaimg.data, tgaimg.width, tgaimg.height); } else if(tgaimg.bpp == 24) { img = UFB_ConvertRGB24PixelsToImage(tgaimg.data, tgaimg.width, tgaimg.height); } free(tgaimg.data); return img; }
static int mcdx_xfer(struct s_drive_stuff *stuffp, char *p, int sector, int nr_sectors) /* This does actually the transfer from the drive. Return: -1 on timeout or other error else status byte (as in stuff->st) */ { int border; int done = 0; long timeout; if (stuffp->audio) { xwarn("Attempt to read from audio CD.\n"); return -1; } if (!stuffp->readcmd) { xinfo("Can't transfer from missing disk.\n"); return -1; } while (stuffp->lock) { interruptible_sleep_on(&stuffp->lockq); } if (stuffp->valid && (sector >= stuffp->pending) && (sector < stuffp->low_border)) { /* All (or at least a part of the sectors requested) seems * to be already requested, so we don't need to bother the * drive with new requests ... * Wait for the drive become idle, but first * check for possible occurred errors --- the drive * seems to report them asynchronously */ border = stuffp->high_border < (border = sector + nr_sectors) ? stuffp->high_border : border; stuffp->lock = current->pid; do { while (stuffp->busy) { timeout = interruptible_sleep_on_timeout (&stuffp->busyq, 5 * HZ); if (!stuffp->introk) { xtrace(XFER, "error via interrupt\n"); } else if (!timeout) { xtrace(XFER, "timeout\n"); } else if (signal_pending(current)) { xtrace(XFER, "signal\n"); } else continue; stuffp->lock = 0; stuffp->busy = 0; stuffp->valid = 0; wake_up_interruptible(&stuffp->lockq); xtrace(XFER, "transfer() done (-1)\n"); return -1; } /* check if we need to set the busy flag (as we * expect an interrupt */ stuffp->busy = (3 == (stuffp->pending & 3)); /* Test if it's the first sector of a block, * there we have to skip some bytes as we read raw data */ if (stuffp->xa && (0 == (stuffp->pending & 3))) { const int HEAD = CD_FRAMESIZE_RAW - CD_XA_TAIL - CD_FRAMESIZE; insb(stuffp->rreg_data, p, HEAD); } /* now actually read the data */ insb(stuffp->rreg_data, p, 512); /* test if it's the last sector of a block, * if so, we have to handle XA special */ if ((3 == (stuffp->pending & 3)) && stuffp->xa) { char dummy[CD_XA_TAIL]; insb(stuffp->rreg_data, &dummy[0], CD_XA_TAIL); } if (stuffp->pending == sector) { p += 512; done++; sector++; } } while (++(stuffp->pending) < border); stuffp->lock = 0; wake_up_interruptible(&stuffp->lockq); } else { /* The requested sector(s) is/are out of the * already requested range, so we have to bother the drive * with a new request. */ static unsigned char cmd[] = { 0, 0, 0, 0, 0, 0, 0 }; cmd[0] = stuffp->readcmd; /* The numbers held in ->pending, ..., should be valid */ stuffp->valid = 1; stuffp->pending = sector & ~3; /* do some sanity checks */ if (stuffp->pending > stuffp->lastsector) { xwarn ("transfer() sector %d from nirvana requested.\n", stuffp->pending); stuffp->status = MCDX_ST_EOM; stuffp->valid = 0; xtrace(XFER, "transfer() done (-1)\n"); return -1; } if ((stuffp->low_border = stuffp->pending + DIRECT_SIZE) > stuffp->lastsector + 1) { xtrace(XFER, "cut low_border\n"); stuffp->low_border = stuffp->lastsector + 1; } if ((stuffp->high_border = stuffp->pending + REQUEST_SIZE) > stuffp->lastsector + 1) { xtrace(XFER, "cut high_border\n"); stuffp->high_border = stuffp->lastsector + 1; } { /* Convert the sector to be requested to MSF format */ struct cdrom_msf0 pending; log2msf(stuffp->pending / 4, &pending); cmd[1] = pending.minute; cmd[2] = pending.second; cmd[3] = pending.frame; } cmd[6] = (unsigned char) ((stuffp->high_border - stuffp->pending) / 4); xtrace(XFER, "[%2d]\n", cmd[6]); stuffp->busy = 1; /* Now really issue the request command */ outsb(stuffp->wreg_data, cmd, sizeof cmd); } #ifdef AK2 if (stuffp->int_err) { stuffp->valid = 0; stuffp->int_err = 0; return -1; } #endif /* AK2 */ stuffp->low_border = (stuffp->low_border += done) < stuffp->high_border ? stuffp->low_border : stuffp->high_border; return done; }
int main(int argc, char *argv[]) { int o; unsigned short old_rows; struct slab_info *slab_list = NULL; int run_once = 0, retval = EXIT_SUCCESS; static const struct option longopts[] = { { "delay", required_argument, NULL, 'd' }, { "sort", required_argument, NULL, 's' }, { "once", no_argument, NULL, 'o' }, { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'V' }, { NULL, 0, NULL, 0 } }; #ifdef HAVE_PROGRAM_INVOCATION_NAME program_invocation_name = program_invocation_short_name; #endif setlocale (LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); atexit(close_stdout); sort_func = DEF_SORT_FUNC; while ((o = getopt_long(argc, argv, "d:s:ohV", longopts, NULL)) != -1) { switch (o) { case 'd': errno = 0; delay = strtol_or_err(optarg, _("illegal delay")); if (delay < 1) xerrx(EXIT_FAILURE, _("delay must be positive integer")); break; case 's': sort_func = (int (*)(const struct slab_info*, const struct slab_info *)) set_sort_func(optarg[0]); break; case 'o': run_once=1; delay = 0; break; case 'V': printf(PROCPS_NG_VERSION); return EXIT_SUCCESS; case 'h': usage(stdout); default: usage(stderr); } } if (tcgetattr(STDIN_FILENO, &saved_tty) == -1) xwarn(_("terminal setting retrieval")); old_rows = rows; term_size(0); if (!run_once) { initscr(); resizeterm(rows, cols); signal(SIGWINCH, term_size); } signal(SIGINT, sigint_handler); do { struct slab_info *curr; struct slab_stat stats; struct timeval tv; fd_set readfds; char c; int i; memset(&stats, 0, sizeof(struct slab_stat)); if (get_slabinfo(&slab_list, &stats)) { retval = EXIT_FAILURE; break; } if (!run_once && old_rows != rows) { resizeterm(rows, cols); old_rows = rows; } move(0, 0); print_line(" %-35s: %d / %d (%.1f%%)\n" " %-35s: %d / %d (%.1f%%)\n" " %-35s: %d / %d (%.1f%%)\n" " %-35s: %.2fK / %.2fK (%.1f%%)\n" " %-35s: %.2fK / %.2fK / %.2fK\n\n", /* Translation Hint: Next five strings must not * exceed 35 length in characters. */ /* xgettext:no-c-format */ _("Active / Total Objects (% used)"), stats.nr_active_objs, stats.nr_objs, 100.0 * stats.nr_active_objs / stats.nr_objs, /* xgettext:no-c-format */ _("Active / Total Slabs (% used)"), stats.nr_active_slabs, stats.nr_slabs, 100.0 * stats.nr_active_slabs / stats.nr_slabs, /* xgettext:no-c-format */ _("Active / Total Caches (% used)"), stats.nr_active_caches, stats.nr_caches, 100.0 * stats.nr_active_caches / stats.nr_caches, /* xgettext:no-c-format */ _("Active / Total Size (% used)"), stats.active_size / 1024.0, stats.total_size / 1024.0, 100.0 * stats.active_size / stats.total_size, _("Minimum / Average / Maximum Object"), stats.min_obj_size / 1024.0, stats.avg_obj_size / 1024.0, stats.max_obj_size / 1024.0); slab_list = slabsort(slab_list); attron(A_REVERSE); /* Translation Hint: Please keep alignment of the * following intact. */ print_line("%-78s\n", _(" OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME")); attroff(A_REVERSE); curr = slab_list; for (i = 0; i < rows - 8 && curr->next; i++) { print_line("%6u %6u %3u%% %7.2fK %6u %8u %9uK %-23s\n", curr->nr_objs, curr->nr_active_objs, curr->use, curr->obj_size / 1024.0, curr->nr_slabs, curr->objs_per_slab, (unsigned)(curr->cache_size / 1024), curr->name); curr = curr->next; } put_slabinfo(slab_list); if (!run_once) { refresh(); FD_ZERO(&readfds); FD_SET(STDIN_FILENO, &readfds); tv.tv_sec = delay; tv.tv_usec = 0; if (select(STDOUT_FILENO, &readfds, NULL, NULL, &tv) > 0) { if (read(STDIN_FILENO, &c, 1) != 1) break; parse_input(c); } } } while (delay); tcsetattr(STDIN_FILENO, TCSAFLUSH, &saved_tty); free_slabinfo(slab_list); if (!run_once) endwin(); return retval; }
ScriptMap::~ScriptMap() { for(std::map<VFS::File*, ScriptMap::Script, strCmp>::iterator si = scripts.begin(); si != scripts.end(); si++) { syslog(" Script : %s", si->first->name()); } xwarn(scripts.size() == 0, "Script map not empty : script allocation has memory leaks."); }
// QC:A ScriptableObject* Factory::createInstance(TiXmlElement *xmlData, VFS::File* xmlFile, ownedset* owned) { Factory::mapping::iterator it; if(!xmlData) { return NULL; } const char* id = xmlData->Attribute("id"); if(id) { ScriptableObject* obj = state->script()->getobj(id); if(obj) { syslog("reusing id=%s", id); return obj; } } const char* src = xmlData->Attribute("src"); if(src) { std::map<const char*, const char*> overrides; TiXmlAttribute* attr = xmlData->FirstAttribute(); while(attr) { if(strcmp(attr->Name(), "id")!=0 && strcmp(attr->Name(), "src")!=0) { overrides[attr->Name()] = attr->Value(); } attr = attr->Next(); } VFS::File* srcFile = VFS::openFile(src, xmlFile); ScriptableObject* createdObject = load(srcFile, &overrides, owned); delete srcFile; if(id) { state->script()->setval(id, createdObject); } return createdObject; } // Find the factory for this class and call it. it = factories.find(xmlData->Value()); xassert(it != factories.end(), "Don't know how to make instances of %s", xmlData->Value()); xassert(it->second, "NULL factory for class %s", xmlData->Value()); // Call the class-specific factory ScriptableObject* createdObject = (this->*(it->second))(xmlData, xmlFile, owned); createdObject->sourceFile = xmlFile->copy(); if(id) { state->script()->setval(id, createdObject); } xwarn(createdObject, "Warning : could not create an instance of %s", xmlData->Value() ); #ifdef KEEP_AOD_SOURCES createdObject->aodSource = xmlData->Clone()->ToElement(); char ptrValue[64]; sprintf(ptrValue, "%p", createdObject); createdObject->aodSource->SetAttribute("_ptr", ptrValue); #endif return createdObject; }
static int __init mcdx_init_drive(int drive) { struct s_version version; struct gendisk *disk; struct s_drive_stuff *stuffp; int size = sizeof(*stuffp); char msg[80]; xtrace(INIT, "init() try drive %d\n", drive); xtrace(INIT, "kmalloc space for stuffpt's\n"); xtrace(MALLOC, "init() malloc %d bytes\n", size); if (!(stuffp = kzalloc(size, GFP_KERNEL))) { xwarn("init() malloc failed\n"); return 1; } disk = alloc_disk(1); if (!disk) { xwarn("init() malloc failed\n"); kfree(stuffp); return 1; } xtrace(INIT, "init() got %d bytes for drive stuff @ %p\n", sizeof(*stuffp), stuffp); /* set default values */ stuffp->present = 0; /* this should be 0 already */ stuffp->toc = NULL; /* this should be NULL already */ /* setup our irq and i/o addresses */ stuffp->irq = irq(mcdx_drive_map[drive]); stuffp->wreg_data = stuffp->rreg_data = port(mcdx_drive_map[drive]); stuffp->wreg_reset = stuffp->rreg_status = stuffp->wreg_data + 1; stuffp->wreg_hcon = stuffp->wreg_reset + 1; stuffp->wreg_chn = stuffp->wreg_hcon + 1; init_waitqueue_head(&stuffp->busyq); init_waitqueue_head(&stuffp->lockq); init_waitqueue_head(&stuffp->sleepq); /* check if i/o addresses are available */ if (!request_region(stuffp->wreg_data, MCDX_IO_SIZE, "mcdx")) { xwarn("0x%03x,%d: Init failed. " "I/O ports (0x%03x..0x%03x) already in use.\n", stuffp->wreg_data, stuffp->irq, stuffp->wreg_data, stuffp->wreg_data + MCDX_IO_SIZE - 1); xtrace(MALLOC, "init() free stuffp @ %p\n", stuffp); kfree(stuffp); put_disk(disk); xtrace(INIT, "init() continue at next drive\n"); return 0; /* next drive */ } xtrace(INIT, "init() i/o port is available at 0x%03x\n" stuffp->wreg_data); xtrace(INIT, "init() hardware reset\n"); mcdx_reset(stuffp, HARD, 1); xtrace(INIT, "init() get version\n"); if (-1 == mcdx_requestversion(stuffp, &version, 4)) { /* failed, next drive */ release_region(stuffp->wreg_data, MCDX_IO_SIZE); xwarn("%s=0x%03x,%d: Init failed. Can't get version.\n", MCDX, stuffp->wreg_data, stuffp->irq); xtrace(MALLOC, "init() free stuffp @ %p\n", stuffp); kfree(stuffp); put_disk(disk); xtrace(INIT, "init() continue at next drive\n"); return 0; } switch (version.code) { case 'D': stuffp->readcmd = READ2X; stuffp->present = DOUBLE | DOOR | MULTI; break; case 'F': stuffp->readcmd = READ1X; stuffp->present = SINGLE | DOOR | MULTI; break; case 'M': stuffp->readcmd = READ1X; stuffp->present = SINGLE; break; default: stuffp->present = 0; break; } stuffp->playcmd = READ1X; if (!stuffp->present) { release_region(stuffp->wreg_data, MCDX_IO_SIZE); xwarn("%s=0x%03x,%d: Init failed. No Mitsumi CD-ROM?.\n", MCDX, stuffp->wreg_data, stuffp->irq); kfree(stuffp); put_disk(disk); return 0; /* next drive */ } xtrace(INIT, "init() register blkdev\n"); if (register_blkdev(MAJOR_NR, "mcdx")) { release_region(stuffp->wreg_data, MCDX_IO_SIZE); kfree(stuffp); put_disk(disk); return 1; } mcdx_queue = blk_init_queue(do_mcdx_request, &mcdx_lock); if (!mcdx_queue) { unregister_blkdev(MAJOR_NR, "mcdx"); release_region(stuffp->wreg_data, MCDX_IO_SIZE); kfree(stuffp); put_disk(disk); return 1; } xtrace(INIT, "init() subscribe irq and i/o\n"); if (request_irq(stuffp->irq, mcdx_intr, IRQF_DISABLED, "mcdx", stuffp)) { release_region(stuffp->wreg_data, MCDX_IO_SIZE); xwarn("%s=0x%03x,%d: Init failed. Can't get irq (%d).\n", MCDX, stuffp->wreg_data, stuffp->irq, stuffp->irq); stuffp->irq = 0; blk_cleanup_queue(mcdx_queue); kfree(stuffp); put_disk(disk); return 0; } xtrace(INIT, "init() get garbage\n"); { int i; mcdx_delay(stuffp, HZ / 2); for (i = 100; i; i--) (void) inb(stuffp->rreg_status); } #ifdef WE_KNOW_WHY /* irq 11 -> channel register */ outb(0x50, stuffp->wreg_chn); #endif xtrace(INIT, "init() set non dma but irq mode\n"); mcdx_config(stuffp, 1); stuffp->info.ops = &mcdx_dops; stuffp->info.speed = 2; stuffp->info.capacity = 1; stuffp->info.handle = stuffp; sprintf(stuffp->info.name, "mcdx%d", drive); disk->major = MAJOR_NR; disk->first_minor = drive; strcpy(disk->disk_name, stuffp->info.name); disk->fops = &mcdx_bdops; disk->flags = GENHD_FL_CD; stuffp->disk = disk; sprintf(msg, " mcdx: Mitsumi CD-ROM installed at 0x%03x, irq %d." " (Firmware version %c %x)\n", stuffp->wreg_data, stuffp->irq, version.code, version.ver); mcdx_stuffp[drive] = stuffp; xtrace(INIT, "init() mcdx_stuffp[%d] = %p\n", drive, stuffp); if (register_cdrom(&stuffp->info) != 0) { printk("Cannot register Mitsumi CD-ROM!\n"); free_irq(stuffp->irq, NULL); release_region(stuffp->wreg_data, MCDX_IO_SIZE); kfree(stuffp); put_disk(disk); if (unregister_blkdev(MAJOR_NR, "mcdx") != 0) xwarn("cleanup() unregister_blkdev() failed\n"); blk_cleanup_queue(mcdx_queue); return 2; } disk->private_data = stuffp; disk->queue = mcdx_queue; add_disk(disk); printk(msg); return 0; }
static int mcdx_open(struct cdrom_device_info *cdi, int purpose) { struct s_drive_stuff *stuffp; xtrace(OPENCLOSE, "open()\n"); stuffp = cdi->handle; if (!stuffp->present) return -ENXIO; /* Make the modules looking used ... (thanx bjorn). * But we shouldn't forget to decrement the module counter * on error return */ /* this is only done to test if the drive talks with us */ if (-1 == mcdx_getstatus(stuffp, 1)) return -EIO; if (stuffp->xxx) { xtrace(OPENCLOSE, "open() media changed\n"); stuffp->audiostatus = CDROM_AUDIO_INVALID; stuffp->readcmd = 0; xtrace(OPENCLOSE, "open() Request multisession info\n"); if (-1 == mcdx_requestmultidiskinfo(stuffp, &stuffp->multi, 6)) xinfo("No multidiskinfo\n"); } else { /* multisession ? */ if (!stuffp->multi.multi) stuffp->multi.msf_last.second = 2; xtrace(OPENCLOSE, "open() MS: %d, last @ %02x:%02x.%02x\n", stuffp->multi.multi, stuffp->multi.msf_last.minute, stuffp->multi.msf_last.second, stuffp->multi.msf_last.frame); {; } /* got multisession information */ /* request the disks table of contents (aka diskinfo) */ if (-1 == mcdx_requesttocdata(stuffp, &stuffp->di, 1)) { stuffp->lastsector = -1; } else { stuffp->lastsector = (CD_FRAMESIZE / 512) * msf2log(&stuffp->di.msf_leadout) - 1; xtrace(OPENCLOSE, "open() start %d (%02x:%02x.%02x) %d\n", stuffp->di.n_first, stuffp->di.msf_first.minute, stuffp->di.msf_first.second, stuffp->di.msf_first.frame, msf2log(&stuffp->di.msf_first)); xtrace(OPENCLOSE, "open() last %d (%02x:%02x.%02x) %d\n", stuffp->di.n_last, stuffp->di.msf_leadout.minute, stuffp->di.msf_leadout.second, stuffp->di.msf_leadout.frame, msf2log(&stuffp->di.msf_leadout)); } if (stuffp->toc) { xtrace(MALLOC, "open() free old toc @ %p\n", stuffp->toc); kfree(stuffp->toc); stuffp->toc = NULL; } xtrace(OPENCLOSE, "open() init irq generation\n"); if (-1 == mcdx_config(stuffp, 1)) return -EIO; #ifdef FALLBACK /* Set the read speed */ xwarn("AAA %x AAA\n", stuffp->readcmd); if (stuffp->readerrs) stuffp->readcmd = READ1X; else stuffp->readcmd = stuffp->present | SINGLE ? READ1X : READ2X; xwarn("XXX %x XXX\n", stuffp->readcmd); #else stuffp->readcmd = stuffp->present | SINGLE ? READ1X : READ2X; #endif /* try to get the first sector, iff any ... */ if (stuffp->lastsector >= 0) { char buf[512]; int ans; int tries; stuffp->xa = 0; stuffp->audio = 0; for (tries = 6; tries; tries--) { stuffp->introk = 1; xtrace(OPENCLOSE, "open() try as %s\n", stuffp->xa ? "XA" : "normal"); /* set data mode */ if (-1 == (ans = mcdx_setdatamode(stuffp, stuffp-> xa ? MODE2 : MODE1, 1))) { /* return -EIO; */ stuffp->xa = 0; break; } if ((stuffp->audio = e_audio(ans))) break; while (0 == (ans = mcdx_transfer(stuffp, buf, 0, 1))); if (ans == 1) break; stuffp->xa = !stuffp->xa; } } /* xa disks will be read in raw mode, others not */ if (-1 == mcdx_setdrivemode(stuffp, stuffp->xa ? RAW : COOKED, 1)) return -EIO; if (stuffp->audio) { xinfo("open() audio disk found\n"); } else if (stuffp->lastsector >= 0) { xinfo("open() %s%s disk found\n", stuffp->xa ? "XA / " : "", stuffp->multi. multi ? "Multi Session" : "Single Session"); } } stuffp->xxx = 0; stuffp->users++; return 0; }
static void do_mcdx_request(request_queue_t * q) { struct s_drive_stuff *stuffp; struct request *req; again: req = elv_next_request(q); if (!req) return; stuffp = req->rq_disk->private_data; if (!stuffp->present) { xwarn("do_request(): bad device: %s\n",req->rq_disk->disk_name); xtrace(REQUEST, "end_request(0): bad device\n"); end_request(req, 0); return; } if (stuffp->audio) { xwarn("do_request() attempt to read from audio cd\n"); xtrace(REQUEST, "end_request(0): read from audio\n"); end_request(req, 0); return; } xtrace(REQUEST, "do_request() (%lu + %lu)\n", req->sector, req->nr_sectors); if (req->cmd != READ) { xwarn("do_request(): non-read command to cd!!\n"); xtrace(REQUEST, "end_request(0): write\n"); end_request(req, 0); return; } else { stuffp->status = 0; while (req->nr_sectors) { int i; i = mcdx_transfer(stuffp, req->buffer, req->sector, req->nr_sectors); if (i == -1) { end_request(req, 0); goto again; } req->sector += i; req->nr_sectors -= i; req->buffer += (i * 512); } end_request(req, 1); goto again; xtrace(REQUEST, "end_request(1)\n"); end_request(req, 1); } goto again; }
int mcdx_readtoc(struct s_drive_stuff *stuffp) /* Read the toc entries from the CD, * Return: -1 on failure, else 0 */ { if (stuffp->toc) { xtrace(READTOC, "ioctl() toc already read\n"); return 0; } xtrace(READTOC, "ioctl() readtoc for %d tracks\n", stuffp->di.n_last - stuffp->di.n_first + 1); if (-1 == mcdx_hold(stuffp, 1)) return -1; xtrace(READTOC, "ioctl() tocmode\n"); if (-1 == mcdx_setdrivemode(stuffp, TOC, 1)) return -EIO; /* all seems to be ok so far ... malloc */ { int size; size = sizeof(struct s_subqcode) * (stuffp->di.n_last - stuffp->di.n_first + 2); xtrace(MALLOC, "ioctl() malloc %d bytes\n", size); stuffp->toc = kmalloc(size, GFP_KERNEL); if (!stuffp->toc) { xwarn("Cannot malloc %d bytes for toc\n", size); mcdx_setdrivemode(stuffp, DATA, 1); return -EIO; } } /* now read actually the index */ { int trk; int retries; for (trk = 0; trk < (stuffp->di.n_last - stuffp->di.n_first + 1); trk++) stuffp->toc[trk].index = 0; for (retries = 300; retries; retries--) { /* why 300? */ struct s_subqcode q; unsigned int idx; if (-1 == mcdx_requestsubqcode(stuffp, &q, 1)) { mcdx_setdrivemode(stuffp, DATA, 1); return -EIO; } idx = bcd2uint(q.index); if ((idx > 0) && (idx <= stuffp->di.n_last) && (q.tno == 0) && (stuffp->toc[idx - stuffp->di.n_first]. index == 0)) { stuffp->toc[idx - stuffp->di.n_first] = q; xtrace(READTOC, "ioctl() toc idx %d (trk %d)\n", idx, trk); trk--; } if (trk == 0) break; } memset(&stuffp-> toc[stuffp->di.n_last - stuffp->di.n_first + 1], 0, sizeof(stuffp->toc[0])); stuffp->toc[stuffp->di.n_last - stuffp->di.n_first + 1].dt = stuffp->di.msf_leadout; } /* unset toc mode */ xtrace(READTOC, "ioctl() undo toc mode\n"); if (-1 == mcdx_setdrivemode(stuffp, DATA, 2)) return -EIO; #if MCDX_DEBUG && READTOC { int trk; for (trk = 0; trk < (stuffp->di.n_last - stuffp->di.n_first + 2); trk++) xtrace(READTOC, "ioctl() %d readtoc %02x %02x %02x" " %02x:%02x.%02x %02x:%02x.%02x\n", trk + stuffp->di.n_first, stuffp->toc[trk].control, stuffp->toc[trk].tno, stuffp->toc[trk].index, stuffp->toc[trk].tt.minute, stuffp->toc[trk].tt.second, stuffp->toc[trk].tt.frame, stuffp->toc[trk].dt.minute, stuffp->toc[trk].dt.second, stuffp->toc[trk].dt.frame); } #endif return 0; }
static int mcdx_talk(struct s_drive_stuff *stuffp, const unsigned char *cmd, size_t cmdlen, void *buffer, size_t size, unsigned int timeout, int tries) /* Send a command to the drive, wait for the result. * returns -1 on timeout, drive status otherwise * If buffer is not zero, the result (length size) is stored there. * If buffer is zero the size should be the number of bytes to read * from the drive. These bytes are discarded. */ { int st; char c; int discard; /* Somebody wants the data read? */ if ((discard = (buffer == NULL))) buffer = &c; while (stuffp->lock) { xtrace(SLEEP, "*** talk: lockq\n"); interruptible_sleep_on(&stuffp->lockq); xtrace(SLEEP, "talk: awoken\n"); } stuffp->lock = 1; /* An operation other then reading data destroys the * data already requested and remembered in stuffp->request, ... */ stuffp->valid = 0; #if MCDX_DEBUG & TALK { unsigned char i; xtrace(TALK, "talk() %d / %d tries, res.size %d, command 0x%02x", tries, timeout, size, (unsigned char) cmd[0]); for (i = 1; i < cmdlen; i++) xtrace(TALK, " 0x%02x", cmd[i]); xtrace(TALK, "\n"); } #endif /* give up if all tries are done (bad) or if the status * st != -1 (good) */ for (st = -1; st == -1 && tries; tries--) { char *bp = (char *) buffer; size_t sz = size; outsb(stuffp->wreg_data, cmd, cmdlen); xtrace(TALK, "talk() command sent\n"); /* get the status byte */ if (-1 == mcdx_getval(stuffp, timeout, 0, bp)) { xinfo("talk() %02x timed out (status), %d tr%s left\n", cmd[0], tries - 1, tries == 2 ? "y" : "ies"); continue; } st = *bp; sz--; if (!discard) bp++; xtrace(TALK, "talk() got status 0x%02x\n", st); /* command error? */ if (e_cmderr(st)) { xwarn("command error cmd = %02x %s \n", cmd[0], cmdlen > 1 ? "..." : ""); st = -1; continue; } /* audio status? */ if (stuffp->audiostatus == CDROM_AUDIO_INVALID) stuffp->audiostatus = e_audiobusy(st) ? CDROM_AUDIO_PLAY : CDROM_AUDIO_NO_STATUS; else if (stuffp->audiostatus == CDROM_AUDIO_PLAY && e_audiobusy(st) == 0) stuffp->audiostatus = CDROM_AUDIO_COMPLETED; /* media change? */ if (e_changed(st)) { xinfo("talk() media changed\n"); stuffp->xxx = stuffp->yyy = 1; } /* now actually get the data */ while (sz--) { if (-1 == mcdx_getval(stuffp, timeout, 0, bp)) { xinfo("talk() %02x timed out (data), %d tr%s left\n", cmd[0], tries - 1, tries == 2 ? "y" : "ies"); st = -1; break; } if (!discard) bp++; xtrace(TALK, "talk() got 0x%02x\n", *(bp - 1)); } } #if !MCDX_QUIET if (!tries && st == -1) xinfo("talk() giving up\n"); #endif stuffp->lock = 0; wake_up_interruptible(&stuffp->lockq); xtrace(TALK, "talk() done with 0x%02x\n", st); return st; }
void _rtld_process_hints(const char *execname, Search_Path **path_p, Library_Xform **lib_p, const char *fname) { int fd; char *buf, small[128]; const char *b, *ep, *ptr; struct stat st; ssize_t sz; Search_Path **head_p = path_p; if ((fd = open(fname, O_RDONLY)) == -1) { /* Don't complain */ return; } /* Try to avoid mmap/stat on the file. */ buf = small; buf[0] = '\0'; sz = read(fd, buf, sizeof(small)); if (sz == -1) { xwarn("read: %s", fname); (void)close(fd); return; } if (sz >= sizeof(small)) { if (fstat(fd, &st) == -1) { /* Complain */ xwarn("fstat: %s", fname); (void)close(fd); return; } sz = (ssize_t) st.st_size; buf = mmap(0, sz, PROT_READ, MAP_SHARED|MAP_FILE, fd, 0); if (buf == MAP_FAILED) { xwarn("mmap: %s", fname); (void)close(fd); return; } } (void)close(fd); while ((*path_p) != NULL) path_p = &(*path_p)->sp_next; for (b = buf, ep = buf + sz; b < ep; b++) { (void)getcstr(&b, ep, WS); if (b == ep) break; ptr = getstr(&b, ep, "\n#"); if (*ptr == '/') { /* * Since '/' != '\n' and != '#', we know ptr < * b. And we will stop when b[-1] == '/'. */ while (b[-1] == ' ' || b[-1] == '\t') b--; path_p = _rtld_append_path(head_p, path_p, execname, ptr, b); } else _rtld_process_mapping(lib_p, ptr, b); /* * b points one of ' ', \t, \n, # or equal to ep. So, * make sure we are at newline or end of string. */ (void)getstr(&b, ep, "\n"); } if (buf != small) (void)munmap(buf, sz); }