SYSCALL_HANDLER3(sys_read, uint32_t fd, const void *buf, size_t *c) { ssize_t *t = (ssize_t*)c; if (buf == NULL) { kerr("buffer null !"); *t = -1; return; } process_t * process = get_current_process(); open_file_descriptor *ofd; if (process->fd[fd]) { ofd = process->fd[fd]; if(ofd->f_ops->read == NULL) { kerr("No \"read\" method for this device."); *t = -1; } else { *t = ofd->f_ops->read(ofd, (void*) buf, *c); } } else { *t = -1; } }
void floppy_dma_init(floppy_io io_dir) { //Pour initialiser le dma, on doit lui fournir l'adresse du buffer, ainsi que le nombre d'octets à lire union { uint8_t b[4]; // 4 x 1 octet uint32_t l; // 1 x 4 octets } address, count; char dma_mode; count.l = (uint32_t) floppy_dmalen - 1; // "-1 car le DMA compte de address jusqu'a 0xffff en décrémentant, et non jusqu'à 0x0000 address.l = (uint32_t) &floppy_dma_buffer; // Count doit tenir sur 16bits et Address sur 24bits. // De plus la somme des deux ne doit pas lever de retenue // On vérifie donc tout ça avant d'aller plus loin if((count.l >> 16)|(address.l >> 24)|(((address.l & 0xffff)+ count.l) >> 16)) { kerr("Static buffer error.\n"); return; } switch(io_dir) { case FLOPPY_READ: // READ = single/inc/no-auto/to-mem/chan2 = 01-0-0-01-10 dma_mode = 0x46; break; case FLOPPY_WRITE: // WRITE = single/inc/no-auto/from-mem/chan2 = 01-0-0-10-10 dma_mode = 0x4A; break; default: kerr("Invalid io_dir (0x%x).", io_dir); return; } outb(0x06, 0x0a); // masque le channel 2 outb(0xff, 0x0c); // reset flip-flop outb(address.b[0], 0x04); // - address low byte outb(address.b[1], 0x04); // - address high byte outb(address.b[2], 0x81); // registre de page externe outb(0xff, 0x0c); // reset flip-flop outb(count.b[0], 0x05); // - count low byte outb(count.b[1], 0x05); // - count high byte outb(dma_mode, 0x0b); // donne le mode du DMA outb(0x02, 0x0a); // démasque le channel 2 }
SYSCALL_HANDLER3(sys_sigprocmask, uint32_t how, sigset_t* set, sigset_t* oldset) { process_t* current = get_current_process(); /* On récupère l'ancien set */ if (oldset != NULL) *oldset = current->signal_data.mask; /* Si set est null, alors on fait rien. */ if (set == NULL) return; /* Et on met à jour le nouveau */ switch(how) { case SIG_SETMASK: current->signal_data.mask = *set; break; case SIG_UNBLOCK: current->signal_data.mask &= ~(*set); break; case SIG_BLOCK: current->signal_data.mask |= (*set); break; default: kerr("Invalid sigprocmask command (0x%x).", how); } }
struct caldav * caldav_parse(const char *buf, size_t sz) { struct parse p; memset(&p, 0, sizeof(struct parse)); if (NULL == (p.xp = XML_ParserCreateNS(NULL, ':'))) { kerr(NULL); return(NULL); } bufappend(&p.buf, " ", 1); XML_SetDefaultHandler(p.xp, NULL); XML_SetElementHandler(p.xp, parseopen, parseclose); XML_SetCdataSectionHandler(p.xp, cdata, cdata); XML_SetUserData(p.xp, &p); if (XML_STATUS_OK != XML_Parse(p.xp, buf, (int)sz, 1)) { caldav_free(p.p); p.p = NULL; } XML_ParserFree(p.xp); free(p.buf.buf); return(p.p); }
int init_floppy() { int drive = floppy_get_current_drive(); uint8_t drive_type = 0; uint8_t CCR; /* On vérifie qu'on a bien un controleur standard, sinon on affiche un warning */ if(floppy_get_version() != 0x90) kerr("WARNING: Floppy driver may not work with 0x%x controler.", floppy_get_version()); floppy_reset_irq(); // On fait le reset du controler + activation DMA/IRQ outb(0x00, FLOPPY_BASE + FLOPPY_DOR); outb(0x0C, FLOPPY_BASE + FLOPPY_DOR); floppy_wait_irq(); floppy_sense_interrupt(NULL,NULL); // On regle la vitesse de transfert en fonction du type de disquette drive_type = floppy_get_type(drive); switch(drive_type) { case 1: // 300 kbps (01) case 3: CCR = 0x01; break; case 2: // 500 kbps (00) case 4: CCR = 0x00; break; case 5: // 1 Mbps (11) CCR= 0x03; break; default: CCR = 0x00; // choix arbitraire btw break; } outb(CCR, FLOPPY_BASE + FLOPPY_CCR); /* Totalement hardcodé et moche à fortiori*/ floppy_write_command(SPECIFY); floppy_write_command(0xdf); /* steprate = 3ms, unload time = 240ms */ floppy_write_command(0x02); /* load time = 16ms, no-DMA = 0 */ /* *************************************** */ // On calibre le lecteur if(floppy_calibrate()) return -1; return 0; }
// Repositionne la tête de lecture sur le cylindre 0 int floppy_calibrate() { int i, st0, cy1 = -1; int drive = floppy_get_current_drive(); // Allumer le moteur floppy_motor(ON); // On essaye 5 fois (oui c'est totalement arbitraire) for(i=0; i<5; i++) { // Le recalibrage déclenche l'IRQ, on se prépare donc à attendre l'IRQ floppy_reset_irq(); // Procedure de calibrage: // On envoi dans un premier temps la commande RECALIBRATE, // puis on envoi le numero du lecteur que l'on veut recalibrer floppy_write_command(RECALIBRATE); floppy_write_command(drive); // On attend la réponse floppy_wait_irq(); // une fois l'IRQ arrivée, on peut récuperer les données de retour via SENSE_INTERRUPT floppy_sense_interrupt(&st0, &cy1); if(st0 & 0xC0) { static const char * status[] = { 0, "error", "invalid", "drive" }; klog("floppy_recalibrate: status = %s.", status[st0 >> 6]); klog("\tST0:0x%x.\nCY1:0x%x.", st0, cy1); continue; } if(!cy1) // si cy1=0, on a bien atteint le cylindre 0 et on peut arreter la calibration { floppy_motor(OFF); return 0; } } kerr("floppy_recalibrate: failure."); floppy_motor(OFF); return -1; }
SYSCALL_HANDLER3(sys_ioctl, uint32_t *fd, unsigned int request, void *data) { process_t * process = get_current_process(); open_file_descriptor *ofd; if (process->fd[*fd]) { ofd = process->fd[*fd]; if (ofd->f_ops->ioctl == NULL) { kerr("No \"ioctl\" method for this device."); *fd = -1; } else { *fd = ofd->f_ops->ioctl(ofd, request, data); } } }
SYSCALL_HANDLER3(sys_seek, uint32_t fd, long *offset, int whence) { process_t * process = get_current_process(); open_file_descriptor *ofd; if (process->fd[fd]) { ofd = process->fd[fd]; if(ofd->f_ops->seek == NULL) { kerr("No \"seek\" method for this device."); *offset = -1; } else { ofd->f_ops->seek(ofd, *offset, whence); *offset = ofd->current_octet; } } }
double *getklist(K p) { double *r; r=g_malloc(p->n*sizeof(double)); switch(p->t){ case 1 : case 4 : DO(p->n,r[i]=kG(p)[i]);break; case 5 : DO(p->n,r[i]=kH(p)[i]);break; case 6 : case 13 : case 14 : case 17 : case 18 : DO(p->n,r[i]=kI(p)[i]);break; case 7 : case 16 : DO(p->n,r[i]=kJ(p)[i]);break; case 8 : DO(p->n,r[i]=kE(p)[i]);break; case 9 : case 15 : DO(p->n,r[i]=kF(p)[i]);break; case 10 : DO(p->n,r[i]=kC(p)[i]);break; default : g_free(r);return (double *)kerr("invalid numeric type"); } return r; }
SYSCALL_HANDLER3(sys_write, uint32_t fd, const void *buf, size_t *c) { process_t * process = get_current_process(); ssize_t *t = (ssize_t*)c; open_file_descriptor *ofd; if (process->fd[fd]) { ofd = process->fd[fd]; if(ofd->f_ops->write == NULL) { kerr("No \"write\" method for this device."); *t = -1; } else { *t = ofd->f_ops->write(ofd, buf, *c); } } else { *t = -1; } }
/* * Decompose a path into the principal, collection, and resource parts. * We manage this as follows: * /principal/collection/resource * For now, the collection can't have directories of its own. * Return zero on failure (no leading slash or memory failure), non-zero * on success. * All pointers will be set. */ int http_paths(const char *in, char **pp, char **cp, char **rp) { const char *p; *pp = *cp = *rp = NULL; /* Strip leading absolute path. */ if ('/' != in[0]) return(0); in++; if (NULL != (p = strchr(in, '/'))) { *pp = malloc(p - in + 1); memcpy(*pp, in, p - in); (*pp)[p - in] = '\0'; in = p + 1; if (NULL != (p = strrchr(in, '/'))) { *cp = malloc(p - in + 1); memcpy(*cp, in, p - in); (*cp)[p - in] = '\0'; in = p + 1; http_decode(in, rp); } else { *cp = strdup(""); http_decode(in, rp); } } else { *pp = strdup(in); *cp = strdup(""); *rp = strdup(""); } if (NULL == *pp || NULL == *cp || NULL == *rp) { kerr(NULL); free(*pp); free(*cp); free(*rp); return(0); } return(1); }
/* TODO: d'après POSIX, kill(-1, sig) doit envoyer le signal à tous les processus possibles... */ SYSCALL_HANDLER3(sys_kill, int pid, int signum, int* ret) { process_t* process = find_process(pid); int retour = -1; if(process != NULL) { retour = sigaddset( &(process->signal_data.pending_set), signum ); klog("%d sending signal %s(%d) to pid %d.", get_current_process()->pid, signal_names[signum], signum, pid); } else { kerr("Process not found (%d).", pid); } if(ret!=NULL) *ret = retour; }
static int floppy_cylinder(int drive, int cylinder, floppy_io io_dir) { uint8_t command = 0; int i; const uint8_t flags = 0xC0; // Multitrack et MFM activés // Variables recevant les valeurs de retour de la lecture uint8_t st0, st1, st2, rcy, rhe, rse, bps; int error = 0; switch(io_dir) { case FLOPPY_WRITE: command = WRITE_DATA | flags; break; case FLOPPY_READ: command = READ_DATA | flags; break; default: kerr("Invalid io_dir (0x%x).", io_dir); return -1; } // On lit avec les deux têtes, on les met donc toutes en position if(floppy_seek(drive, cylinder, 0)) return -1; if(floppy_seek(drive, cylinder, 1)) return -1; // On s'accord 5 essais, totalement arbitraire, à calibrer donc. for(i=0; i<5; i++) { // Allumage moteur floppy_motor(drive, ON); // Initialisation DMA floppy_dma_init(io_dir); //TODO: Sleep pour attendre que le seek soit bien fini // Envoi de la commande //1) Commande //2) (head<<2)|drive //3) Numero du cylindre //4) head //5) Numero du premier secteur //6) Taille des secteur(2=512 bytes, ce qui est le cas pour toutes les floppy...) //7) Nombre de secteurs à lire //8) 0x1b (taille par défaut de GAP1) //9) 0xff (??) floppy_write_command(command); floppy_write_command(drive&0x03); // head = 0 dans le cas du MT, et drive&0x03 au cas ou drive > 3 floppy_write_command(cylinder); floppy_write_command(0); // voir plus haut floppy_write_command(1); // On compte les secteurs a partir de 1 floppy_write_command(2); floppy_write_command(18); // 18 secteurs par piste floppy_write_command(0x1b); floppy_write_command(0xff); floppy_wait_irq(); // On verifie que la lecture c'est correctement déroulée // Informations de statut st0 = floppy_read_data(); st1 = floppy_read_data(); st2 = floppy_read_data(); // Informations sur les CHS rcy = floppy_read_data(); // Cylindre rhe = floppy_read_data(); // Head rse = floppy_read_data(); // Secteur bps = floppy_read_data(); // Nomber de byte par secteur /* Traitement des erreurs repompée */ if(st0 & 0xC0) { static const char * status[] = { 0, "error", "invalid command", "drive not ready" }; klog("floppy_do_sector: status = %s", status[st0 >> 6]); error = 1; } if(st1 & 0x80) { kerr("end of cylinder"); error = 1; } if(st0 & 0x08) { kerr("drive not ready "); error = 1; } if(st1 & 0x20) { kerr("CRC error"); error = 1; } if(st1 & 0x10) { kerr("controller timeout"); error = 1; } if(st1 & 0x04) { kerr("no data found\n"); error = 1; } if((st1|st2) & 0x01) { kerr("no address mark found"); error = 1; } if(st2 & 0x40) { kerr("deleted address mark"); error = 1; } if(st2 & 0x20) { kerr("CRC error in data"); error = 1; } if(st2 & 0x10) { kerr("wrong cylinder"); error = 1; } if(st2 & 0x04) { kerr("uPD765 sector not found"); error = 1; } if(st2 & 0x02) { kerr("bad cylinder"); error = 1; } if(bps != 0x2) { kerr("wanted 512B/sector, got %d", (1<<(bps+7))); error = 1; } if(st1 & 0x02) { kerr("not writable"); error = 2; } if(!error) { floppy_motor(drive, OFF); return 0; } if(error > 1) { kerr("not retrying...(rcy = %0x%x, rhe = %0x%x, rse = %0x%x)", rcy, rhe, rse); floppy_motor(drive, OFF); return -2; } } return 0; }