void readDriveConfig(int drive) { int i; short info[256]; Out_Byte(IDE_DRIVE_HEAD_REGISTER, (drive == 0) ? IDE_DRIVE_0 : IDE_DRIVE_1); Out_Byte(IDE_COMMAND_REGISTER, IDE_COMMAND_IDENTIFY_DRIVE); while (In_Byte(IDE_STATUS_REGISTER) != 0x58); 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]; Print ("Found IDE: Drive %d\n", drive); Print (" %d cylinders, %d heads, %d sectors/tack, %d bytes/sector\n", drives[drive].num_Cylinders, drives[drive].num_Heads, drives[drive].num_SectorsPerTrack, drives[drive].num_BytesPerSector); Print (" Disk has %d blocks\n", IDE_getNumBlocks(drive)); }
void NE2000_Get_Dev_Hdr(struct Net_Device *device, struct Net_Device_Header *hdr, ulong_t pageOffset) { unsigned int i; ulong_t baseAddr = device->baseAddr; ulong_t size = sizeof(struct Net_Device_Header) >> 1; ushort_t *buffer = (ushort_t *) hdr; /* Set the Command Register */ Out_Byte(baseAddr + NE2K_CR, 0x22); /* Load the packet size into the registers */ Out_Byte(baseAddr + NE2K0W_RBCR0, sizeof(struct Net_Device_Header)); Out_Byte(baseAddr + NE2K0W_RBCR1, 0); /* Load the page start into the RSARX registers */ Out_Byte(baseAddr + NE2K0W_RSAR0, 0x00); Out_Byte(baseAddr + NE2K0W_RSAR1, pageOffset); /* Start the remote write */ Out_Byte(baseAddr + NE2K_CR, NE2K_CR_DMA_RREAD | NE2K_CR_STA); /* Read the data in through the I/O port */ for (i = 0; i < size; ++i) { buffer[i] = In_Word(baseAddr + NE2K_IO_PORT); } }
static void rtl8139_interrupt( struct Interrupt_State * state ) { Begin_IRQ(state); uint_t status = In_Word(RTL8139_ISR); PrintBoth("Interrupt Received: %x\n", status); if( status == PKT_RX ) rtl8139_Receive(); rtl8139_Clear_IRQ(status); End_IRQ(state); }
/* actually reads the data out of the device */ void NE2000_Receive(struct Net_Device *device, void *buffer, ulong_t length, ulong_t pageOffset) { ulong_t baseAddr = device->baseAddr; KASSERT(!Interrupts_Enabled()); int i; int newLength = length >> 1; unsigned short *newBuffer = (unsigned short *)buffer; /* Set the Command Register */ Out_Byte(baseAddr + NE2K_CR, 0x22); Out_Byte(baseAddr + NE2K0W_RCR, 0x0C); /* Load the packet size into the registers */ Out_Byte(baseAddr + NE2K0W_RBCR0, length & 0xFF); Out_Byte(baseAddr + NE2K0W_RBCR1, length >> 8); /* Load the page start into the RSARX registers */ Out_Byte(baseAddr + NE2K0W_RSAR0, pageOffset & 0xFF); Out_Byte(baseAddr + NE2K0W_RSAR1, pageOffset >> 8); /* Start the remote write */ Out_Byte(baseAddr + NE2K_CR, NE2K_CR_DMA_RREAD | NE2K_CR_STA); /* Read the data in through the I/O port */ for (i = 0; i < newLength; ++i) { newBuffer[i] = In_Word(baseAddr + NE2K_IO_PORT); } /* Receive the last byte of data if we have an odd length */ if (length & 0x1) { ((uchar_t *) buffer)[length - 1] = In_Byte(baseAddr + NE2K_IO_PORT); } /* Ack the remote DMA interrupt */ Out_Byte(baseAddr + NE2K0R_ISR, NE2K_ISR_RDC); device->rxBytes += length; }
/* * Read a block at the logical block number indicated. */ int IDE_Read(int driveNum, int blockNum, char *buffer) { int i; int head; int sector; int cylinder; short *bufferW; if (driveNum < 0 || driveNum > (numDrives-1)) { return IDE_ERROR_BAD_DRIVE; } if (blockNum < 0 || blockNum >= IDE_getNumBlocks(driveNum)) { 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) { Print ("request to read 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)); if (driveNum == 0) { Out_Byte(IDE_DRIVE_HEAD_REGISTER, IDE_DRIVE_0 | head); } else if (driveNum == 1) { Out_Byte(IDE_DRIVE_HEAD_REGISTER, IDE_DRIVE_1 | head); } Out_Byte(IDE_COMMAND_REGISTER, IDE_COMMAND_READ_SECTORS); if (ideDebug) Print("About to wait for Read \n"); /* wait for the drive */ while (!(In_Byte(IDE_STATUS_REGISTER) & IDE_STATUS_DRIVE_READY)); 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) Print("got buffer \n"); bufferW = (short *) buffer; for (i=0; i < 256; i++) { bufferW[i] = In_Word(IDE_DATA_REGISTER); } return IDE_ERROR_NO_ERROR; }
void Init_8139() { cur_tx = 0; cur_rx = 0; /* Reset the chip */ Out_Byte(RTL8139_CR, CmdReset); //while( In_Byte(RTL8139_CR) != 0 ) /*udelay(10)*/; /* Unlock Config[01234] and BMCR register writes */ Out_Byte(RTL8139_9346CR, Cfg9346_Unlock); /* Enable Tx/Rx before setting transfer thresholds */ Out_Byte(RTL8139_CR, CmdRxEnb | CmdTxEnb); /* Using 32K ring */ Out_DWord(RTL8139_RCR, RxCfgRcv32K | RxNoWrap | (7 << RxCfgFIFOShift) | (7 << RxCfgDMAShift) | AcceptBroadcast | AcceptMyPhys); // Out_DWord(RTL8139_TCR, RxCfgRcv32K | RxNoWrap | (7 << RxCfgFIFOShift) | (7 << RxCfgDMAShift)); Out_DWord(RTL8139_TCR, TxIFG96 | (6 << TxDMAShift) | (8 << TxRetryShift)); /* Lock Config[01234] and BMCR register writes */ Out_Byte(RTL8139_9346CR, Cfg9346_Lock); /* init Rx ring buffer DMA address */ rx_buf = Malloc(RX_BUF_LEN); Out_DWord(RTL8139_RBSTART, (uint_t)rx_buf); /* init Tx buffer DMA addresses (4 registers) */ tx_buf = Malloc(TX_BUF_SIZE * 4); int i; for(i = 0; i < 4; i++) Out_DWord(RTL8139_TSAD0 + (i * 4), ((uint_t)tx_buf) + (i * TX_BUF_SIZE)); /* missed packet counter */ Out_DWord(RTL8139_MPC, 0); // rtl8139_set_rx_mode does some stuff here. Out_DWord(RTL8139_RCR, In_DWord(RTL8139_RCR) | AcceptBroadcast | AcceptMulticast | AcceptMyPhys | AcceptAllPhys); for(i = 0; i < 8; i++) Out_Byte(RTL8139_MAR0 + i, 0xff); /* no early-rx interrupts */ Out_Word(RTL8139_MULINT, In_Word(RTL8139_MULINT) & MultiIntrClear); /* make sure RxTx has started */ if(!(In_Byte(RTL8139_CR) & CmdRxEnb) || !(In_Byte(RTL8139_CR) & CmdTxEnb)) Out_Byte(RTL8139_CR, CmdRxEnb | CmdTxEnb); /* Enable all known interrupts by setting the interrupt mask. */ Out_Word(RTL8139_IMR, rtl8139_intr_mask); Install_IRQ(RTL8139_IRQ, rtl8139_interrupt); Enable_IRQ(RTL8139_IRQ); PrintBoth("8139 initialized\n"); }
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; }
/* * 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; }
int Init_NE2000(struct Net_Device *device) { unsigned char saProm[32]; int i; ulong_t baseAddr = device->baseAddr; Print("Initializing ne2000 nic...\n"); /* Read the PROM, taken from ne2k-pci.c in linux kernel */ Out_Byte(baseAddr + NE2K_CR, 0x21); Out_Byte(baseAddr + NE2K0W_DCR, 0x49); Out_Byte(baseAddr + NE2K0W_RBCR0, 0x00); Out_Byte(baseAddr + NE2K0W_RBCR1, 0x00); Out_Byte(baseAddr + NE2K0W_IMR, 0x00); Out_Byte(baseAddr + NE2K0R_ISR, 0xFF); Out_Byte(baseAddr + NE2K0W_RCR, 0x20); Out_Byte(baseAddr + NE2K0W_TCR, 0x02); Out_Byte(baseAddr + NE2K0W_RBCR0, 32); Out_Byte(baseAddr + NE2K0W_RBCR1, 0x00); Out_Byte(baseAddr + NE2K0W_RSAR0, 0x00); Out_Byte(baseAddr + NE2K0W_RSAR1, 0x00); Out_Byte(baseAddr + NE2K_CR, NE2K_CR_STA + NE2K_CR_DMA_RREAD); for (i = 0; i < 32; ++i) { saProm[i] = (unsigned char)In_Word(baseAddr + NE2K_IO_PORT); } /* Ensure this is an ne2000. Ne2000 cards have the byte values 0x57 in the 0x0e and 0x0f bytes in the station prom */ if (saProm[0x0e] != 0x57 || saProm[0x0f] != 0x57) { return -1; } /* Print out the mac address */ device->addrLength = 6; Print("Mac address: "); for (i = 0; i < 6; ++i) { device->devAddr[i] = saProm[i]; Print("%02x", saProm[i]); if (i < 5) Print(":"); } Print("\n"); /* Install interrupt handler */ Install_IRQ(device->irq, NE2000_Interrupt_Handler); /* Enable IRQ */ Enable_IRQ(device->irq); /* Program Command Register for Page 0 */ Out_Byte(baseAddr + NE2K_CR, 0x21); /* Initialize Data Configuration Register */ Out_Byte(baseAddr + NE2K0W_DCR, 0x49); /* Clear remote byte count registers */ Out_Byte(baseAddr + NE2K0W_RBCR0, 0x00); Out_Byte(baseAddr + NE2K0W_RBCR1, 0x00); /* Initialize Receive Configuration Register */ Out_Byte(baseAddr + NE2K0W_RCR, 0x0C); /* Place the NIC in LOOPBACK mode 1 or 2 */ Out_Byte(baseAddr + NE2K0W_TCR, 0x02); /* Initialize Transmit page start register */ Out_Byte(baseAddr + NE2K0W_TPSR, NE2K_TRANSMIT_PAGE); /* Clear Interrupt Status Register ISR by writing 0xFF to it */ Out_Byte(baseAddr + NE2K0R_ISR, 0xFF); /* Initialize Interrupt Mask Register */ Out_Byte(baseAddr + NE2K0W_IMR, 0x0F + NE2K_ISR_OVW); /* Initialize the Receive Buffer Ring (BNDRY, PSTART, PSTOP) */ Out_Byte(baseAddr + NE2K0W_PSTART, NE2K_RB_START); Out_Byte(baseAddr + NE2K0W_BNRY, NE2K_RB_START); Out_Byte(baseAddr + NE2K0W_PSTOP, NE2K_RB_STOP); /* Go to Page 1 */ Out_Byte(baseAddr + NE2K_CR, 0x61); /* Initialize Physical Address Registers */ Out_Byte(baseAddr + NE2K1W_PAR0, saProm[0]); Out_Byte(baseAddr + NE2K1W_PAR1, saProm[1]); Out_Byte(baseAddr + NE2K1W_PAR2, saProm[2]); Out_Byte(baseAddr + NE2K1W_PAR3, saProm[3]); Out_Byte(baseAddr + NE2K1W_PAR4, saProm[4]); Out_Byte(baseAddr + NE2K1W_PAR5, saProm[5]); /* Initialize Multicast Address Registers */ Out_Byte(baseAddr + NE2K1W_MAR0, 0xFF); Out_Byte(baseAddr + NE2K1W_MAR1, 0xFF); Out_Byte(baseAddr + NE2K1W_MAR2, 0xFF); Out_Byte(baseAddr + NE2K1W_MAR3, 0xFF); Out_Byte(baseAddr + NE2K1W_MAR4, 0xFF); Out_Byte(baseAddr + NE2K1W_MAR5, 0xFF); Out_Byte(baseAddr + NE2K1W_MAR6, 0xFF); Out_Byte(baseAddr + NE2K1W_MAR7, 0xFF); /* Write the CURRENT buffer address */ Out_Byte(baseAddr + NE2K1W_CURR, NE2K_RB_START); Print("Current buffer Address: %x\n", In_Byte(baseAddr + NE2K1W_CURR)); /* Go back to Page 0 and Start */ Out_Byte(baseAddr + NE2K_CR, 0x22); /* Initialize the Transmit Configuration Register */ Out_Byte(baseAddr + NE2K0W_TCR, 0x00); return 0; }