コード例 #1
0
ファイル: ide.c プロジェクト: khwang18c/CMSC412
/*
 * Write a block at the logical block number indicated.
 */
static int IDE_Write(int driveNum, int blockNum, char *buffer) {
    int i;
    int head;
    int sector;
    int cylinder;
    short *bufferW;
    int reEnable = 0;

    if (driveNum < 0 || driveNum > (numDrives - 1)) {
        return IDE_ERROR_BAD_DRIVE;
    }

    if (blockNum < 0 || blockNum >= IDE_getNumBlocks(driveNum)) {
        return IDE_ERROR_INVALID_BLOCK;
    }

    if (Interrupts_Enabled()) {
        Disable_Interrupts();
        reEnable = 1;
    }

    /* now compute the head, cylinder, and sector */
    sector = blockNum % drives[driveNum].num_SectorsPerTrack + 1;
    cylinder = blockNum / (drives[driveNum].num_Heads *
                           drives[driveNum].num_SectorsPerTrack);
    head = (blockNum / drives[driveNum].num_SectorsPerTrack) %
           drives[driveNum].num_Heads;

    if (ideDebug) {
        Print("request to write block %d\n", blockNum);
        Print("    head %d\n", head);
        Print("    cylinder %d\n", cylinder);
        Print("    sector %d\n", sector);
    }

    Out_Byte(IDE_SECTOR_COUNT_REGISTER, 1);
    Out_Byte(IDE_SECTOR_NUMBER_REGISTER, sector);
    Out_Byte(IDE_CYLINDER_LOW_REGISTER, LOW_BYTE(cylinder));
    Out_Byte(IDE_CYLINDER_HIGH_REGISTER, HIGH_BYTE(cylinder));
    Out_Byte(IDE_DRIVE_HEAD_REGISTER, IDE_DRIVE(driveNum) | head);

    Out_Byte(IDE_COMMAND_REGISTER, IDE_COMMAND_WRITE_SECTORS);


    /* wait for the drive */
    while (In_Byte(IDE_STATUS_REGISTER) & IDE_STATUS_DRIVE_BUSY);

    bufferW = (short *)buffer;
    for (i = 0; i < 256; i++) {
        Out_Word(IDE_DATA_REGISTER, bufferW[i]);
    }

    if (ideDebug)
        Print("About to wait for Write \n");

    /* wait for the drive */
    while (In_Byte(IDE_STATUS_REGISTER) & IDE_STATUS_DRIVE_BUSY);

    if (In_Byte(IDE_STATUS_REGISTER) & IDE_STATUS_DRIVE_ERROR) {
        Print("ERROR: Got Read %d\n", In_Byte(IDE_STATUS_REGISTER));
        return IDE_ERROR_DRIVE_ERROR;
    }

    if (reEnable)
        Enable_Interrupts();

    return IDE_ERROR_NO_ERROR;
}
コード例 #2
0
ファイル: ide.c プロジェクト: khwang18c/CMSC412
static int readDriveConfig(int drive) {
    int i;
    int status;
    short info[256];
    char devname[BLOCKDEV_MAX_NAME_LEN];
    int rc;

    if (ideDebug > 1)
        Print("ide: about to read drive config for drive #%d\n", drive);

    Out_Byte(IDE_DRIVE_HEAD_REGISTER, IDE_DRIVE(drive));
    Out_Byte(IDE_COMMAND_REGISTER, IDE_COMMAND_IDENTIFY_DRIVE);
    while (In_Byte(IDE_STATUS_REGISTER) & IDE_STATUS_DRIVE_BUSY);

    status = In_Byte(IDE_STATUS_REGISTER);
    /*
     * simulate failure
     * status = 0x50;
     */
    if ((status & IDE_STATUS_DRIVE_DATA_REQUEST)) {
        Print("ide: probe found ATA drive\n");
        /* drive responded to ATA probe */
        for (i = 0; i < 256; i++) {
            info[i] = In_Word(IDE_DATA_REGISTER);
        }

        drives[drive].num_Cylinders = info[IDE_INDENTIFY_NUM_CYLINDERS];
        drives[drive].num_Heads = info[IDE_INDENTIFY_NUM_HEADS];
        drives[drive].num_SectorsPerTrack =
            info[IDE_INDENTIFY_NUM_SECTORS_TRACK];
        drives[drive].num_BytesPerSector =
            info[IDE_INDENTIFY_NUM_BYTES_SECTOR];
    } else {
        /* try for ATAPI */
        Out_Byte(IDE_FEATURE_REG, 0);   /* disable dma & overlap */

        Out_Byte(IDE_DRIVE_HEAD_REGISTER, IDE_DRIVE(drive));
        Out_Byte(IDE_COMMAND_REGISTER, IDE_COMMAND_ATAPI_IDENT_DRIVE);
        while (In_Byte(IDE_STATUS_REGISTER) & IDE_STATUS_DRIVE_BUSY);
        status = In_Byte(IDE_STATUS_REGISTER);
        Print("status is %x\n", status);
        if ((status & IDE_STATUS_DRIVE_DATA_REQUEST)) {
            Print("ide: found atapi drive\n");
        } else {
            Print("ide: found no drive %d\n", drive);
        }
        return -1;
    }

    Print("    ide%d: cyl=%d, heads=%d, sectors=%d\n", drive,
          drives[drive].num_Cylinders, drives[drive].num_Heads,
          drives[drive].num_SectorsPerTrack);

    /* Register the drive as a block device */
    snprintf(devname, sizeof(devname), "ide%d", drive);
    rc = Register_Block_Device(devname, &s_ideDeviceOps, drive, 0,
                               &s_ideWaitQueue, &s_ideRequestQueue);
    if (rc != 0)
        Print("  Error: could not create block device for %s\n", devname);

    return 0;
}
コード例 #3
0
ファイル: ide.c プロジェクト: Danielhu229/geekos-task
/*
 * Read a block at the logical block number indicated.
 */
static int IDE_Read(int driveNum, int blockNum, char *buffer) {
    int i;
    int head;
    int sector;
    int cylinder;
    short *bufferW;
    int reEnable = 0;

    if(driveNum < 0 || driveNum > (numDrives - 1)) {
        if(ideDebug)
            Print("ide: invalid drive %d\n", driveNum);
        return IDE_ERROR_BAD_DRIVE;
    }

    if(blockNum < 0 || blockNum >= IDE_getNumBlocks(driveNum)) {
        if(ideDebug)
            Print("ide: invalid block %d\n", blockNum);
        return IDE_ERROR_INVALID_BLOCK;
    }

    /* now compute the head, cylinder, and sector */
    sector = blockNum % drives[driveNum].num_SectorsPerTrack + 1;
    cylinder = blockNum / (drives[driveNum].num_Heads *
                           drives[driveNum].num_SectorsPerTrack);
    head = (blockNum / drives[driveNum].num_SectorsPerTrack) %
        drives[driveNum].num_Heads;

    if(ideDebug >= 2) {
        Print("request to read block %d\n", blockNum);
        Print("    head %d, cylinder %d, sector %d\n", head, cylinder,
              sector);
        // Print ("    cylinder %d\n", cylinder);
        // Print ("    sector %d\n", sector);
    }
#ifndef NS_INTERRUPTABLE_NO_GLOBAL_LOCK
    reEnable = Begin_Int_Atomic();
#endif

    Out_Byte(IDE_SECTOR_COUNT_REGISTER, 1);
    Out_Byte(IDE_SECTOR_NUMBER_REGISTER, sector);
    Out_Byte(IDE_CYLINDER_LOW_REGISTER, LOW_BYTE(cylinder));
    Out_Byte(IDE_CYLINDER_HIGH_REGISTER, HIGH_BYTE(cylinder));
    Out_Byte(IDE_DRIVE_HEAD_REGISTER, IDE_DRIVE(driveNum) | head);

    Out_Byte(IDE_COMMAND_REGISTER, IDE_COMMAND_READ_SECTORS);

    if(ideDebug > 2)
        Print("About to wait for Read \n");

    /* wait for the drive */
    while (In_Byte(IDE_STATUS_REGISTER) & IDE_STATUS_DRIVE_BUSY) ;
    if(In_Byte(IDE_STATUS_REGISTER) & IDE_STATUS_DRIVE_ERROR) {
        Print("ERROR: Got Read %d\n", In_Byte(IDE_STATUS_REGISTER));
        return IDE_ERROR_DRIVE_ERROR;
    }

    if(ideDebug > 2)
        Print("got buffer \n");

    bufferW = (short *)buffer;
    for(i = 0; i < 256; i++) {
        bufferW[i] = In_Word(IDE_DATA_REGISTER);
    }
    if(ideDebug > 2)
        Print("read buffer \n");

#ifndef NS_INTERRUPTABLE_NO_GLOBAL_LOCK
    End_Int_Atomic(reEnable);
#endif

    return IDE_ERROR_NO_ERROR;
}