diff --git a/ChangeLog b/ChangeLog index dad635729..b0227a679 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,33 @@ +2000-02-21 OKUJI Yoshinori + + * stage2/disk_io.c (check_BSD_parts) [!STAGE1_5]: If the BSD + label is invalid, print a message with the partition type in the + case where FLAGS is non-zero and DO_COMPLETION is zero. + +2000-02-20 OKUJI Yoshinori + + * docs/user-ref.texi (Command-line-specific commands): Added a + description about "cmp". + * docs/appendices.texi (Reporting bugs): Rewritten. + +2000-02-20 OKUJI Yoshinori + + Update the netboot code to Etherboot 4.4.3. + + * netboot/netboot_config.h: Copied from etherboot-4.4.3. + * netboot/cs89x0.h: Likewise. + * netboot/cs89x0.c: Likewise. + * netboot/i82586.c: Likewise. + * netboot/lance.c: Likewise. + * netboot/linux-asm-string.h: Likewise. + * netboot/nic.h: Likewise. + * netboot/ntulip.c: Likewise. + * netboot/osdep.h: Likewise. + * netboot/pci.h: Likewise. + * netboot/pci.c: Likewise. + * netboot/rtl8139.c: Likewise. + * netboot/tiara.c: Likewise. + 2000-02-19 OKUJI Yoshinori * stage2/builtins.c (cmp_func): New function. diff --git a/NEWS b/NEWS index 1c617700b..6dd3bf8ac 100644 --- a/NEWS +++ b/NEWS @@ -30,7 +30,7 @@ New in 0.5.94: * The command "chainloader" now accepts an option "--force", which is required if you want to chain-load a boot loader defective in the signature, such as SCO Unixware 7.1. -* The netboot support is heavily rewritten, based on Etherboot-4.4.2. +* The netboot support is heavily rewritten, based on Etherboot-4.4.3. Most of the device drivers are stolen from it, so we now have many network drivers. See netboot/README.netboot for more details. * Now configure accepts the option `--disable-lba-support-bitmap-check' diff --git a/docs/appendices.texi b/docs/appendices.texi index 298aa505d..68d640746 100644 --- a/docs/appendices.texi +++ b/docs/appendices.texi @@ -215,9 +215,35 @@ for more information. When you encounter any problem or bug, please submit it to @email{bug-grub@@gnu.org} with information about your computer and what -you did @emph{as much as possible}. For example, your operating system, -the geometries of your drives and the version of GRUB are very -important. +you did @emph{as much as possible}. Take a look at this list before you +send e-mail to the address: + +@itemize @bullet +@item +Write what you did and what messages were printed on the screen in +detail. Don't paraphrase them. Please describe them as they were. + +@item +Explain what you wanted to do. It is very useful to know your purpose +and your wish, and how GRUB didn't satisfy you. + +@item +Inform us of the information about your GRUB. What version were you +using? Which were you using the grub shell or the boot images? If using +the grub shell, tell us what operating system was used to run it. And, +if you ran @command{configure} with some options when building GRUB, it +would be a good thing to let us know how to build it. + +@item +The information on your hardware is also essential. These are especially +important: the geometries and the partition tables of your hard disk +drives and your BIOS. + +@item +Write down anything that you think might be related. If you are not sure +whether to state a fact or leave it out, state it! Reporting too many +things is quite better than omitting an important thing. +@end itemize @node Index diff --git a/docs/user-ref.texi b/docs/user-ref.texi index bc2f288f5..3131fc908 100644 --- a/docs/user-ref.texi +++ b/docs/user-ref.texi @@ -780,6 +780,24 @@ correct signature or not. This is required when you want to load a defective boot loader, such as SCO Unixware 7.1. @end deffn +@deffn Command cmp file1 file2 +Compare the file @var{file1} with the file @var{file2}. If they differ +in size, print the sizes like this: + +@example +Differ in size: 0x1234 [foo], 0x4321 [bar] +@end example + +If the sizes are equal but the bytes at an offset differ, then print the +bytes like this: + +@example +Differ at the offset 777: 0xbe [foo], 0xef [bar] +@end example + +If they are complete identical, nothing will be printed. +@end deffn + @deffn Command configfile @var{file} Load @var{file} as the configuration file. @end deffn diff --git a/netboot/cs89x0.c b/netboot/cs89x0.c index 1f4d312ac..ab13e8335 100644 --- a/netboot/cs89x0.c +++ b/netboot/cs89x0.c @@ -1,25 +1,10 @@ /* cs89x0.c: A Crystal Semiconductor CS89[02]0 driver for etherboot. */ /* - This code is heavily based on the linux driver as written by - Russell Nelson and Donald Becker - and modified by Mike Cruse - . That driver has been released under the - conditions of the GNU Public License, thus this one is probably to - be considered "derived work". Therefore, there are some legal - obstacles in combining this file with etherboot's code, which is - released under a BSD style license. - - So, if you want to actually use this code, you should make sure that - you are aware of the legal implications. I release *my* work into - the PUBLIC DOMAIN which implies that you can use it either under a - BSD style license, or under the conditions of the GPL, or under any - other conditions that you like. N.B. this does not apply to the - parts that originate from other authors. So, you should probably - contact them first and verify if they agree with your intended use. - - If you contacted all of the above authors and they agreed to give - special permission for using this code under the conditions of a BSD - style license, then please do let me know. + Permission is granted to distribute the enclosed cs89x0.[ch] driver + only in conjunction with the Etherboot package. The code is + ordinarily distributed under the GPL. + + Russ Nelson, January 2000 ChangeLog: diff --git a/netboot/cs89x0.h b/netboot/cs89x0.h index ec638659a..1b105bc4d 100644 --- a/netboot/cs89x0.h +++ b/netboot/cs89x0.h @@ -1,7 +1,3 @@ -/* This file has been copied from Russel Nelson's device driver for - Linux. Please look into the header of cs89x0.c for details on the - legal implications! */ - /* Copyright, 1988-1992, Russell Nelson, Crynwr Software This program is free software; you can redistribute it and/or modify diff --git a/netboot/i82586.c b/netboot/i82586.c index c7cb41579..e50865644 100644 --- a/netboot/i82586.c +++ b/netboot/i82586.c @@ -4,6 +4,13 @@ i82586 NIC driver for Etherboot Ken Yap, January 1998 ***************************************************************************/ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2, or (at + * your option) any later version. + */ + /* to get some global routines like printf */ #include "etherboot.h" /* to get the interface to the body of the program */ @@ -236,7 +243,6 @@ static unsigned short init_words[] = { static unsigned short ioaddr, irq, scb_base; static Address mem_start, mem_end; -static char if_port; static unsigned short rx_head, rx_tail; #define read_mem(m,s) fmemcpy((char *)s, m, sizeof(s)) @@ -330,7 +336,7 @@ RESET - Reset adapter static void i82586_reset(struct nic *nic) { - int boguscnt; + long time; #ifdef ETHERBOOT32 unsigned short *shmem = (short *)mem_start; #endif @@ -373,14 +379,14 @@ static void i82586_reset(struct nic *nic) /* This was time consuming to track down; you need to give two channel attention signals to reliably start up the i82586. */ outb(0, ioaddr + I82586_ATTN); - boguscnt = 10000; + time = currticks() + TICKS_PER_SEC; /* allow 1 second to init */ while ( #ifdef ETHERBOOT16 read_mem(mem_start, shmem), #endif shmem[iSCB_STATUS>>1] == 0) { - if (--boguscnt == 0) + if (currticks() > time) { printf("i82586 initialisation timed out with status %x, cmd %x\n", shmem[iSCB_STATUS>>1], shmem[iSCB_CMD>>1]); @@ -592,6 +598,7 @@ static int t507_probe1(struct nic *nic, unsigned short ioaddr) int i; Address size; char mem_config; + char if_port; if (inb(ioaddr) != '*' || inb(ioaddr+1) != '3' || inb(ioaddr+2) != 'C' || inb(ioaddr+3) != 'O') @@ -606,7 +613,7 @@ static int t507_probe1(struct nic *nic, unsigned short ioaddr) } else { - size = ((((Address)mem_config & 0x3) + 1) << 14) & 0xffffL; + size = ((((Address)mem_config & 0x3) + 1) << 14); mem_start = 0x0c0000L + (((Address)mem_config & 0x18) << 12); } mem_end = mem_start + size; diff --git a/netboot/lance.c b/netboot/lance.c index 559c1eab1..4d5f8c856 100644 --- a/netboot/lance.c +++ b/netboot/lance.c @@ -5,6 +5,13 @@ Large portions borrowed from the Linux LANCE driver by Donald Becker Ken Yap, July 1997 ***************************************************************************/ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2, or (at + * your option) any later version. + */ + /* to get some global routines like printf */ #include "etherboot.h" /* to get the interface to the body of the program */ diff --git a/netboot/linux-asm-string.h b/netboot/linux-asm-string.h index 84268a5ec..02f0c1c5d 100644 --- a/netboot/linux-asm-string.h +++ b/netboot/linux-asm-string.h @@ -19,7 +19,9 @@ * consider these trivial functions to be PD. */ +#ifndef __FreeBSD__ typedef int size_t; +#endif extern inline void * __memcpy(void * to, const void * from, size_t n) { diff --git a/netboot/netboot_config.h b/netboot/netboot_config.h index eaf284d15..e98e1f93d 100644 --- a/netboot/netboot_config.h +++ b/netboot/netboot_config.h @@ -1,3 +1,10 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2, or (at + * your option) any later version. + */ + extern struct nic nic; extern void print_config(void); diff --git a/netboot/nic.h b/netboot/nic.h index 0e09d1098..df82daba5 100644 --- a/netboot/nic.h +++ b/netboot/nic.h @@ -1,3 +1,10 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2, or (at + * your option) any later version. + */ + /* * Structure returned from eth_probe and passed to other driver * functions. diff --git a/netboot/ntulip.c b/netboot/ntulip.c index cecbe065c..58c2a7180 100644 --- a/netboot/ntulip.c +++ b/netboot/ntulip.c @@ -77,6 +77,10 @@ enum ntulip_offsets { CSR12=0x60, CSR13=0x68, CSR14=0x70, CSR15=0x78, CSR16=0x80, CSR20=0xA0 }; +#define DEC_21142_CSR6_TTM 0x00400000 /* Transmit Threshold Mode */ +#define DEC_21142_CSR6_HBD 0x00080000 /* Heartbeat Disable */ +#define DEC_21142_CSR6_PS 0x00040000 /* Port Select */ + /* EEPROM Address width definitions */ #define EEPROM_ADDRLEN 6 #define EEPROM_SIZE 128 /* 2 << EEPROM_ADDRLEN */ @@ -423,6 +427,18 @@ static void ntulip_reset(struct nic *nic) csr6 = 0x814C0000; outl(0x00000001, ioaddr + CSR15); + } else if (vendor == PCI_VENDOR_ID_DEC && dev_id == PCI_DEVICE_ID_DEC_21142) { + /* check SROM for evidence of an MII interface */ + /* get Controller_0 Info Leaf Offset from SROM - assume already in ee_data */ + int offset = ee_data [27] + (ee_data [28] << 8); + + /* check offset range and if we have an extended type 3 Info Block */ + if ((offset >= 30) && (offset < 120) && (ee_data [offset + 3] > 128) && + (ee_data [offset + 4] == 3)) { + /* must have an MII interface - disable heartbeat, select port etc. */ + csr6 |= (DEC_21142_CSR6_HBD | DEC_21142_CSR6_PS); + csr6 &= ~(DEC_21142_CSR6_TTM); + } } /* Start the chip's Tx to process setup frame. */ @@ -558,12 +574,7 @@ struct nic *ntulip_probe(struct nic *nic, unsigned short *io_addrs, nic->node_addr[i*2] = (u8)((value >> 8) & 0xff); nic->node_addr[i*2 + 1] = (u8)( value & 0xff); } - printf("NTulip %b:%b:%b:%b:%b:%b at ioaddr 0x%x\n", - nic->node_addr[0],nic->node_addr[1],nic->node_addr[2],nic->node_addr[3], - nic->node_addr[4],nic->node_addr[5],ioaddr); - } else { - /* read EEPROM data */ for (i = 0; i < sizeof(ee_data)/2; i++) ((unsigned short *)ee_data)[i] = @@ -572,12 +583,12 @@ struct nic *ntulip_probe(struct nic *nic, unsigned short *io_addrs, /* extract MAC address from EEPROM buffer */ for (i=0; i<6; i++) nic->node_addr[i] = ee_data[20+i]; - - printf("NTulip %b:%b:%b:%b:%b:%b at ioaddr 0x%x\n", - nic->node_addr[0],nic->node_addr[1],nic->node_addr[2],nic->node_addr[3], - nic->node_addr[4],nic->node_addr[5],ioaddr); } + printf("NTulip %b:%b:%b:%b:%b:%b at ioaddr 0x%x\n", + nic->node_addr[0],nic->node_addr[1],nic->node_addr[2],nic->node_addr[3], + nic->node_addr[4],nic->node_addr[5],ioaddr); + /* initialize device */ ntulip_reset(nic); diff --git a/netboot/osdep.h b/netboot/osdep.h index df491ed1d..7dda46371 100644 --- a/netboot/osdep.h +++ b/netboot/osdep.h @@ -1,6 +1,13 @@ #ifndef __OSDEP_H__ #define __OSDEP_H__ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2, or (at + * your option) any later version. + */ + #if 1 # define ETHERBOOT32 # include diff --git a/netboot/pci.c b/netboot/pci.c index 858da3f2f..f82235ff4 100644 --- a/netboot/pci.c +++ b/netboot/pci.c @@ -14,6 +14,13 @@ ** a multi-pcibus machine will have something better than an ne2000) */ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2, or (at + * your option) any later version. + */ + #include "etherboot.h" #include "pci.h" diff --git a/netboot/pci.h b/netboot/pci.h index 4306502aa..911235e35 100644 --- a/netboot/pci.h +++ b/netboot/pci.h @@ -11,6 +11,13 @@ ** /usr/src/linux/drivers/net/ne.c */ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2, or (at + * your option) any later version. + */ + #define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */ #define PCI_COMMAND_MASTER 0x4 /* Enable bus mastering */ #define PCI_LATENCY_TIMER 0x0d /* 8 bits */ @@ -96,17 +103,11 @@ __asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory") #define PCI_VENDOR_ID_NETVIN 0x4a14 #define PCI_DEVICE_ID_NETVIN_NV5000SC 0x5000 #define PCI_VENDOR_ID_3COM 0x10b7 -#define PCI_DEVICE_ID_3COM_3C985 0x0001 -#define PCI_DEVICE_ID_3COM_3C339 0x3390 -#define PCI_DEVICE_ID_3COM_3C590 0x5900 -#define PCI_DEVICE_ID_3COM_3C595TX 0x5950 -#define PCI_DEVICE_ID_3COM_3C595T4 0x5951 -#define PCI_DEVICE_ID_3COM_3C595MII 0x5952 -#define PCI_DEVICE_ID_3COM_3C900TPO 0x9000 -#define PCI_DEVICE_ID_3COM_3C900COMBO 0x9001 -#define PCI_DEVICE_ID_3COM_3C905TX 0x9050 -#define PCI_DEVICE_ID_3COM_3C905T4 0x9051 -#define PCI_DEVICE_ID_3COM_3C905B_TX 0x9055 +#define PCI_DEVICE_ID_3COM_3C900TPO 0x9000 +#define PCI_DEVICE_ID_3COM_3C900COMBO 0x9001 +#define PCI_DEVICE_ID_3COM_3C905TX 0x9050 +#define PCI_DEVICE_ID_3COM_3C905T4 0x9051 +#define PCI_DEVICE_ID_3COM_3C905B_TX 0x9055 #define PCI_DEVICE_ID_3COM_3C905C_TXM 0x9200 #define PCI_VENDOR_ID_INTEL 0x8086 #define PCI_DEVICE_ID_INTEL_82557 0x1229 diff --git a/netboot/rtl8139.c b/netboot/rtl8139.c index 26e133d14..2b7d452c1 100644 --- a/netboot/rtl8139.c +++ b/netboot/rtl8139.c @@ -7,9 +7,8 @@ of the GNU Public License, incorporated herein by reference. changes to the original driver: - - removed support for interrupts, switchung to polling mode (yuck!) + - removed support for interrupts, switching to polling mode (yuck!) - removed support for the 8129 chip (external MII) - and the 8139 with ids 0x1113/0x1211 (should be easy to add) */ @@ -19,6 +18,30 @@ /* + 4 Feb 2000 espenlaub@informatik.uni-ulm.de (Klaus Espenlaub) + Shuffled things around, removed the leftovers from the 8129 support + that was in the Linux driver and added a bit more 8139 definitions. + Moved the 8K receive buffer to a fixed, available address outside the + 0x98000-0x9ffff range. This is a bit of a hack, but currently the only + way to make room for the Etherboot features that need substantial amounts + of code like the ANSI console support. Currently the buffer is just below + 0x10000, so this even conforms to the tagged boot image specification, + which reserves the ranges 0x00000-0x10000 and 0x98000-0xA0000. My + interpretation of this "reserved" is that Etherboot may do whatever it + likes, as long as its environment is kept intact (like the BIOS + variables). Hopefully fixed rtl_poll() once and for all. The symptoms + were that if Etherboot was left at the boot menu for several minutes, the + first eth_poll failed. Seems like I am the only person who does this. + First of all I fixed the debugging code and then set out for a long bug + hunting session. It took me about a week full time work - poking around + various places in the driver, reading Don Becker's and Jeff Garzik's Linux + driver and even the FreeBSD driver (what a piece of crap!) - and + eventually spotted the nasty thing: the transmit routine was acknowledging + each and every interrupt pending, including the RxOverrun and RxFIFIOver + interrupts. This confused the RTL8139 thoroughly. It destroyed the + Rx ring contents by dumping the 2K FIFO contents right where we wanted to + get the next packet. Oh well, what fun. + 18 Jan 2000 mdc@thinguin.org (Marty Connor) Drastically simplified error handling. Basically, if any error in transmission or reception occurs, the card is reset. @@ -40,10 +63,7 @@ /* we have a PIC card */ #include "pci.h" -/* make things easier: the "linux kernel types" */ -#define u16 unsigned short -#define u32 unsigned long -#define u8 unsigned char +#define RTL_TIMEOUT (1*TICKS_PER_SEC) /* PCI Tuning Parameters Threshold is bytes transferred to chip before transmission starts. */ @@ -52,35 +72,41 @@ #define RX_DMA_BURST 4 /* Maximum PCI burst, '4' is 256 bytes */ #define TX_DMA_BURST 4 /* Calculate as 16<vendor == PCI_VENDOR_ID_REALTEK) && (p->dev_id == PCI_DEVICE_ID_REALTEK_8139) ) @@ -186,14 +216,20 @@ struct nic *rtl8139_probe(struct nic *nic, unsigned short *probeaddrs, *ap++ = read_eeprom(ioaddr, i + 7); } else { unsigned char *ap = (unsigned char*)nic->node_addr; - for (i = 0; i < 6; i++) + for (i = 0; i < ETHER_ADDR_SIZE; i++) *ap++ = inb(ioaddr + MAC0 + i); } - printf(" I/O %x ", ioaddr); + printf("ioaddr 0x%x, addr ", ioaddr); - for (i = 0; i < 6; i++) - printf ("%b%c", nic->node_addr[i] , i < 5 ?':':' '); + for (i = 0; i < ETHER_ADDR_SIZE; i++) { + printf("%b", nic->node_addr[i]); + if (i < ETHER_ADDR_SIZE-1) putchar(':'); + } + speed10 = inb(ioaddr + MediaStatus) & MSRSpeed10; + fullduplex = inw(ioaddr + MII_BMCR) & BMCRDuplex; + printf(" %sMbps %s-duplex\n", speed10 ? "10" : "100", + fullduplex ? "full" : "half"); rtl_reset(nic); @@ -231,7 +267,7 @@ struct nic *rtl8139_probe(struct nic *nic, unsigned short *probeaddrs, static int read_eeprom(long ioaddr, int location) { int i; - unsigned retval = 0; + unsigned int retval = 0; long ee_addr = ioaddr + Cfg9346; int read_cmd = location | EE_READ_CMD; @@ -262,13 +298,14 @@ static int read_eeprom(long ioaddr, int location) return retval; } -static void rtl_open(struct nic* nic) +static void rtl_reset(struct nic* nic) { int i; outb(CmdReset, ioaddr + ChipCmd); - rtl8129_init_ring(); + cur_rx = 0; + cur_tx = 0; /* Check that the chip has finished the reset. */ for (i = 1000; i > 0; i--) @@ -280,148 +317,149 @@ static void rtl_open(struct nic* nic) /* Must enable Tx/Rx before setting transfer thresholds! */ outb(CmdRxEnb | CmdTxEnb, ioaddr + ChipCmd); - outl((RX_FIFO_THRESH << 13) | (RX_BUF_LEN_IDX << 11) | (RX_DMA_BURST<<8), - ioaddr + RxConfig); + outl((RX_FIFO_THRESH<<13) | (RX_BUF_LEN_IDX<<11) | (RX_DMA_BURST<<8), + ioaddr + RxConfig); /* accept no frames yet! */ outl((TX_DMA_BURST<<8)|0x03000000, ioaddr + TxConfig); - tx_flag = (TX_FIFO_THRESH<<11) & 0x003f0000; - outb(0xC0, ioaddr + Cfg9346); - outb(0x20, ioaddr + Config1); /* half-duplex */ - outb(0x00, ioaddr + Cfg9346); + /* The Linux driver changes Config1 here to use a different LED pattern + * for half duplex or full/autodetect duplex (for full/autodetect, the + * outputs are TX/RX, Link10/100, FULL, while for half duplex it uses + * TX/RX, Link100, Link10). This is messy, because it doesn't match + * the inscription on the mounting bracket. It should not be changed + * from the configuration EEPROM default, because the card manufacturer + * should have set that to match the card. */ #ifdef DEBUG_RX - printf("rx start address is %X\n",(unsigned long) my.rx_ring); + printf("rx ring address is %X\n",(unsigned long)rx_ring); #endif - outl((unsigned long)my.rx_ring, ioaddr + RxBuf); + outl((unsigned long)rx_ring, ioaddr + RxBuf); /* Start the chip's Tx and Rx process. */ outl(0, ioaddr + RxMissed); /* set_rx_mode */ - outb(AcceptBroadcast|AcceptMulticast|AcceptMyPhys, ioaddr + RxConfig); - outl(0xFFFFFFFF, ioaddr + MAR0 + 0); - outl(0xFFFFFFFF, ioaddr + MAR0 + 4); + outb(AcceptBroadcast|AcceptMyPhys, ioaddr + RxConfig); + /* If we add multicast support, the MAR0 register would have to be + * initialized to 0xffffffffffffffff (two 32 bit accesses). Etherboot + * only needs broadcast (for ARP/RARP/BOOTP/DHCP) and unicast. */ outb(CmdRxEnb | CmdTxEnb, ioaddr + ChipCmd); /* Disable all known interrupts by setting the interrupt mask. */ outw(0, ioaddr + IntrMask); } -/* Initialize the Rx and Tx rings, along with various 'dev' bits. */ -static void rtl8129_init_ring() -{ - int i; - - cur_rx = 0; - cur_tx = 0; - - for (i = 0; i < NUM_TX_DESC; i++) { - tx_buf[i] = my.tx_bufs; - } -} - static void rtl_transmit(struct nic *nic, char *destaddr, unsigned int type, unsigned int len, char *data) { - unsigned int i, status=0, to, nstype; + unsigned int i, status, to, nstype; unsigned long txstatus; - unsigned char *txp = tx_buf[cur_tx]; - memcpy(txp, destaddr, ETHER_ADDR_SIZE); - memcpy(txp + ETHER_ADDR_SIZE, nic->node_addr, ETHER_ADDR_SIZE); + memcpy(tx_buffer, destaddr, ETHER_ADDR_SIZE); + memcpy(tx_buffer + ETHER_ADDR_SIZE, nic->node_addr, ETHER_ADDR_SIZE); nstype = htons(type); - memcpy(txp + 2 * ETHER_ADDR_SIZE, (char*)&nstype, 2); - memcpy(txp + ETHER_HDR_SIZE, data, len); + memcpy(tx_buffer + 2 * ETHER_ADDR_SIZE, (char*)&nstype, 2); + memcpy(tx_buffer + ETHER_HDR_SIZE, data, len); len += ETHER_HDR_SIZE; #ifdef DEBUG_TX printf("sending %d bytes ethtype %x\n", len, type); #endif - outl((unsigned long) txp, ioaddr + TxAddr0 + cur_tx*4); - /* Note: the chip doesn't have auto-pad! */ - /* 60 = ETH_ZLEN */ - outl(tx_flag | (len >= 60 ? len : 60), + + /* Note: RTL8139 doesn't auto-pad, send minimum payload (another 4 + * bytes are sent automatically for the FCS, totalling to 64 bytes). */ + while (len < ETH_MIN_PACKET - 4) { + tx_buffer[len++] = '\0'; + } + + outl((unsigned long)tx_buffer, ioaddr + TxAddr0 + cur_tx*4); + outl(((TX_FIFO_THRESH<<11) & 0x003f0000) | len, ioaddr + TxStatus0 + cur_tx*4); - to = TIME_OUT; + to = currticks() + RTL_TIMEOUT; do { status = inw(ioaddr + IntrStatus); - outw(status, ioaddr + IntrStatus); + /* Only acknlowledge interrupt sources we can properly handle + * here - the RxOverflow/RxFIFOOver MUST be handled in the + * rtl_poll() function. */ + outw(status & (TxOK | TxErr | PCIErr), ioaddr + IntrStatus); if ((status & (TxOK | TxErr | PCIErr)) != 0) break; - } while (--to); + } while (currticks() < to); txstatus = inl(ioaddr+ TxStatus0 + cur_tx*4); if (status & TxOK) { cur_tx = ++cur_tx % NUM_TX_DESC; #ifdef DEBUG_TX - printf("tx done (%d loops), status %x txstatus %X\n", - TIME_OUT-to, status, txstatus); + printf("tx done (%d ticks), status %x txstatus %X\n", + to-currticks(), status, txstatus); #endif - return; - } else { #ifdef DEBUG_TX - printf("tx ERROR (%d loops), status %x txstatus %X\n", - TIME_OUT-to, status, txstatus); - printf("tx TIME-OUT, status %x\n", status); + printf("tx timeout/error (%d ticks), status %x txstatus %X\n", + currticks()-to, status, txstatus); #endif - rtl_reset(nic); - return; - } } static int rtl_poll(struct nic *nic) { - unsigned int status=0; - unsigned int ring_offset, rx_size, rx_status; + unsigned int status; + unsigned int ring_offs; + unsigned int rx_size, rx_status; + + if (inb(ioaddr + ChipCmd) & RxBufEmpty) { + return 0; + } status = inw(ioaddr + IntrStatus); - outw(status, ioaddr + IntrStatus); + /* See below for the rest of the interrupt acknowledges. */ + outw(status & ~(RxFIFOOver | RxOverflow | RxOK), ioaddr + IntrStatus); - if((inb(ioaddr + ChipCmd) & RxBufEmpty) && !(status & RxErr)) - return 0; +#ifdef DEBUG_RX + printf("rtl_poll: int %x ", status); +#endif - if( status & RxErr ) { - rtl_reset(nic); - return 0; - } - - ring_offset = cur_rx % RX_BUF_LEN; - rx_status = *(unsigned int*)(my.rx_ring + ring_offset); + ring_offs = cur_rx % RX_BUF_LEN; + rx_status = *(unsigned int*)(rx_ring + ring_offs); rx_size = rx_status >> 16; + rx_status &= 0xffff; - if (rx_status & RxStatusOK) { - nic->packetlen = rx_size; - if (ring_offset+rx_size+4 > RX_BUF_LEN) { - int semi_count = RX_BUF_LEN - ring_offset - 4; - memcpy(nic->packet, (char*)&my.rx_ring[ring_offset+4], semi_count); - memcpy(nic->packet+semi_count, my.rx_ring, rx_size-semi_count); -#ifdef DEBUG_RX - printf("rtl_poll: rx packet %d + %d bytes\n", semi_count,rx_size-semi_count); -#endif - } else { - memcpy(nic->packet, (char*) &my.rx_ring[ring_offset+4], nic->packetlen); -#ifdef DEBUG_RX - printf("rtl_poll: rx packet %d bytes at %X type %b%b status %x rxstatus %X\n", - rx_size, (unsigned long) (my.rx_ring+ring_offset+4), - my.rx_ring[ring_offset+4+12], my.rx_ring[ring_offset+4+13], - status, rx_status); -#endif - } - cur_rx = (cur_rx + rx_size + 4 + 3) & ~3; - outw(cur_rx - 16, ioaddr + RxBufPtr); - return 1; - - } else { - - printf("rtl_poll: rx error status %x\n",status); - rtl_reset(nic); + if ((rx_status & (RxBadSymbol|RxRunt|RxTooLong|RxCRCErr|RxBadAlign)) || + (rx_size < ETH_MIN_PACKET) || (rx_size > ETH_MAX_PACKET)) { + printf("rx error %x\n", rx_status); + rtl_reset(nic); /* this clears all interrupts still pending */ return 0; - } + + /* Received a good packet */ + nic->packetlen = rx_size - 4; /* no one cares about the FCS */ + if (ring_offs+4+rx_size-4 > RX_BUF_LEN) { + int semi_count = RX_BUF_LEN - ring_offs - 4; + + memcpy(nic->packet, rx_ring + ring_offs + 4, semi_count); + memcpy(nic->packet+semi_count, rx_ring, rx_size-4-semi_count); +#ifdef DEBUG_RX + printf("rx packet %d+%d bytes", semi_count,rx_size-4-semi_count); +#endif + } else { + memcpy(nic->packet, rx_ring + ring_offs + 4, nic->packetlen); +#ifdef DEBUG_RX + printf("rx packet %d bytes", rx_size-4); +#endif + } +#ifdef DEBUG_RX + printf(" at %X type %b%b rxstatus %x\n", + (unsigned long)(rx_ring+ring_offs+4), + nic->packet[12], nic->packet[13], rx_status); +#endif + cur_rx = (cur_rx + rx_size + 4 + 3) & ~3; + outw(cur_rx - 16, ioaddr + RxBufPtr); + /* See RTL8139 Programming Guide V0.1 for the official handling of + * Rx overflow situations. The document itself contains basically no + * usable information, except for a few exception handling rules. */ + outw(status & (RxFIFOOver | RxOverflow | RxOK), ioaddr + IntrStatus); + return 1; } static void rtl_disable(struct nic *nic) diff --git a/netboot/tiara.c b/netboot/tiara.c index 5b4b73597..97c84d940 100644 --- a/netboot/tiara.c +++ b/netboot/tiara.c @@ -10,6 +10,13 @@ TIARA.ASM Packet driver by Brian Fisher, Queens U, Kingston, Ontario Fujitsu MB86960 spec sheet (different chip but same family) ***************************************************************************/ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2, or (at + * your option) any later version. + */ + /* to get some global routines like printf */ #include "etherboot.h" /* to get the interface to the body of the program */ diff --git a/stage2/disk_io.c b/stage2/disk_io.c index ddb315595..b4fb29d6d 100644 --- a/stage2/disk_io.c +++ b/stage2/disk_io.c @@ -481,6 +481,15 @@ check_BSD_parts (int flags) return 1; } +#ifndef STAGE1_5 + if (flags) + { + if (! do_completion) + grub_printf (" No BSD slice found, partition type 0x%x\n", + current_slice); + } +#endif + errnum = ERR_BAD_PART_TABLE; return 0; }