//硬盘读入sec_cnt个扇区的数据到buf static void read_from_sector(struct disk* hd,void* buf,uint8_t sec_cnt){ uint32_t size_in_byte; if(sec_cnt == 0){ //因为sec_cnt是8为变量,由主调函数将其赋值时,若为256则会将最高位的1丢掉变为0 size_in_byte = 256 * 512; }else{ size_in_byte = sec_cnt * 512; } insw(reg_data(hd->my_channel),buf,size_in_byte / 2); }
// RAMのaddrからsizeバイトdstに読み込み。 void ne_getblock(ne_t* ne, ushort addr, int size, void* dst) { ne_rdma_setup(ne, CR_DM_RR, addr, size); if (ne->is16bit) insw(ne->base + NE_DATA, dst, size); else insb(ne->base + NE_DATA, dst, size); return; }
static void q40ide_input_data(ide_drive_t *drive, struct request *rq, void *buf, unsigned int len) { unsigned long data_addr = drive->hwif->io_ports.data_addr; if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS) return insw(data_addr, buf, (len + 1) / 2); insw_swapw(data_addr, buf, (len + 1) / 2); }
//------------------------------------------------------------------------------------------------------------------------------- // // 读取硬盘分区信息函数 // //------------------------------------------------------------------------------------------------------------------------------- int ReadPartition(void) { int i = 0; int sector, head, cylinder; unsigned char buffer[512]; struct partition* p; #ifndef HD_BOOT_SECTOR #define HD_BOOT_SECTOR 0 #endif ConsolePrintf("Check the hard disk partition\n"); sector = HD_BOOT_SECTOR &0xff; cylinder = (HD_BOOT_SECTOR &0xffff00)>>8; head = (HD_BOOT_SECTOR &0xf000000)>>24; while(inb(HD_STATUS) & 0x80); io_wait(); outb(0,HD_CMD); outb(1,0x1f2); ///////////读写的扇区数.这个端口应该是:0X1F2,下面开始增加一 outb(HD_BOOT_SECTOR,0x1f3); ////////开始扇区 outb(cylinder,0x1f4); ///////开始柱面 outb(cylinder>>8,0x1f5); ///////开始柱面高位 outb(0xE0|(0 <<4)|head,0x1f6); /////主磁盘 outb(0x20,0x1F7); ////read命令 while(inb(HD_STATUS) & 0x80); insw(0x1F0, buffer, 256); if (buffer[510] != (unsigned char) 0x55 || buffer[511] != (unsigned char) 0xAA){ ConsolePrintFault(); ConsoleWarning(" read_partition(): Can't Read Harddisk(IDE) partition data\n"); return -1; } ConsolePrintOK(); for (i=1;i<5;i++) { p = (struct partition*)&buffer[0x1be + (i-1)*0x10]; //partition table offset after 446 byte. hd[i].start_sect = p->start_sec; // 从0算起的绝对扇区(分区表的起始扇区,不是FAT表的) hd[i].start_head=p->start_head; hd[i].start_cyl=p->start_cyl; hd[i].nr_sects = p->size; // 分区扇区总数 hd[i].flag = p->type; hd[i].lowsec = p->lowsec; hd[i].type = GetPartitionName( p->type); hd[i].name = 0x42+i; FindActivePartition(p, i); } ReadIDEInfo(); return 0; }
static int ad7606_par16_read_block(struct device *dev, int count, void *buf) { struct platform_device *pdev = to_platform_device(dev); struct iio_dev *indio_dev = platform_get_drvdata(pdev); struct ad7606_state *st = iio_priv(indio_dev); insw((unsigned long) st->base_address, buf, count); return 0; }
static inline void hfa384x_insw_debug(struct net_device *dev, int a, u8 *buf, int wc) { struct hostap_interface *iface = dev->priv; local_info_t *local = iface->local; unsigned long flags; spin_lock_irqsave(&local->lock, flags); prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INSW, a, wc); insw(dev->base_addr + a, buf, wc); spin_unlock_irqrestore(&local->lock, flags); }
/* ** Name: void pio_getblock(dpeth_t *dep, u16_t offset, ** int size, void *dst) ** Function: Reads a block of packet from board (Prog. I/O). */ static void pio_getblock(dpeth_t *dep, u16_t offset, int size, void *dst) { /* Sets up board for reading */ ns_rw_setup(dep, CR_DM_RR, size, offset); #if PIO16 == 0 insb(dep->de_data_port, SELF, dst, size); #else if (dep->de_16bit == TRUE) { insw(dep->de_data_port, dst, size); } else { insb(dep->de_data_port, dst, size); } #endif return; }
//------------------------------------------------------------------------------------------------------------------------------- // // 硬盘读写处理函数 // //------------------------------------------------------------------------------------------------------------------------------- void HardDiskRW(int RW, unsigned long sectors, void* buffer) { unsigned __eflag; int sector, head, cylinder; save_eflags(&__eflag); sector = sectors &0xff; cylinder = (sectors &0xffff00)>>8; head = (sectors &0xf000000)>>24; while(inb(HD_STATUS) & 0x80); io_wait(); outb(0,HD_CMD); outb(1,0x1f2); ///////////读写的扇区数.这个端口应该是:0X1F2,下面开始增加一 outb(sector,0x1f3); ////////开始扇区 outb(cylinder,0x1f4); ///////开始柱面 outb(cylinder>>8,0x1f5); ///////开始柱面高位 outb(0xE0|(0 <<4)|head,0x1f6); /////主磁盘 if (RW == READ) { ////read命令 outb(0x20,0x1F7); while(inb(HD_STATUS) & 0x80); insw(0x1F0, buffer, 256); } else if (RW == WRITE) { ////write命令 if (inb(HD_STATUS & 0x01)) { ConsoleWarning(" issue write_command command error !\n"); return; } outb(0x30,0x1F7); while((inb(HD_STATUS) & 0x08) == 0); //DRQ outsw(0x1F0, buffer, 256); } else { ConsoleWarning(" Panic:bad command:you only can read or write on harddisk!"); } restore_eflags(__eflag); return; }
static void read_intr(void) { struct request *req; int i, retries = 100000; do { i = (unsigned) inb_p(HD_STATUS); if (i & BUSY_STAT) continue; if (!OK_STATUS(i)) break; if (i & DRQ_STAT) goto ok_to_read; } while (--retries > 0); dump_status("read_intr", i); bad_rw_intr(); hd_request(); return; ok_to_read: req = CURRENT; insw(HD_DATA,req->buffer,256); req->sector++; req->buffer += 512; req->errors = 0; i = --req->nr_sectors; --req->current_nr_sectors; #ifdef DEBUG printk("%s: read: sector %ld, remaining = %ld, buffer=%p\n", req->rq_disk->disk_name, req->sector, req->nr_sectors, req->buffer+512); #endif if (req->current_nr_sectors <= 0) end_request(req, 1); if (i > 0) { SET_HANDLER(&read_intr); return; } (void) inb_p(HD_STATUS); #if (HD_DELAY > 0) last_req = read_timer(); #endif if (elv_next_request(QUEUE)) hd_request(); return; }
/************************************************************************** POLL - Wait for a frame ***************************************************************************/ static int tiara_poll(struct nic *nic) { unsigned int len; if (inb(ioaddr + DLCR_RECV_MODE) & BUF_EMPTY) return (0); /* Ack packet */ outw(CLR_RCV_STATUS, ioaddr + DLCR_RECV_STAT); len = inw(ioaddr + BMPR_MEM_PORT); /* throw away status */ len = inw(ioaddr + BMPR_MEM_PORT); /* Drop overlength packets */ if (len > ETH_FRAME_LEN) return (0); /* should we drain the buffer? */ insw(ioaddr + BMPR_MEM_PORT, nic->packet, len / 2); /* If it's our own, drop it */ if (memcmp(nic->packet + ETH_ALEN, nic->node_addr, ETH_ALEN) == 0) return (0); nic->packetlen = len; return (1); }
void bus_space_read_multi_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int16_t *ptr, bus_size_t cnt) { if ((t) == X86_BUS_SPACE_IO) { insw(h + o, ptr, cnt); } else { void *dummy1; int dummy2; void *dummy3; int __x; __asm __volatile(" cld ;" "1: movw (%2),%%ax ;" " stosw ;" " loop 1b" : "=D" (dummy1), "=c" (dummy2), "=r" (dummy3), "=&a" (__x) : "0" ((ptr)), "1" ((cnt)), "2" (h + o) : "memory"); } }
/* * This is used for most PIO data transfers *from* the IDE interface * * These routines will round up any request for an odd number of bytes, * so if an odd len is specified, be sure that there's at least one * extra byte allocated for the buffer. */ void ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf, unsigned int len) { ide_hwif_t *hwif = drive->hwif; struct ide_io_ports *io_ports = &hwif->io_ports; unsigned long data_addr = io_ports->data_addr; unsigned int words = (len + 1) >> 1; u8 io_32bit = drive->io_32bit; u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; if (io_32bit) { unsigned long uninitialized_var(flags); if ((io_32bit & 2) && !mmio) { local_irq_save_nort(flags); ata_vlb_sync(io_ports->nsect_addr); } words >>= 1; if (mmio) __ide_mm_insl((void __iomem *)data_addr, buf, words); else insl(data_addr, buf, words); if ((io_32bit & 2) && !mmio) local_irq_restore_nort(flags); if (((len + 1) & 3) < 2) return; buf += len & ~3; words = 1; } if (mmio) __ide_mm_insw((void __iomem *)data_addr, buf, words); else insw(data_addr, buf, words); }
//------------------------------------------------------------------------------------------------------------------------------- // // 检测硬盘存在函数 // //------------------------------------------------------------------------------------------------------------------------------- static int GetIDENum(void) { unsigned short buffer[256]; char *text; unsigned char c_disks; c_disks = ReadCmos(0x12); if (c_disks & 0xf0){ if (c_disks & 0x0f){ NR_HD_DEV = 2; } else{ NR_HD_DEV = 1; } } else{ NR_HD_DEV = 0; return 0; } outb(0xA0,0x1F6); // Get first/second drive outb(0xEC,0x1F7); // 获取驱动器信息数据 memset(HardDiskInfo, 0, sizeof(struct HardDiskStruct)); while (inb(HD_STATUS)&0x80); insw(0x1f0, buffer, 256); //将数据读到缓冲区 HardDiskInfo[0].sect = buffer[6]; HardDiskInfo[0].head = buffer[3]; HardDiskInfo[0].cyl = buffer[1]; text = (unsigned char*)&buffer[27]; SwapChar(text); strcpy(HardDiskName, text); HardDiskName[15]=0; return NR_HD_DEV; }
static void read_intr(void) { struct request *req; int i, retries = 100000; do { i = (unsigned) inb_p(HD_STATUS); if (i & BUSY_STAT) continue; if (!OK_STATUS(i)) break; if (i & DRQ_STAT) goto ok_to_read; } while (--retries > 0); dump_status("read_intr", i); bad_rw_intr(); hd_request(); return; ok_to_read: req = hd_req; insw(HD_DATA, req->buffer, 256); #ifdef DEBUG printk("%s: read: sector %ld, remaining = %u, buffer=%p\n", req->rq_disk->disk_name, blk_rq_pos(req) + 1, blk_rq_sectors(req) - 1, req->buffer+512); #endif if (hd_end_request(0, 512)) { SET_HANDLER(&read_intr); return; } (void) inb_p(HD_STATUS); #if (HD_DELAY > 0) last_req = read_timer(); #endif hd_request(); }
static void ioport_read16r(void __iomem *addr, void *dst, unsigned long count) { insw(ADDR2PORT(addr), dst, count); }
/* Use the ATA IDENTIFY command to find out what kind of drive is * attached to the given bus/slot. */ uint32 ata_identify (uint32 bus, uint32 drive) { uint8 status; uint16 buffer[256]; ata_drive_select (bus, drive); // while(!(status=inb(ATA_COMMAND(bus)) & 0x60)){ // rprintf("loop0"); // } outb (ATA_COMMAND (bus),0xEC); /* Send IDENTIFY command */ ATA_SELECT_DELAY (bus); status = inb (ATA_COMMAND (bus)); if (status == 0) { // rprintf ("ATA bus %X drive %X does not exist\n", bus, drive); return NOTCD; } if (status & 0x1) { /* Drive does not support IDENTIFY. Probably a CD-ROM. */ goto guess_identity; } /* Poll the Status port (0x1F7) until bit 7 (BSY, value = 0x80) * clears, and bit 3 (DRQ, value = 8) sets -- or until bit 0 (ERR, * value = 1) sets. */ while ((status = inb (ATA_COMMAND (bus))) & 0x80){ asm volatile ("pause"); // printf("%s\n","busy"); } /* BUSY */ while (!((status = inb (ATA_COMMAND (bus))) & 0x8) && !(status & 0x01)){ // printf("%x",status); asm volatile ("pause"); } if (status & 0x1) { // rprintf ("ATA bus %X drive %X caused error.\n", bus, drive); goto guess_identity; } /* Read 256 words */ insw (ATA_DATA (bus), buffer, 256); #ifdef DEBUG_ATA { int i, j; // DLOG ("IDENTIFY (bus: %X drive: %X) command output:", bus, drive); /* dump to com1 */ for (i = 0; i < 32; i++) { for (j = 0; j < 8; j++) { rprintf ("%.4X ", buffer[i * 32 + j]); } rprintf ("\n"); } } #endif if (buffer[83] & (1 << 10)) // rprintf ("LBA48 mode supported.\n"); // rprintf ("LBA48 addressable sectors: %.4X %.4X %.4X %.4X\n", // buffer[100], buffer[101], buffer[102], buffer[103]); rprintf("not a cd"); return NOTCD; guess_identity:{ uint8 b1, b2; b1 = inb (ATA_ADDRESS2 (bus)); b2 = inb (ATA_ADDRESS3 (bus)); // rprintf ("ata_detect: %.2X %.2X\n", b1, b2); if (b1 == 0x14 && b2 == 0xEB) { rprintf("is a CD"); // rprintf("P-ATAPI detected\n"); return ISCD; } //TODO: probar eliminar estos if (b1 == 0x69 && b2 == 0x96) { rprintf("is a CD"); // rprintf ("S-ATAPI detected\n"); return ISCD; } if (b1 == 0x3C && b2 == 0xC3) { rprintf("is a CD"); // rprintf ("SATA detected\n"); return ISCD; } rprintf("NOT a CD"); return NOTCD; } }
/* receive a single frame and assemble datagram * (this is the heart of the interrupt routine) */ static int sb1000_rx(struct net_device *dev) { #define FRAMESIZE 184 unsigned char st[2], buffer[FRAMESIZE], session_id, frame_id; short dlen; int ioaddr, ns; unsigned int skbsize; struct sk_buff *skb; struct sb1000_private *lp = netdev_priv(dev); struct net_device_stats *stats = &dev->stats; /* SB1000 frame constants */ const int FrameSize = FRAMESIZE; const int NewDatagramHeaderSkip = 8; const int NewDatagramHeaderSize = NewDatagramHeaderSkip + 18; const int NewDatagramDataSize = FrameSize - NewDatagramHeaderSize; const int ContDatagramHeaderSkip = 7; const int ContDatagramHeaderSize = ContDatagramHeaderSkip + 1; const int ContDatagramDataSize = FrameSize - ContDatagramHeaderSize; const int TrailerSize = 4; ioaddr = dev->base_addr; insw(ioaddr, (unsigned short*) st, 1); #ifdef XXXDEBUG printk("cm0: received: %02x %02x\n", st[0], st[1]); #endif /* XXXDEBUG */ lp->rx_frames++; /* decide if it is a good or bad frame */ for (ns = 0; ns < NPIDS; ns++) { session_id = lp->rx_session_id[ns]; frame_id = lp->rx_frame_id[ns]; if (st[0] == session_id) { if (st[1] == frame_id || (!frame_id && (st[1] & 0xf0) == 0x30)) { goto good_frame; } else if ((st[1] & 0xf0) == 0x30 && (st[0] & 0x40)) { goto skipped_frame; } else { goto bad_frame; } } else if (st[0] == (session_id | 0x40)) { if ((st[1] & 0xf0) == 0x30) { goto skipped_frame; } else { goto bad_frame; } } } goto bad_frame; skipped_frame: stats->rx_frame_errors++; skb = lp->rx_skb[ns]; if (sb1000_debug > 1) printk(KERN_WARNING "%s: missing frame(s): got %02x %02x " "expecting %02x %02x\n", dev->name, st[0], st[1], skb ? session_id : session_id | 0x40, frame_id); if (skb) { dev_kfree_skb(skb); skb = NULL; } good_frame: lp->rx_frame_id[ns] = 0x30 | ((st[1] + 1) & 0x0f); /* new datagram */ if (st[0] & 0x40) { /* get data length */ insw(ioaddr, buffer, NewDatagramHeaderSize / 2); #ifdef XXXDEBUG printk("cm0: IP identification: %02x%02x fragment offset: %02x%02x\n", buffer[30], buffer[31], buffer[32], buffer[33]); #endif /* XXXDEBUG */ if (buffer[0] != NewDatagramHeaderSkip) { if (sb1000_debug > 1) printk(KERN_WARNING "%s: new datagram header skip error: " "got %02x expecting %02x\n", dev->name, buffer[0], NewDatagramHeaderSkip); stats->rx_length_errors++; insw(ioaddr, buffer, NewDatagramDataSize / 2); goto bad_frame_next; } dlen = ((buffer[NewDatagramHeaderSkip + 3] & 0x0f) << 8 | buffer[NewDatagramHeaderSkip + 4]) - 17; if (dlen > SB1000_MRU) { if (sb1000_debug > 1) printk(KERN_WARNING "%s: datagram length (%d) greater " "than MRU (%d)\n", dev->name, dlen, SB1000_MRU); stats->rx_length_errors++; insw(ioaddr, buffer, NewDatagramDataSize / 2); goto bad_frame_next; } lp->rx_dlen[ns] = dlen; /* compute size to allocate for datagram */ skbsize = dlen + FrameSize; if ((skb = alloc_skb(skbsize, GFP_ATOMIC)) == NULL) { if (sb1000_debug > 1) printk(KERN_WARNING "%s: can't allocate %d bytes long " "skbuff\n", dev->name, skbsize); stats->rx_dropped++; insw(ioaddr, buffer, NewDatagramDataSize / 2); goto dropped_frame; } skb->dev = dev; skb_reset_mac_header(skb); skb->protocol = (unsigned short) buffer[NewDatagramHeaderSkip + 16]; insw(ioaddr, skb_put(skb, NewDatagramDataSize), NewDatagramDataSize / 2); lp->rx_skb[ns] = skb; } else { /* continuation of previous datagram */ insw(ioaddr, buffer, ContDatagramHeaderSize / 2); if (buffer[0] != ContDatagramHeaderSkip) { if (sb1000_debug > 1) printk(KERN_WARNING "%s: cont datagram header skip error: " "got %02x expecting %02x\n", dev->name, buffer[0], ContDatagramHeaderSkip); stats->rx_length_errors++; insw(ioaddr, buffer, ContDatagramDataSize / 2); goto bad_frame_next; } skb = lp->rx_skb[ns]; insw(ioaddr, skb_put(skb, ContDatagramDataSize), ContDatagramDataSize / 2); dlen = lp->rx_dlen[ns]; } if (skb->len < dlen + TrailerSize) { lp->rx_session_id[ns] &= ~0x40; return 0; } /* datagram completed: send to upper level */ skb_trim(skb, dlen); netif_rx(skb); stats->rx_bytes+=dlen; stats->rx_packets++; lp->rx_skb[ns] = NULL; lp->rx_session_id[ns] |= 0x40; return 0; bad_frame: insw(ioaddr, buffer, FrameSize / 2); if (sb1000_debug > 1) printk(KERN_WARNING "%s: frame error: got %02x %02x\n", dev->name, st[0], st[1]); stats->rx_frame_errors++; bad_frame_next: if (sb1000_debug > 2) sb1000_print_status_buffer(dev->name, st, buffer, FrameSize); dropped_frame: stats->rx_errors++; if (ns < NPIDS) { if ((skb = lp->rx_skb[ns])) { dev_kfree_skb(skb); lp->rx_skb[ns] = NULL; } lp->rx_session_id[ns] |= 0x40; } return -1; }
/************************************************************************** ETH_POLL - Wait for a frame ***************************************************************************/ int EtherReceive(char *pkt, int maxlen) { /* common variables */ int len; /* variables for 3C509 */ short status, cst; register short rx_fifo; cst = inw(BASE + EP_STATUS); #ifdef EDEBUG if (cst & 0x1FFF) printf("-%x-",cst); #endif if ((cst & (S_RX_COMPLETE|S_RX_EARLY)) == 0) { /* acknowledge everything */ outw(BASE + EP_COMMAND, ACK_INTR| (cst & S_5_INTS)); outw(BASE + EP_COMMAND, C_INTR_LATCH); return 0; } status = inw(BASE + EP_W1_RX_STATUS); #ifdef EDEBUG printf("*%x*",status); #endif if (status & ERR_RX) { outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK); return 0; } rx_fifo = status & RX_BYTES_MASK; if (rx_fifo == 0) return 0; if (rx_fifo > maxlen) goto zulang; /* read packet */ #ifdef EDEBUG printf("[l=%d",rx_fifo); #endif insw(BASE + EP_W1_RX_PIO_RD_1, pkt, rx_fifo / 2); if (rx_fifo & 1) pkt[rx_fifo-1] = inb(BASE + EP_W1_RX_PIO_RD_1); len = rx_fifo; for (;;) { status = inw(BASE + EP_W1_RX_STATUS); #ifdef EDEBUG printf("*%x*",status); #endif rx_fifo = status & RX_BYTES_MASK; if (rx_fifo > 0) { if ((len + rx_fifo) > maxlen) goto zulang; insw(BASE + EP_W1_RX_PIO_RD_1, pkt + len, rx_fifo / 2); if (rx_fifo & 1) pkt[len + rx_fifo-1] = inb(BASE + EP_W1_RX_PIO_RD_1); len += rx_fifo; #ifdef EDEBUG printf("+%d",rx_fifo); #endif } if ((status & RX_INCOMPLETE) == 0) { #ifdef EDEBUG printf("=%d",len); #endif break; } delay(1000); } /* acknowledge reception of packet */ outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK); while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS) continue; return len; zulang: outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK); while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS) continue; return 0; }
bool ATAManager::GetDeviceInformation(ushort controller, uchar device, DeviceInfo &devInfo) { AutoDisable lock; // disable ints uchar statusReg; MemSet(&devInfo, 0, sizeof(DeviceInfo)); // just zero it out // delay for 400ns ATADriver::Delay400ns(controller); // check the status register statusReg = inb(controller | ATADriver::ALT_STATUS_REG); // if we get 0xFF from the status register then no controller :-( if(statusReg == 0xFF) return false; // DEBUG("*** START (%x) ***\n", statusReg); // wait for the drive to not be busy do { statusReg = inb(controller | ATADriver::ALT_STATUS_REG); } while(statusReg & ATADriver::BUSY); // DEBUG("STATUS REG: %x\n", statusReg); asm("cli"); // clear interrupts // wait for the drive to be ready do { statusReg = inb(controller | ATADriver::ALT_STATUS_REG); } while(!(statusReg & ATADriver::DRIVE_READY)); // DEBUG("STATUS REG: %x\n", statusReg); // select the device outb(controller | ATADriver::DRIVE_HEAD_REG, device); // send the "IDENTIFY DRIVE" command outb(controller | ATADriver::COMMAND_REG, ATADriver::IDENT_DEV); asm("sti"); // enable interrupts // DEBUG("SENT COMMAND\n"); // INT HAPPENS HERE // wait for the driver to not be busy do { statusReg = inb(controller | ATADriver::ALT_STATUS_REG); } while(statusReg & ATADriver::BUSY); // DEBUG("STATUS REG: %x\n", statusReg); asm("cli"); // clear interrupts // poll to see if the drive is ready do { statusReg = inb(controller | ATADriver::ALT_STATUS_REG); } while(!(statusReg & ATADriver::DRIVE_READY) && (statusReg & ATADriver::DATA_READY)); // DEBUG("STATUS REG: %x\n", statusReg); ushort tmpBuf[256]; // getting an error probably means we're dealing with ATAPI if(statusReg & ATADriver::ERROR) { // DEBUG("GOT AN ERROR\n"); uchar cl, ch; // read in cylinder high & low to check for ATAPI cl = inb(controller | ATADriver::CYLINDER_LOW_REG); ch = inb(controller | ATADriver::CYLINDER_HIGH_REG); // DEBUG("LOW 0x%x == 0x14 && HIGH 0x%x == 0xeb\n", cl, ch); if(cl == 0x14 && ch == 0xeb) // we have a packet device { // perform a software reset ATADriver::ResetController(controller); } else // some other error PANIC("Unknown error identifying drives", false); // // Reset this device // // wait for the drive to not be busy /* do { statusReg = inb(controller | ATADriver::ALT_STATUS_REG); } while(statusReg & ATADriver::BUSY); asm("cli"); // wait for the drive to be ready do { statusReg = inb(controller | ATADriver::ALT_STATUS_REG); } while(!(statusReg & ATADriver::DRIVE_READY)); // select the device outb(controller | ATADriver::DRIVE_HEAD_REG, device); // send the "RESET DEVICE" command outb(controller | ATADriver::COMMAND_REG, ATADriver::RESET_DEVICE); asm("sti"); // wait for the drive to not be busy do { statusReg = inb(controller | ATADriver::ALT_STATUS_REG); } while(statusReg & ATADriver::BUSY); statusReg = inb(controller | ATADriver::STATUS_REG); printf("STATUS: %x\n", statusReg); */ return(false); } // DEBUG("READING DATA\n"); // it is 256 words (ushort) or 512 bytes (uchar) insw(controller | ATADriver::DATA_REG, tmpBuf, 256); // read the primary status register once inb(controller | ATADriver::STATUS_REG); // fill in the info for the drive devInfo.ATAPI_dev = tmpBuf[0] & 0x8000; devInfo.numLogCylinders = tmpBuf[1]; devInfo.numLogHeads = tmpBuf[3]; devInfo.numSecPreTrack = tmpBuf[6]; MemCopy(devInfo.serialNumber, &tmpBuf[10], sizeof(devInfo.serialNumber)); MemCopy(devInfo.firmwareVersion, &tmpBuf[23], sizeof(devInfo.firmwareVersion)); MemCopy(devInfo.modelNumber, &tmpBuf[27], sizeof(devInfo.modelNumber)); // need to byte swap the model number ByteSwap(devInfo.modelNumber, sizeof(devInfo.modelNumber)); devInfo.maxSectorsForMultiple = tmpBuf[47] & 0x00FF; devInfo.numCurLogCylinders = tmpBuf[54]; devInfo.numCurLogHeads = tmpBuf[55]; devInfo.numCurLogSectorsPerTrack = tmpBuf[56]; MemCopy(&devInfo.curCapacityInSectors, &tmpBuf[57], sizeof(devInfo.curCapacityInSectors)); devInfo.curNumSectorsForMultiple = tmpBuf[59] & 0x00FF; MemCopy(&devInfo.totalAddressableSectors, &tmpBuf[60], sizeof(devInfo.totalAddressableSectors)); devInfo.ATAVersion = tmpBuf[80]; return(true); }
static void el2_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { int boguscount = 0; void __iomem *base = ei_status.mem; unsigned short int *buf; unsigned short word; /* Maybe enable shared memory just be to be safe... nahh.*/ if (base) { /* Use the shared memory. */ ring_offset -= (EL2_MB1_START_PG<<8); if (ring_offset + count > EL2_MEMSIZE) { /* We must wrap the input move. */ int semi_count = EL2_MEMSIZE - ring_offset; memcpy_fromio(skb->data, base + ring_offset, semi_count); count -= semi_count; memcpy_fromio(skb->data + semi_count, base + ei_status.priv, count); } else { memcpy_fromio(skb->data, base + ring_offset, count); } return; } /* * No shared memory, use programmed I/O. */ word = (unsigned short) ring_offset; outb(word>>8, E33G_DMAAH); outb(word&0xFF, E33G_DMAAL); outb_p((ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI) | ECNTRL_INPUT | ECNTRL_START, E33G_CNTRL); /* * Here I also try to get data as fast as possible. I am betting that I * can read one extra byte without clobbering anything in the kernel because * this would only occur on an odd byte-count and allocation of skb->data * is word-aligned. Variable 'count' is NOT checked. Caller must check * for a valid count. * [This is currently quite safe.... but if one day the 3c503 explodes * you know where to come looking ;)] */ buf = (unsigned short int *) skb->data; count = (count + 1) >> 1; for(;;) { boguscount = 0x1000; while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0) { if(!boguscount--) { printk("%s: FIFO blocked in el2_block_input.\n", dev->name); el2_reset_8390(dev); goto blocked; } } if(count > WRD_COUNT) { insw(E33G_FIFOH, buf, WRD_COUNT); buf += WRD_COUNT; count -= WRD_COUNT; } else { insw(E33G_FIFOH, buf, count); break; } } blocked:; outb_p(ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL); return; }
/************************************************************************** ETH_POLL - Wait for a frame ***************************************************************************/ static int t595_poll(struct nic *nic, int retrieve) { /* common variables */ /* variables for 3C595 */ short status, cst; register short rx_fifo; cst=inw(BASE + VX_STATUS); #ifdef EDEBUG if(cst & 0x1FFF) printf("-%hX-",cst); #endif if( (cst & S_RX_COMPLETE)==0 ) { /* acknowledge everything */ outw(ACK_INTR | cst, BASE + VX_COMMAND); outw(C_INTR_LATCH, BASE + VX_COMMAND); return 0; } status = inw(BASE + VX_W1_RX_STATUS); #ifdef EDEBUG printf("*%hX*",status); #endif if (status & ERR_RX) { outw(RX_DISCARD_TOP_PACK, BASE + VX_COMMAND); return 0; } rx_fifo = status & RX_BYTES_MASK; if (rx_fifo==0) return 0; if ( ! retrieve ) return 1; /* read packet */ #ifdef EDEBUG printf("[l=%d",rx_fifo); #endif insw(BASE + VX_W1_RX_PIO_RD_1, nic->packet, rx_fifo / 2); if(rx_fifo & 1) nic->packet[rx_fifo-1]=inb(BASE + VX_W1_RX_PIO_RD_1); nic->packetlen=rx_fifo; while(1) { status = inw(BASE + VX_W1_RX_STATUS); #ifdef EDEBUG printf("*%hX*",status); #endif rx_fifo = status & RX_BYTES_MASK; if(rx_fifo>0) { insw(BASE + VX_W1_RX_PIO_RD_1, nic->packet+nic->packetlen, rx_fifo / 2); if(rx_fifo & 1) nic->packet[nic->packetlen+rx_fifo-1]=inb(BASE + VX_W1_RX_PIO_RD_1); nic->packetlen+=rx_fifo; #ifdef EDEBUG printf("+%d",rx_fifo); #endif } if(( status & RX_INCOMPLETE )==0) { #ifdef EDEBUG printf("=%d",nic->packetlen); #endif break; } udelay(1000); } /* acknowledge reception of packet */ outw(RX_DISCARD_TOP_PACK, BASE + VX_COMMAND); while (inw(BASE + VX_STATUS) & S_COMMAND_IN_PROGRESS); #ifdef EDEBUG { unsigned short type = 0; /* used by EDEBUG */ type = (nic->packet[12]<<8) | nic->packet[13]; if(nic->packet[0]+nic->packet[1]+nic->packet[2]+nic->packet[3]+nic->packet[4]+ nic->packet[5] == 0xFF*ETH_ALEN) printf(",t=%hX,b]",type); else printf(",t=%hX]",type); } #endif return 1; }
wstdcall void WRAP_EXPORT(READ_PORT_BUFFER_USHORT) (ULONG_PTR port, USHORT *buf, ULONG count) { insw(port, buf, count); }
__weak void ide_input_data_shorts(int dev, ushort *sect_buf, int shorts) { insw(ATA_CURR_BASE(dev) + ATA_DATA_REG, sect_buf, shorts); }
static void epread(struct ep_softc *sc) { struct mbuf *top, *mcur, *m; struct ifnet *ifp; int lenthisone; short rx_fifo2, status; short rx_fifo; ifp = &sc->arpcom.ac_if; status = inw(BASE + EP_W1_RX_STATUS); read_again: if (status & ERR_RX) { IFNET_STAT_INC(ifp, ierrors, 1); if (status & ERR_RX_OVERRUN) { /* * we can think the rx latency is actually greather than we * expect */ #ifdef EP_LOCAL_STATS if (EP_FTST(sc, F_RX_FIRST)) sc->rx_overrunf++; else sc->rx_overrunl++; #endif } goto out; } rx_fifo = rx_fifo2 = status & RX_BYTES_MASK; if (EP_FTST(sc, F_RX_FIRST)) { m = m_getl(rx_fifo, MB_DONTWAIT, MT_DATA, M_PKTHDR, NULL); if (!m) goto out; sc->top = sc->mcur = top = m; #define EROUND ((sizeof(struct ether_header) + 3) & ~3) #define EOFF (EROUND - sizeof(struct ether_header)) top->m_data += EOFF; /* Read what should be the header. */ insw(BASE + EP_W1_RX_PIO_RD_1, mtod(top, caddr_t), sizeof(struct ether_header) / 2); top->m_len = sizeof(struct ether_header); rx_fifo -= sizeof(struct ether_header); sc->cur_len = rx_fifo2; } else { /* come here if we didn't have a complete packet last time */ top = sc->top; m = sc->mcur; sc->cur_len += rx_fifo2; } /* Reads what is left in the RX FIFO */ while (rx_fifo > 0) { lenthisone = min(rx_fifo, M_TRAILINGSPACE(m)); if (lenthisone == 0) { /* no room in this one */ mcur = m; m = m_getl(rx_fifo, MB_DONTWAIT, MT_DATA, 0, NULL); if (!m) goto out; m->m_len = 0; mcur->m_next = m; lenthisone = min(rx_fifo, M_TRAILINGSPACE(m)); } if (EP_FTST(sc, F_ACCESS_32_BITS)) { /* default for EISA configured cards*/ insl(BASE + EP_W1_RX_PIO_RD_1, mtod(m, caddr_t) + m->m_len, lenthisone / 4); m->m_len += (lenthisone & ~3); if (lenthisone & 3) insb(BASE + EP_W1_RX_PIO_RD_1, mtod(m, caddr_t) + m->m_len, lenthisone & 3); m->m_len += (lenthisone & 3); } else { insw(BASE + EP_W1_RX_PIO_RD_1, mtod(m, caddr_t) + m->m_len, lenthisone / 2); m->m_len += lenthisone; if (lenthisone & 1) *(mtod(m, caddr_t) + m->m_len - 1) = inb(BASE + EP_W1_RX_PIO_RD_1); } rx_fifo -= lenthisone; } if (status & ERR_RX_INCOMPLETE) { /* we haven't received the complete * packet */ sc->mcur = m; #ifdef EP_LOCAL_STATS sc->rx_no_first++; /* to know how often we come here */ #endif EP_FRST(sc, F_RX_FIRST); if (!((status = inw(BASE + EP_W1_RX_STATUS)) & ERR_RX_INCOMPLETE)) { /* we see if by now, the packet has completly arrived */ goto read_again; } outw(BASE + EP_COMMAND, SET_RX_EARLY_THRESH | RX_NEXT_EARLY_THRESH); return; } outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK); IFNET_STAT_INC(ifp, ipackets, 1); EP_FSET(sc, F_RX_FIRST); top->m_pkthdr.rcvif = &sc->arpcom.ac_if; top->m_pkthdr.len = sc->cur_len; ifp->if_input(ifp, top); sc->top = 0; while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS); outw(BASE + EP_COMMAND, SET_RX_EARLY_THRESH | RX_INIT_EARLY_THRESH); return; out: outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK); if (sc->top) { m_freem(sc->top); sc->top = 0; #ifdef EP_LOCAL_STATS sc->rx_no_mbuf++; #endif } EP_FSET(sc, F_RX_FIRST); while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS); outw(BASE + EP_COMMAND, SET_RX_EARLY_THRESH | RX_INIT_EARLY_THRESH); }
void os_insw (void *port, HPT_U16 *buffer, HPT_U32 count) { insw((unsigned)(HPT_UPTR)port, (void *)buffer, count); }
void eata_pio_int_handler(int irq, void *dev_id, struct pt_regs * regs) { uint eata_stat = 0xfffff; Scsi_Cmnd *cmd; hostdata *hd; struct eata_ccb *cp; uint base; ulong flags; uint x,z; struct Scsi_Host *sh; ushort zwickel=0; unchar stat,odd; save_flags(flags); cli(); for (x = 1, sh = first_HBA; x <= registered_HBAs; x++, sh = SD(sh)->prev) { if (sh->irq != irq) continue; if (inb((uint)sh->base + HA_RSTATUS) & HA_SBUSY) continue; int_counter++; hd=SD(sh); cp = &hd->ccb[0]; cmd = cp->cmd; base = (uint) cmd->host->base; do { stat=inb(base+HA_RSTATUS); if (stat&HA_SDRQ) { if (cp->DataIn) { z=256; odd=FALSE; while ((cmd->SCp.Status)&&((z>0)||(odd))) { if (odd) { *(cmd->SCp.ptr)=zwickel>>8; IncStat(&cmd->SCp,1); odd=FALSE; } x=min(z,cmd->SCp.this_residual/2); insw(base+HA_RDATA,cmd->SCp.ptr,x); z-=x; IncStat(&cmd->SCp,2*x); if ((z>0)&&(cmd->SCp.this_residual==1)) { zwickel=inw(base+HA_RDATA); *(cmd->SCp.ptr)=zwickel&0xff; IncStat(&cmd->SCp,1); z--; odd=TRUE; } } while (z>0) { zwickel=inw(base+HA_RDATA); z--; } } else /* cp->DataOut */ { odd=FALSE; z=256; while ((cmd->SCp.Status)&&((z>0)||(odd))) { if (odd) { zwickel+=*(cmd->SCp.ptr)<<8; IncStat(&cmd->SCp,1); outw(zwickel,base+HA_RDATA); z--; odd=FALSE; } x=min(z,cmd->SCp.this_residual/2); outsw(base+HA_RDATA,cmd->SCp.ptr,x); z-=x; IncStat(&cmd->SCp,2*x); if ((z>0)&&(cmd->SCp.this_residual==1)) { zwickel=*(cmd->SCp.ptr); zwickel&=0xff; IncStat(&cmd->SCp,1); odd=TRUE; } } while (z>0||odd) { outw(zwickel,base+HA_RDATA); z--; odd=FALSE; } } } }
static void ide_insw (unsigned long port, void *addr, u32 count) { return insw(port, addr, count); }
static inline void cirrus_frame_read (struct net_device *dev,struct sk_buff *skb,u16 length) { insw (dev->base_addr,skb_put (skb,length),(length + 1) / 2); }
static irqreturn_t eata_pio_int_handler(int irq, void *dev_id) { unsigned int eata_stat = 0xfffff; struct scsi_cmnd *cmd; hostdata *hd; struct eata_ccb *cp; unsigned long base; unsigned int x, z; struct Scsi_Host *sh; unsigned short zwickel = 0; unsigned char stat, odd; irqreturn_t ret = IRQ_NONE; for (x = 1, sh = first_HBA; x <= registered_HBAs; x++, sh = SD(sh)->prev) { if (sh->irq != irq) continue; if (inb(sh->base + HA_RSTATUS) & HA_SBUSY) continue; int_counter++; ret = IRQ_HANDLED; hd = SD(sh); cp = &hd->ccb[0]; cmd = cp->cmd; base = cmd->device->host->base; do { stat = inb(base + HA_RSTATUS); if (stat & HA_SDRQ) { if (cp->DataIn) { z = 256; odd = 0; while ((cmd->SCp.Status) && ((z > 0) || (odd))) { if (odd) { *(cmd->SCp.ptr) = zwickel >> 8; IncStat(&cmd->SCp, 1); odd = 0; } x = min_t(unsigned int, z, cmd->SCp.this_residual / 2); insw(base + HA_RDATA, cmd->SCp.ptr, x); z -= x; IncStat(&cmd->SCp, 2 * x); if ((z > 0) && (cmd->SCp.this_residual == 1)) { zwickel = inw(base + HA_RDATA); *(cmd->SCp.ptr) = zwickel & 0xff; IncStat(&cmd->SCp, 1); z--; odd = 1; } } while (z > 0) { zwickel = inw(base + HA_RDATA); z--; } } else { /* cp->DataOut */ odd = 0; z = 256; while ((cmd->SCp.Status) && ((z > 0) || (odd))) { if (odd) { zwickel += *(cmd->SCp.ptr) << 8; IncStat(&cmd->SCp, 1); outw(zwickel, base + HA_RDATA); z--; odd = 0; } x = min_t(unsigned int, z, cmd->SCp.this_residual / 2); outsw(base + HA_RDATA, cmd->SCp.ptr, x); z -= x; IncStat(&cmd->SCp, 2 * x); if ((z > 0) && (cmd->SCp.this_residual == 1)) { zwickel = *(cmd->SCp.ptr); zwickel &= 0xff; IncStat(&cmd->SCp, 1); odd = 1; } } while (z > 0 || odd) { outw(zwickel, base + HA_RDATA); z--; odd = 0; } } } }
uint8_t identify() { inb(ATA_PRIMARY_COMM_REGSTAT); outb(ATA_PRIMARY_DRIVE_HEAD, 0xA0); inb(ATA_PRIMARY_COMM_REGSTAT); outb(ATA_PRIMARY_SECCOUNT, 0); inb(ATA_PRIMARY_COMM_REGSTAT); outb(ATA_PRIMARY_LBA_LO, 0); inb(ATA_PRIMARY_COMM_REGSTAT); outb(ATA_PRIMARY_LBA_MID, 0); inb(ATA_PRIMARY_COMM_REGSTAT); outb(ATA_PRIMARY_LBA_HI, 0); inb(ATA_PRIMARY_COMM_REGSTAT); outb(ATA_PRIMARY_COMM_REGSTAT, 0xEC); outb(ATA_PRIMARY_COMM_REGSTAT, 0xE7); // Read the status port. If it's zero, the drive does not exist. uint8_t status = inb(ATA_PRIMARY_COMM_REGSTAT); printf("Waiting for status.\n"); while(status & STAT_BSY) { uint32_t i = 0; while(1) { printf("Printing stuff %d\n", i); i++; } for(i = 0; i < 0x0FFFFFFF; i++) {} printf("Checking regstat.\n"); status = inb(ATA_PRIMARY_COMM_REGSTAT); } if(status == 0) return 0; printf("Status indicates presence of a drive. Polling while STAT_BSY... "); while(status & STAT_BSY) { printf("\ninb(ATA_PRIMARY_COMM_REGSTAT);... "); status = inb(ATA_PRIMARY_COMM_REGSTAT); } printf("Done.\n"); uint8_t mid = inb(ATA_PRIMARY_LBA_MID); uint8_t hi = inb(ATA_PRIMARY_LBA_HI); if(mid || hi) { // The drive is not ATA. (Who knows what it is.) return 0; } printf("Waiting for ERR or DRQ.\n"); // Wait for ERR or DRQ while(!(status & (STAT_ERR | STAT_DRQ))) { status = inb(ATA_PRIMARY_COMM_REGSTAT); } if(status & STAT_ERR) { // There was an error on the drive. Forget about it. return 0; } printf("Reading IDENTIFY structure.\n"); //uint8_t *buff = kmalloc(40960, 0, NULL); uint8_t buff[256 * 2]; insw(ATA_PRIMARY_DATA, buff, 256); printf("Success. Disk is ready to go.\n"); // We read it! return 1; }