📄 ide.c
字号:
break; case IDE_CMD_IDENTIFY : sector_count = 1; buffer = (UINT8 *)buf_id; break; default : return ERROR_IDE_INVALID_COMMAND; } /**** Determine if device is available ****/ /* Select device */ IO8(IDE_DRIVE_HEAD_OFS) = (dev << IDE_DRIVE_HEAD_DEV_SHF) | 0xE0; /* Wait until BSY is cleared (may take up to 30 seconds, depending * on configuration). */ while( IO8(IDE_STATUS_OFS) & IDE_STATUS_BSY_MSK ) ; /* Devices present and functional should now have the DRDY bit set */ if( ( IO8(IDE_STATUS_OFS) & (IDE_STATUS_DRDY_MSK | IDE_STATUS_DF_MSK) ) != IDE_STATUS_DRDY_BIT ) { return ERROR_IDE_UNAVAILABLE_DEVICE; } /* Now perform the requested operation */ while( sector_count-- ) { if( (p_param->command != IDE_CMD_IDENTIFY) && (sector & 0xF0000000) ) { /* Bits 31:28 are not used for IDE */ /* Sector number is now valid for error handling */ sector_valid = TRUE; return ERROR_IDE_ID_NOT_FOUND; } /* Wait until device is ready */ while( !(IO8(IDE_STATUS_OFS) & IDE_STATUS_DRDY_BIT) ) ; if( p_param->command != IDE_CMD_IDENTIFY ) { /* Setup sector (LBA mode) */ IO8(IDE_SECTOR_COUNT_OFS) = 1; IO8(IDE_SECTOR_NUMBER_OFS) = (sector >> 0) & 0xFF; IO8(IDE_CYL_LOW_OFS) = (sector >> 8) & 0xFF; IO8(IDE_CYL_HI_OFS) = (sector >> 16) & 0xFF; IO8(IDE_DRIVE_HEAD_OFS) = ((sector >> 24) & 0x0F) | (dev << IDE_DRIVE_HEAD_DEV_SHF) | 0xE0; } /* Issue command */ IO8(IDE_COMMAND_OFS) = p_param->command; /* Wait until device is ready to exchange data or * an error is detected */ do { status = IO8(IDE_STATUS_OFS); } while( ((status & IDE_STATUS_DRQ_BIT) == 0) && ((status & IDE_STATUS_ERR_BIT) == 0) ) ; /* Note : The PIIX4 Southbridge will convert 32 bit accesses * to the IDE_DATA to two 16 bit accesses to the device. */ if( p_param->command != IDE_CMD_WRITE ) { /* Check if read caused error */ if( status & IDE_STATUS_ERR_BIT ) return get_error(); /* Read data from device sector buffer */ for( i=0; i < IDE_BYTES_PER_SECTOR / 4; i++ ) { data32 = IO32(IDE_DATA_OFS); /* Byte oriented data */ buffer[0] = (data32 >> 0) & 0xff; buffer[1] = (data32 >> 8) & 0xff; buffer[2] = (data32 >> 16) & 0xff; buffer[3] = (data32 >> 24) & 0xff;#ifdef EB if( p_param->command == IDE_CMD_IDENTIFY ) { UINT8 tmp; /* Identity data is 16 bit oriented */ tmp = buffer[0]; buffer[0] = buffer[1]; buffer[1] = tmp; tmp = buffer[2]; buffer[2] = buffer[3]; buffer[3] = tmp; }#endif buffer+= 4; } } else { /* Write data to device sector buffer */ for( i=0; i < IDE_BYTES_PER_SECTOR / 4; i++ ) { data32 = (buffer[0] << 0) | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24); IO32(IDE_DATA_OFS) = data32; buffer+= 4; } /* Wait until device is done. * This will be the case when DRQ and BSY are both cleared. */ while( IO8(IDE_STATUS_OFS) & IDE_STATUS_DRQ_BIT ) ; while( IO8(IDE_STATUS_OFS) & IDE_STATUS_BSY_BIT ) ; /* Check if write caused error */ if( IO8(IDE_STATUS_OFS) & IDE_STATUS_ERR_BIT ) return get_error(); } sector++; } if( p_param->command == IDE_CMD_IDENTIFY ) { identify_struct = &p_param->u.identify; /* Decode buffer */ i = 0; identify_struct->config = buf_id[i++]; identify_struct->cyl_count = buf_id[i++]; identify_struct->reserved0 = buf_id[i++]; identify_struct->head_count= buf_id[i++]; for( t=0; t<2; t++ ) { identify_struct->obsolete0[t] = buf_id[i++]; } identify_struct->sectors_per_track = buf_id[i++]; for( t=0; t<3; t++ ) { identify_struct->vendor_specific0[t] = buf_id[i++]; } for( t=0; t<10; t++ ) { identify_struct->serial_number[t*2] = (UINT8)(buf_id[i] >> 8); identify_struct->serial_number[t*2+1] = (UINT8)(buf_id[i++] & 0xFF); } for( t=0; t<2; t++ ) { identify_struct->obsolete1[t] = buf_id[i++]; } identify_struct->ecc_count = buf_id[i++]; for( t=0; t<4; t++ ) { identify_struct->firmware_rev[t*2] = (UINT8)(buf_id[i] >> 8); identify_struct->firmware_rev[t*2+1] = (UINT8)(buf_id[i++] & 0xFF); } for( t=0; t<20; t++ ) { identify_struct->model_name[t*2] = (UINT8)(buf_id[i] >> 8); identify_struct->model_name[t*2+1] = (UINT8)(buf_id[i++] & 0xFF); } identify_struct->sectors_per_interrupt = buf_id[i++]; identify_struct->reserved1 = buf_id[i++]; identify_struct->capabilities = buf_id[i++]; identify_struct->reserved2 = buf_id[i++]; identify_struct->timing_mode_pio = buf_id[i++]; identify_struct->timing_mode_dma = buf_id[i++]; identify_struct->application = buf_id[i++]; identify_struct->cyl_count_apparent = buf_id[i++]; identify_struct->head_count_apparent = buf_id[i++]; identify_struct->sectors_per_track_apparent = buf_id[i++]; identify_struct->capacity_apparent = (UINT32)buf_id[i] | ((UINT32)buf_id[i+1] << 16); i+=2; identify_struct->sectors_per_interrupt_apparent = buf_id[i++]; identify_struct->lba_sector_count = (UINT32)buf_id[i] | ((UINT32)buf_id[i+1] << 16); i+=2; identify_struct->modes_single_dma = buf_id[i++]; identify_struct->modes_multiple_dma = buf_id[i++]; identify_struct->modes_adv_pio = buf_id[i++]; identify_struct->min_cycle_time_dma = buf_id[i++]; identify_struct->recommended_cycle_time_dma = buf_id[i++]; identify_struct->minimum_cycle_time_pio = buf_id[i++]; identify_struct->minimom_cycle_time_pio_iordy = buf_id[i++]; for( t=0; t<59; t++ ) { identify_struct->reserved3[59] = buf_id[i++]; } for( t=0; t<32; t++ ) { identify_struct->vendor_specific1[32] = buf_id[i++]; } for( t=0; t<96; t++ ) { identify_struct->reserved4[96] = buf_id[i++]; } } return OK;}/************************************************************************ * get_error ************************************************************************/static UINT32get_error( void ){ UINT8 error = IO8(IDE_ERROR_OFS); /* Sector number is now valid for error handling */ sector_valid = TRUE; if( error & IDE_ERROR_BBK_BIT ) return ERROR_IDE_BAD_BLOCK; else if( error & IDE_ERROR_UNC_BIT ) return ERROR_IDE_UNCORRECTABLE_DATA; else if( error & IDE_ERROR_MC_BIT ) return ERROR_IDE_MEDIA_CHANGE; else if( error & IDE_ERROR_IDNF_BIT ) return ERROR_IDE_ID_NOT_FOUND; else if( error & IDE_ERROR_MCR_BIT ) return ERROR_IDE_MEDIA_CHANGE_REQUESTED; else if( error & IDE_ERROR_ABRT_BIT ) return ERROR_IDE_ABORTED; else if( error & IDE_ERROR_TK0NF_BIT ) return ERROR_IDE_TRACK_0_NOT_FOUND; else if( error & IDE_ERROR_AMNF_BIT ) return ERROR_IDE_ADDRESS_MARK_NOT_FOUND; else return ERROR_IDE_UNKNOWN;}/************************************************************************ * ide_error_lookup ************************************************************************/static INT32 ide_error_lookup( t_sys_error_string *p_param ){ UINT32 t = SYSERROR_ID( p_param->syserror ); /* check for recognized error code */ if( t < sizeof(ide_error_string)/sizeof(char*) ) { /* fill in mandatory error message string */ p_param->strings[SYSCON_ERRORMSG_IDX] = ide_error_string[t]; if( sector_valid ) { sprintf( diag_msg, "Failing sector = 0x%08x", sector ); p_param->strings[SYSCON_DIAGMSG_IDX] = diag_msg; p_param->count = 2; } else p_param->count = 1; } else p_param->count = 0; return OK;}/************************************************************************ * Implementation : Public functions ************************************************************************//************************************************************************ * * ide_install * Description : * ------------- * * Installs the IDE device driver services in the IO system at the * reserved device slot, found in the 'sysdev.h' file, which defines * all major device numbers. * * Note: * This service is the only public declared interface function; all * provided device driver services are static declared, but this * function installs the function pointers in the io-system to * enable the provided public driver services. * * Parameters : * ------------ * * - * * Return values : * --------------- * * 'OK'(=0) * 'ERROR_IO_ILLEGAL_MAJOR': Illegal major device number * 'ERROR_IO_NO_SPACE': Device slot already allocated * ************************************************************************/INT32 ide_install( void ){ t_sys_error_lookup_registration registration; /* register lookup syserror */ registration.prefix = SYSERROR_DOMAIN( ERROR_IDE ); registration.lookup = ide_error_lookup; SYSCON_write( SYSCON_ERROR_REGISTER_LOOKUP_ID, ®istration, sizeof( registration ) ); /* Install device services */ IO_install( SYS_MAJOR_IDE, /* major device number */ (t_io_service)ide_init, /* 'init' service */ NULL, /* 'open' service na */ NULL, /* 'close' service na */ NULL, /* 'read' service na */ NULL, /* 'write' service na */ (t_io_service)ide_ctrl ) ; /* 'ctrl' service */ /* call our own 'init' service */ return IO_init( SYS_MAJOR_IDE, 0, NULL);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -