📄 pci_ide_bus.c
字号:
int_set_io_interrupt_handler(14,&ide_interrupt_handler, current_cookie); break; } i++; } } return 0; } return -1;}static int read_block(void *cookie,int drive,long block,void *buffer,size_t size){ pci_bus_cookie *bus_cookie; ide_drive *thedrive; if(drive<0 || drive>1) return -1; bus_cookie = cookie; thedrive = bus_cookie->drives[drive]; if(thedrive==NULL) return -1; return thedrive->read_block(bus_cookie,bus_cookie->drive_cookie[drive],block,buffer,size);}static int write_block(void *cookie,int drive,long block,void *buffer,size_t size){ pci_bus_cookie *bus_cookie; ide_drive *thedrive; if(drive<0 || drive>1) return -1; bus_cookie = cookie; thedrive = bus_cookie->drives[drive]; if(thedrive==NULL) return -1; return thedrive->write_block(bus_cookie,bus_cookie->drive_cookie[drive],block,buffer,size);}static int setup_dma(void *cookie,int dir, long size, uint8 *buffer ){ TRACE(("entering setup_dma %x %d %d,%p\n",cookie,dir,size,buffer)); pci_bus_cookie *bus_cookie = cookie; prd_entry *table = (prd_entry*)bus_cookie->prd_buf_address; uint32 count = 0; uint32 physical_address; uint32 position = 0; uint32 bufaddr; uint8 *logical_address; out8( BM_CR_MASK_STOP,bus_cookie->io_port + BM_COMMAND_REG); // disable dma_channel out8( bus_cookie->stat_reg | BM_SR_MASK_INT | BM_SR_MASK_ERR,bus_cookie->io_port+ BM_STATUS_REG); // clear dma channel ) bus_cookie->current_dma = buffer; bus_cookie->current_dma_length = size;#define PRD_ENTRIES 8 while (size) { if (count++ >= PRD_ENTRIES) { panic("DMA table too small\n"); } else { physical_address = (uint32)(bus_cookie->raw_buffer + position); count = min (size, 0x10000); if ((physical_address & ~(0x10000-1)) != ((physical_address+count-1) & ~(0x10000-1))) count = 0x10000 - (physical_address & (0x10000-1)); table->address = physical_address; table->count = count & 0xFFFFE; table->eot = 0; table++; size -= count; position += count; } } table--; table->eot = 1; uint32 reserved; reserved = in32(bus_cookie->io_port+BM_PRD_ADDR_LOW) & 0x03; out32(bus_cookie->prd_phy_address | reserved,bus_cookie->io_port+BM_PRD_ADDR_LOW); if ( dir ) { bus_cookie->rw_control = BM_CR_MASK_READ; // ATA Write DMA } else { bus_cookie->rw_control = BM_CR_MASK_WRITE; // ATA Read DMA } out8( bus_cookie->rw_control,bus_cookie->io_port + BM_COMMAND_REG); return 0; }static int start_dma(void *cookie){ pci_bus_cookie *bus_cookie = cookie; TRACE(("DMA about to start cookie=%p\n",bus_cookie)); out8( bus_cookie->rw_control | BM_CR_MASK_START,bus_cookie->io_port + BM_COMMAND_REG ); TRACE(("DMA should have started\n")); return 0;}static int finish_dma(void *cookie){ pci_bus_cookie *bus_cookie = cookie; uint8 status; TRACE(("waiting for DMA to finish\n")); out8( BM_CR_MASK_STOP,bus_cookie->io_port + BM_COMMAND_REG); // disable dma_channel status = read_register( cookie,CB_STAT ); TRACE(("first status = %d\n",status)); if ( status & ( CB_STAT_BSY | CB_STAT_DF | CB_STAT_DRQ | CB_STAT_ERR ) ) return -1; status = in8( bus_cookie->io_port + BM_STATUS_REG ); TRACE(("second status = %d %d\n",status,status & BM_SR_MASK_INT)); TRACE(("pci_ide will copy %d bytes\n",bus_cookie->current_dma_length)); bcopy(bus_cookie->mapped_address,bus_cookie->current_dma,bus_cookie->current_dma_length); switch(status & 0x5) { case 0: TRACE(("IDE -- finish_dma: DMA transfer failed\n")); return -1; case 1: TRACE(("IDE -- finish_dma: DMA transfer aborted\n")); return -1; case 4: return 0; case 5: TRACE(("IDE -- finish_dma: PRD size > device transfer size!\n")); return -1; } return 0;}static int write_register(void *cookie,int reg,uint8 value){ pci_bus_cookie *bus_cookie = cookie; uint16 reg_addr = bus_cookie->pio_reg_addrs[reg]; out8(value,reg_addr); return 0;}static int write_register16(void *cookie,int reg,uint16 value){ pci_bus_cookie *bus_cookie = cookie; uint16 reg_addr = bus_cookie->pio_reg_addrs[reg]; out16(value,reg_addr); return 0;}static uint8 read_register(void *cookie,int reg){ pci_bus_cookie *bus_cookie = cookie; uint16 reg_addr = bus_cookie->pio_reg_addrs[reg]; return in8(reg_addr);}static uint16 read_register16(void *cookie,int reg){ pci_bus_cookie *bus_cookie = cookie; uint16 reg_addr = bus_cookie->pio_reg_addrs[reg]; return in16(reg_addr);}static uint8 get_alt_value(void *cookie){ return read_register( cookie,CB_ASTAT );}static int transfer_buffer(void *cookie,int reg,void *buffer,size_t size,bool fromMemory){ pci_bus_cookie *bus_cookie = cookie; uint16 reg_addr = bus_cookie->pio_reg_addrs[reg]; if(fromMemory==false) { __asm__ __volatile__ ( "rep ; outsw" : "=S" (buffer), "=c" (size) : "d" (reg_addr),"0" (buffer),"1" (size) ); } else { __asm__ __volatile__ ( "rep ; insw" : "=D" (buffer), "=c" (size) : "d" (reg_addr),"0" (buffer),"1" (size) ); } return 0;}static int select_drive(void *cookie,int drive){ if(drive==0) pci_bus.write_register( cookie,CB_DH, CB_DH_DEV0 ); else pci_bus.write_register( cookie,CB_DH, CB_DH_DEV1 ); return 0;}static int delay_on_bus(void *cookie){ pci_bus.get_alt_status(cookie); pci_bus.get_alt_status(cookie); pci_bus.get_alt_status(cookie); pci_bus.get_alt_status(cookie); return 0;}static int reset_bus(void *cookie,int default_drive){ unsigned char status; unsigned char devCtrl; devCtrl = CB_DC_HD15 | ( CB_DC_NIEN ); pci_bus.write_register(cookie,CB_DC, devCtrl | CB_DC_SRST ); pci_bus.delay_on_bus(cookie); pci_bus.write_register(cookie,CB_DC, devCtrl ); pci_bus.delay_on_bus(cookie); if(pci_bus.wait_busy(cookie)==-1) return -1; pci_bus.select_drive( cookie,default_drive ); pci_bus.delay_on_bus(cookie); return 0;}static int wait_busy(void *cookie){ int iterations = 0; uint8 status; while ( 1 ) { status = pci_bus.get_alt_status(cookie); if ( ( status & CB_STAT_BSY ) == 0 ) return 0; if ( iterations>10000 ) { return -1; } iterations++; } return 0;}static void *get_nth_cookie(int channel){ return bus_cookies[channel];}static bool support_dma(void *cookie){ pci_bus_cookie *bus_cookie = cookie; return bus_cookie->dma_supported;}static int lock(void *cookie){ pci_bus_cookie *bus_cookie = cookie; return sem_acquire(bus_cookie->bus_semaphore,1);}static int unlock(void *cookie){ pci_bus_cookie *bus_cookie = cookie; return sem_release(bus_cookie->bus_semaphore,1);}static void *get_attached_drive(void *cookie,int drive){ pci_bus_cookie *bus_cookie = cookie; return bus_cookie->drives[drive];}static void *get_attached_drive_cookie(void *cookie,int drive){ pci_bus_cookie *bus_cookie = cookie; return bus_cookie->drive_cookie[drive];}ide_bus pci_bus ={ "PCI_BUS", &init, &read_block, &write_block, &setup_dma, &start_dma, &finish_dma, &write_register16, &write_register, &read_register16, &read_register, &get_alt_value, &transfer_buffer, &select_drive, &reset_bus, &delay_on_bus, &wait_busy, &get_nth_cookie, &get_attached_drive, &get_attached_drive_cookie, &support_dma, &lock, &unlock};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -