From owner-freebsd-hackers Thu May 18 22:58:01 1995 Return-Path: hackers-owner Received: (from majordom@localhost) by freefall.cdrom.com (8.6.10/8.6.6) id WAA13145 for hackers-outgoing; Thu, 18 May 1995 22:58:01 -0700 Received: from hq.icb.chel.su (icb-rich-gw.icb.chel.su [193.125.10.34]) by freefall.cdrom.com (8.6.10/8.6.6) with ESMTP id WAA13126 for ; Thu, 18 May 1995 22:57:01 -0700 Received: from localhost (babkin@localhost) by hq.icb.chel.su (8.6.5/8.6.5) id BAA07069; Fri, 19 May 1995 01:51:59 +0500 From: "Serge A. Babkin" Message-Id: <199505182051.BAA07069@hq.icb.chel.su> Subject: Re: Fix for 3C509 (ep) driver To: davidg@Root.COM Date: Fri, 19 May 1995 01:51:58 +0500 (GMT+0500) Cc: hackers@FreeBSD.org, steve@simon.chi.il.us, martin@victor.innovus.com In-Reply-To: <199503230451.UAA02437@corbin.Root.COM> from "David Greenman" at Mar 22, 95 08:51:37 pm X-Mailer: ELM [version 2.4 PL23] Content-Type: text Content-Length: 7686 Sender: hackers-owner@FreeBSD.org Precedence: bulk Review please this patch (and commit it if you think it's OK). It does: 1. Card is normally initialized after warm reboot from DOS. This part of patch is written by Steven E. Piette Now it has no kdc_...(I forgot what exactly)... hook that is called on system halt because I'm still running 950210-SNAP what doesn't have this hook. 2. Card works OK with "plug-n-play" mode enabled too (ISA cards only). I'm not shure about EISA autoconfiguration procedure so I didn't changed it. Perhaps the same changes should be done with Netboot, but I don't have its recent version. The patch is: *** 1.14 1995/05/18 08:06:26 --- if_ep.c 1995/05/19 05:36:51 *************** *** 38,44 **** */ /* ! * $Id: if_ep.c,v 1.14 1995/05/18 08:06:26 root Exp $ * * Promiscuous mode added and interrupt logic slightly changed * to reduce the number of adapter failures. Transceiver select --- 38,44 ---- */ /* ! * $Id: if_ep.c,v 1.16 1995/05/19 05:36:10 root Exp root $ * * Promiscuous mode added and interrupt logic slightly changed * to reduce the number of adapter failures. Transceiver select *************** *** 117,122 **** --- 117,123 ---- static int send_ID_sequence __P((int)); static int get_eeprom_data __P((int, int)); + static struct ep_board *ep_look_for_board_at(struct isa_device *); struct ep_softc ep_softc[NEP]; *************** *** 153,163 **** int ep_current_tag = EP_LAST_TAG + 1; ! struct { ! int epb_addr; /* address of this board */ ! char epb_used; /* was this entry already used for configuring ? */ ! } ! ep_board[EP_MAX_BOARDS + 1]; static int eeprom_rdy(is) --- 154,160 ---- int ep_current_tag = EP_LAST_TAG + 1; ! struct ep_board ep_board[EP_MAX_BOARDS + 1]; static int eeprom_rdy(is) *************** *** 173,179 **** return (1); } ! static int ep_look_for_board_at(is) struct isa_device *is; { --- 170,176 ---- return (1); } ! static struct ep_board * ep_look_for_board_at(is) struct isa_device *is; { *************** *** 202,213 **** --- 199,215 ---- * Once activated, all the registers are mapped in the range * x000 - x00F, where x is the slot number. */ + ep_board[neisa].epb_isa = 0; ep_board[neisa].epb_used = 0; ep_board[neisa++].epb_addr = j * EP_EISA_START; } ep_current_tag--; /* Look for the ISA boards. Init and leave them actived */ + outb(id_port, 0); + outb(id_port, 0); + send_ID_sequence(id_port); + outb(id_port, 0xc0); /* Global reset */ DELAY(10000); for (i = 0; i < EP_MAX_BOARDS; i++) { *************** *** 220,231 **** break; /* resolve contention using the Ethernet address */ for (j = 0; j < 3; j++) ! data = get_eeprom_data(id_port, j); ep_board[neisa+nisa].epb_used = 0; ep_board[neisa+nisa++].epb_addr = ! (get_eeprom_data(id_port, EEPROM_ADDR_CFG) & 0x1f) * 0x10 + 0x200; outb(id_port, ep_current_tag); /* tags board */ outb(id_port, ACTIVATE_ADAPTER_TO_CONFIG); ep_current_tag--; --- 222,247 ---- break; /* resolve contention using the Ethernet address */ + + for (j = 0; j < 3; j++) + get_eeprom_data(id_port, j); + + /* and save this address for later use */ + for (j = 0; j < 3; j++) ! ep_board[neisa+nisa].eth_addr[j] = get_eeprom_data(id_port, j); + ep_board[neisa+nisa].res_cfg = + get_eeprom_data(id_port, EEPROM_RESOURCE_CFG); + + ep_board[neisa+nisa].prod_id = + get_eeprom_data(id_port, EEPROM_PROD_ID); + + ep_board[neisa].epb_isa = 1; ep_board[neisa+nisa].epb_used = 0; ep_board[neisa+nisa++].epb_addr = ! (get_eeprom_data(id_port, EEPROM_ADDR_CFG) & 0x1f) * 0x10 + 0x200; ! outb(id_port, ep_current_tag); /* tags board */ outb(id_port, ACTIVATE_ADAPTER_TO_CONFIG); ep_current_tag--; *************** *** 265,271 **** IS_BASE=ep_board[i].epb_addr; ep_board[i].epb_used=1; ! return 1; } else { for (i=0; ep_board[i].epb_addr && ep_board[i].epb_addr != IS_BASE; i++); --- 281,288 ---- IS_BASE=ep_board[i].epb_addr; ep_board[i].epb_used=1; ! ! return &ep_board[i]; } else { for (i=0; ep_board[i].epb_addr && ep_board[i].epb_addr != IS_BASE; i++); *************** *** 276,282 **** printf("ep%d: 3c5x9 at 0x%x in test mode. Erase pencil mark!\n", is->id_unit, IS_BASE); ep_board[i].epb_used=1; ! return 1; } } --- 293,300 ---- printf("ep%d: 3c5x9 at 0x%x in test mode. Erase pencil mark!\n", is->id_unit, IS_BASE); ep_board[i].epb_used=1; ! ! return &ep_board[i]; } } *************** *** 305,324 **** u_short k; int i; ! if (!ep_look_for_board_at(is)) return (0); /* * The iobase was found and MFG_ID was 0x6d50. PROD_ID should be * 0x9[0-f]50 */ GO_WINDOW(0); ! k = get_e(is, EEPROM_PROD_ID); if ((k & 0xf0ff) != (PROD_ID & 0xf0ff)) { printf("epprobe: ignoring model %04x\n", k); return (0); } ! k = get_e(is, EEPROM_RESOURCE_CFG); k >>= 12; /* Now we have two cases again: --- 323,343 ---- u_short k; int i; ! if(( sc->epb=ep_look_for_board_at(is) )==0) return (0); /* * The iobase was found and MFG_ID was 0x6d50. PROD_ID should be * 0x9[0-f]50 */ GO_WINDOW(0); ! k = sc->epb->epb_isa ? sc->epb->prod_id : get_e(is, EEPROM_PROD_ID); if ((k & 0xf0ff) != (PROD_ID & 0xf0ff)) { printf("epprobe: ignoring model %04x\n", k); return (0); } ! k = sc->epb->epb_isa ? sc->epb->res_cfg : get_e(is, EEPROM_RESOURCE_CFG); ! k >>= 12; /* Now we have two cases again: *************** *** 393,399 **** p = (u_short *) & sc->arpcom.ac_enaddr; for (i = 0; i < 3; i++) { GO_WINDOW(0); ! p[i] = htons(get_e(is, i)); GO_WINDOW(2); outw(BASE + EP_W2_ADDR_0 + (i * 2), ntohs(p[i])); } --- 412,418 ---- p = (u_short *) & sc->arpcom.ac_enaddr; for (i = 0; i < 3; i++) { GO_WINDOW(0); ! p[i] = htons( sc->epb->epb_isa ? sc->epb->eth_addr[i] : get_e(is, i) ); GO_WINDOW(2); outw(BASE + EP_W2_ADDR_0 + (i * 2), ntohs(p[i])); } *** 1.8 1995/04/10 07:48:03 --- if_epreg.h 1995/05/19 05:36:53 *************** *** 31,37 **** */ /* ! * $Id: if_epreg.h,v 1.8 1995/04/10 07:48:03 root Exp $ * * Promiscuous mode added and interrupt logic slightly changed * to reduce the number of adapter failures. Transceiver select --- 31,37 ---- */ /* ! * $Id: if_epreg.h,v 1.9 1995/05/19 05:36:10 root Exp root $ * * Promiscuous mode added and interrupt logic slightly changed * to reduce the number of adapter failures. Transceiver select *************** *** 71,76 **** --- 71,78 ---- #define F_ACCESS_32_BITS 0x100 + struct ep_board *epb; + #ifdef EP_LOCAL_STATS short tx_underrun; short rx_no_first; *************** *** 80,85 **** --- 82,98 ---- short rx_overrunl; #endif }; + + struct ep_board { + int epb_addr; /* address of this board */ + char epb_used; /* was this entry already used for configuring ? */ + /* data from EEPROM for later use */ + char epb_isa; /* flag: this is an ISA card */ + u_short eth_addr[3]; /* Ethernet address */ + u_short prod_id; /* product ID */ + u_short res_cfg; /* resource configuration */ + }; + /* * Some global constants Serge Babkin ! (babkin@hq.icb.chel.su) ! Headquarter of Joint Stock Commercial Bank "Chelindbank" ! Chelyabinsk, Russia