3 * ===================================
4 * HARP | Host ATM Research Platform
5 * ===================================
8 * This Host ATM Research Platform ("HARP") file (the "Software") is
9 * made available by Network Computing Services, Inc. ("NetworkCS")
10 * "AS IS". NetworkCS does not provide maintenance, improvements or
11 * support of any kind.
13 * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
14 * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
15 * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
16 * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
17 * In no event shall NetworkCS be responsible for any damages, including
18 * but not limited to consequential damages, arising from or relating to
19 * any use of the Software or related support.
21 * Copyright 1994-1998 Network Computing Services, Inc.
23 * Copies of this Software may be made, however, the above copyright
24 * notice must be reproduced on all copies.
26 * @(#) $FreeBSD: src/sys/dev/hfa/fore_load.c,v 1.13 1999/09/25 18:23:49 phk Exp $
31 * FORE Systems 200-Series Adapter Support
32 * ---------------------------------------
34 * Loadable kernel module and device identification support
38 #include <dev/hfa/fore_include.h>
41 __RCSID("@(#) $FreeBSD: src/sys/dev/hfa/fore_load.c,v 1.13 1999/09/25 18:23:49 phk Exp $");
48 static int fore_start __P((void));
50 static int fore_stop __P((void));
51 static int fore_doload __P((void));
52 static int fore_dounload __P((void));
53 static int fore_identify __P((char *));
54 static int fore_attach __P((struct devinfo *));
57 static const char * fore_pci_probe __P((pcici_t, pcidi_t));
58 static void fore_pci_attach __P((pcici_t, int));
60 static int fore_pci_shutdown __P((struct kern_devconf *, int));
62 static void fore_pci_shutdown __P((void *, int));
65 static void fore_unattach __P((Fore_unit *));
66 static void fore_reset __P((Fore_unit *));
72 static int fore_inited = 0;
78 static struct dev_ops fore_ops = {
80 fore_identify, /* identify */
81 fore_attach, /* attach */
96 static u_long fore_pci_count = 0;
98 static struct pci_device fore_pci_device = {
110 COMPAT_PCI_DRIVER(fore_pci, fore_pci_device);
115 * Initialize driver processing
117 * This will be called during module loading. Not much to do here, as
118 * we must wait for our identify/attach routines to get called before
119 * we know what we're in for.
125 * 0 startup was successful
126 * errno startup failed - reason indicated
134 * Verify software version
136 if (atm_version != ATM_VERSION) {
137 log(LOG_ERR, "version mismatch: fore=%d.%d kernel=%d.%d\n",
138 ATM_VERS_MAJ(ATM_VERSION), ATM_VERS_MIN(ATM_VERSION),
139 ATM_VERS_MAJ(atm_version), ATM_VERS_MIN(atm_version));
144 * Initialize DMA mapping
149 * Start up watchdog timer
151 atm_timeout(&fore_timer, ATM_HZ * FORE_TIME_TICK, fore_timeout);
162 * Halt driver processing
164 * This will be called just prior to unloading the module from memory.
165 * Everything we've setup since we've been loaded must be undone here.
171 * 0 shutdown was successful
172 * errno shutdown failed - reason indicated
183 * Stop the watchdog timer
185 (void) atm_untimeout(&fore_timer);
188 * Clean up each device (if any)
190 for ( i = 0; i < fore_nunits; i++ ) {
191 Fore_unit *fup = fore_units[i];
197 * Deregister device from kernel services
199 if (err = atm_physif_deregister((Cmn_unit *)fup)) {
205 * Unattach the device from the system
210 * Free any Fore-specific device resources
212 fore_interface_free(fup);
215 * Free the unit structure
218 fore_units[i] = NULL;
224 * Now free our global resources
228 * Release our storage pools
230 atm_release_pool(&fore_vcc_pool);
231 atm_release_pool(&fore_nif_pool);
234 * Release all DMA mappings
246 * Device identify routine
248 * Determine if this driver will support the named device. If we claim to
249 * support the device, our attach routine will (later) be called for the
253 * name pointer to identifier string from device
256 * 1 driver claims support for this device
257 * 0 device not claimed by this driver
268 * Initialize driver stuff
270 if (fore_inited == 0) {
275 while (fore_devices[i].fd_name) {
276 if (strcmp(fore_devices[i].fd_name, name) == 0) {
279 * We support this device!!
281 if (fore_nunits < FORE_MAX_UNITS) {
286 "fore_identify: Too many devices\n");
297 * Device attach routine
299 * Attach a device we've previously claimed to support. Walk through its
300 * register set and map, as required. Determine what level the device will
301 * be interrupting at and then register an interrupt handler for it. If we
302 * succeed, then reset the adapter and read useful info from its PROM.
303 * Last, register the interface with the kernel ATM services.
306 * devinfo_p pointer to device information structure
309 * 0 attach was successful
314 fore_attach(devinfo_p)
315 struct dev_info *devinfo_p;
317 struct dev_reg *dev_reg_p;
318 struct dev_intr *dev_intr_p;
324 int err_count = BOOT_LOOPS;
330 if (devinfo_p == NULL)
334 * Make sure this isn't a duplicate unit
336 if (fore_units[unit] != NULL)
340 * Allocate a new unit structure
342 fup = (Fore_unit *) atm_dev_alloc(sizeof(Fore_unit), sizeof(int), 0);
347 * Start initializing it
350 fup->fu_mtu = FORE_IFF_MTU;
351 fup->fu_devinfo = devinfo_p;
352 fup->fu_vcc_pool = &fore_vcc_pool;
353 fup->fu_nif_pool = &fore_nif_pool;
354 fup->fu_ioctl = fore_atm_ioctl;
355 fup->fu_instvcc = fore_instvcc;
356 fup->fu_openvcc = fore_openvcc;
357 fup->fu_closevcc = fore_closevcc;
358 fup->fu_output = fore_output;
361 * Consider this unit assigned
363 fore_units[unit] = fup;
366 ATM_DEBUG1("fore_attach: fup=%p\n", fup);
367 ATM_DEBUG2("\tfu_xmit_q=%p fu_xmit_head=%p\n",
368 fup->fu_xmit_q, &fup->fu_xmit_head);
369 ATM_DEBUG2("\tfu_recv_q=%p fu_recv_head=%p\n",
370 fup->fu_recv_q, &fup->fu_recv_head);
371 ATM_DEBUG2("\tfu_buf1s_q=%p fu_buf1s_head=%p\n",
372 fup->fu_buf1s_q, &fup->fu_buf1s_head);
373 ATM_DEBUG2("\tfu_buf1l_q=%p fu_buf1l_head=%p\n",
374 fup->fu_buf1l_q, &fup->fu_buf1l_head);
375 ATM_DEBUG2("\tfu_cmd_q=%p fu_cmd_head=%p\n",
376 fup->fu_cmd_q, &fup->fu_cmd_head);
377 ATM_DEBUG1("\tfu_stats=%p\n",
381 * Tell kernel our unit number
383 devinfo_p->devi_unit = fup->fu_unit;
386 * Figure out what type of device we've got. This should always
387 * work since we've already done this at identify time!
390 while (fore_devices[i].fd_name) {
391 if (strcmp(fore_devices[i].fd_name, devinfo_p->devi_name) == 0)
395 if (fore_devices[i].fd_name == NULL)
398 fup->fu_config.ac_device = fore_devices[i].fd_devtyp;
401 * Walk through the OPENPROM register information
402 * mapping register banks as they are found.
404 for ( dev_reg_p = devinfo_p->devi_reg, i = 1;
405 i <= devinfo_p->devi_nreg; i++, ++dev_reg_p )
407 if ( dev_reg_p == NULL )
416 * Each device type has different register sets
418 switch (fup->fu_config.ac_device) {
421 case DEV_FORE_SBA200E:
426 * Host Control Register (HCR)
429 if ( sizeof(Fore_reg) != dev_reg_p->reg_size )
433 fup->fu_ctlreg = (Fore_reg *)
434 map_regs ( dev_reg_p->reg_addr,
436 dev_reg_p->reg_bustype );
437 if ( fup->fu_ctlreg == NULL )
444 * SBus Burst Transfer Configuration Register
453 * SBus Interrupt Level Select Register
456 if ( sizeof (Fore_reg) != dev_reg_p->reg_size )
460 fup->fu_intlvl = (Fore_reg *)
461 map_regs ( dev_reg_p->reg_addr,
463 dev_reg_p->reg_bustype );
464 if ( fup->fu_intlvl == NULL )
474 fup->fu_ram = (Fore_mem *)
475 map_regs ( dev_reg_p->reg_addr,
477 dev_reg_p->reg_bustype );
478 if ( fup->fu_ram == NULL )
482 fup->fu_ramsize = dev_reg_p->reg_size;
485 * Various versions of the Sun PROM mess with
486 * the reg_addr value in unpredictable (to me,
487 * at least) ways, so just use the "memoffset"
488 * property, which should give us the RAM
491 val = getprop(devinfo_p->devi_nodeid,
496 fup->fu_config.ac_ram = val;
497 fup->fu_config.ac_ramsize = fup->fu_ramsize;
500 * Set monitor interface for initializing
502 fup->fu_mon = (Mon960 *)
503 (fup->fu_ram + MON960_BASE);
508 "fore_attach: Too many registers\n");
513 case DEV_FORE_SBA200:
518 * Board Control Register (BCR)
521 if ( sizeof(Fore_reg) != dev_reg_p->reg_size )
525 fup->fu_ctlreg = (Fore_reg *)
526 map_regs ( dev_reg_p->reg_addr,
528 dev_reg_p->reg_bustype );
529 if ( fup->fu_ctlreg == NULL )
539 fup->fu_ram = (Fore_mem *)
540 map_regs ( dev_reg_p->reg_addr,
542 dev_reg_p->reg_bustype );
543 if ( fup->fu_ram == NULL )
547 fup->fu_ramsize = dev_reg_p->reg_size;
550 * Various versions of the Sun PROM mess with
551 * the reg_addr value in unpredictable (to me,
552 * at least) ways, so just use the "memoffset"
553 * property, which should give us the RAM
556 val = getprop(devinfo_p->devi_nodeid,
561 fup->fu_config.ac_ram = val;
562 fup->fu_config.ac_ramsize = fup->fu_ramsize;
565 * Set monitor interface for initializing
567 fup->fu_mon = (Mon960 *)
568 (fup->fu_ram + MON960_BASE);
573 "fore_attach: Too many registers\n");
577 #endif /* FORE_SBUS */
581 "fore_attach: Unsupported device type %d\n",
582 fup->fu_config.ac_device);
588 * Install the device in the interrupt chain.
590 * dev_intr_p may be null IFF devi_nintr is zero.
592 dev_intr_p = devinfo_p->devi_intr;
593 for ( i = devinfo_p->devi_nintr; i > 0; --i, ++dev_intr_p )
596 if ( dev_intr_p == NULL )
605 * Convert hardware ipl (0-15) into spl level.
607 if ( ipltospl ( dev_intr_p->int_pri ) > fup->fu_intrpri )
609 fup->fu_intrpri = ipltospl ( dev_intr_p->int_pri );
612 * If SBA-200E card, set SBus interrupt level
613 * into board register
615 if ( fup->fu_intlvl ) {
617 *(fup->fu_intlvl) = dev_intr_p->int_pri;
622 svimap[dev_intr_p->int_pri & 0xf];
629 DEVICE_LOCK((Cmn_unit *)fup);
632 * Register our interrupt routine.
634 (void) addintr ( dev_intr_p->int_pri, fore_poll,
635 devinfo_p->devi_name, devinfo_p->devi_unit );
638 * If we can do DMA (we can), then DVMA routines need
639 * to know the highest IPL level we will interrupt at.
641 adddma ( dev_intr_p->int_pri );
643 DEVICE_UNLOCK((Cmn_unit *)fup);
647 * Poke the hardware...boot the CP and prepare it for downloading
651 switch (fup->fu_config.ac_device) {
654 case DEV_FORE_SBA200E:
658 SBA200E_HCR_SET(*fup->fu_ctlreg, SBA200E_SBUS_ENA);
660 #endif /* FORE_SBUS */
664 * Wait for monitor to perform self-test
666 while (CP_READ(fup->fu_mon->mon_bstat) != BOOT_MONREADY) {
667 if (CP_READ(fup->fu_mon->mon_bstat) == BOOT_FAILTEST) {
668 log(LOG_ERR, "fore_attach: Unit %d failed self-test\n",
672 } else if ( --err_count == 0 ) {
673 log(LOG_ERR, "fore_attach: Unit %d unable to boot\n",
677 DELAY ( BOOT_DELAY );
681 * Write a one line message to the console informing
682 * that we've attached the device.
684 report_dev ( devinfo_p );
687 * Get the mac address from the card PROM
689 val = getprop ( devinfo_p->devi_nodeid, "macaddress1", -1 );
691 fup->fu_pif.pif_macaddr.ma_data[0] = val & 0xff;
692 val = getprop ( devinfo_p->devi_nodeid, "macaddress2", -1 );
693 fup->fu_pif.pif_macaddr.ma_data[1] = val & 0xff;
694 val = getprop ( devinfo_p->devi_nodeid, "macaddress3", -1 );
695 fup->fu_pif.pif_macaddr.ma_data[2] = val & 0xff;
696 val = getprop ( devinfo_p->devi_nodeid, "macaddress4", -1 );
697 fup->fu_pif.pif_macaddr.ma_data[3] = val & 0xff;
698 val = getprop ( devinfo_p->devi_nodeid, "macaddress5", -1 );
699 fup->fu_pif.pif_macaddr.ma_data[4] = val & 0xff;
700 val = getprop ( devinfo_p->devi_nodeid, "macaddress6", -1 );
701 fup->fu_pif.pif_macaddr.ma_data[5] = val & 0xff;
704 * Newer PROM - mac addresses have been combined. Also,
705 * macaddrlo2 reflects the board serial number.
707 val = htonl(getprop(devinfo_p->devi_nodeid, "macaddrlo2", -1));
708 KM_COPY ( (caddr_t)&val,
709 (caddr_t)&fup->fu_pif.pif_macaddr.ma_data[2],
711 val = htonl(getprop(devinfo_p->devi_nodeid, "macaddrhi4", -1));
712 KM_COPY ( (caddr_t)&val,
713 (caddr_t)fup->fu_pif.pif_macaddr.ma_data,
718 * Setup the adapter config info
720 fcp = &fup->fu_config;
721 fcp->ac_vendor = VENDOR_FORE;
722 fcp->ac_vendapi = VENDAPI_FORE_1;
723 fcp->ac_macaddr = fup->fu_pif.pif_macaddr;
724 val = getprop ( devinfo_p->devi_nodeid, "promversion", -1 );
726 val = getprop ( devinfo_p->devi_nodeid, "hw-version", -1 );
729 snprintf(fcp->ac_hard_vers,
730 sizeof(fcp->ac_hard_vers), "%d.%d.%d",
731 (val >> 16) & 0xff, (val >> 8) & 0xff, val & 0xff);
733 snprintf(fcp->ac_hard_vers,
734 sizeof(fcp->ac_hard_vers), "Unknown");
736 val = getprop ( devinfo_p->devi_nodeid, "serialnumber", -1 );
738 fcp->ac_serial = val;
740 valp = (addr_t)getlongprop ( devinfo_p->devi_nodeid, "model" );
746 switch (fcp->ac_device) {
749 case DEV_FORE_SBA200E:
750 fcp->ac_media = MEDIA_OC3C;
751 fup->fu_pif.pif_pcr = ATM_PCR_OC3C;
754 case DEV_FORE_SBA200:
756 * Look at the /SSS trailer to determine 4B5B speed
757 * TAXI-100 = 125; TAXI-140 = 175
758 * Assume that OC3 has no /SSS speed identifier.
760 while (*valp && *valp != '/')
763 fcp->ac_media = MEDIA_OC3C;
764 fup->fu_pif.pif_pcr = ATM_PCR_OC3C;
765 } else if (strcmp(valp, "/125") == 0) {
766 fcp->ac_media = MEDIA_TAXI_100;
767 fup->fu_pif.pif_pcr = ATM_PCR_TAXI100;
769 fcp->ac_media = MEDIA_TAXI_140;
770 fup->fu_pif.pif_pcr = ATM_PCR_TAXI140;
773 #endif /* FORE_SBUS */
777 * Free property space
779 KM_FREE(valp, getproplen(devinfo_p->devi_nodeid, "model"), 0);
787 (long)(devinfo_p->devi_reg->reg_addr - SBUS_BASE) / SBUS_SIZE;
789 sbusslot((u_long)devinfo_p->devi_reg->reg_addr);
792 val = getprop(devinfo_p->devi_parent->devi_nodeid, "burst-sizes", 0);
793 if (val & SBUS_BURST32)
794 fcp->ac_bustype = BUS_SBUS_B32;
796 fcp->ac_bustype = BUS_SBUS_B16;
799 * Set device capabilities
801 fup->fu_pif.pif_maxvpi = FORE_MAX_VPI;
802 fup->fu_pif.pif_maxvci = FORE_MAX_VCI;
805 * Register this interface with ATM core services
807 if ( atm_physif_register
808 ((Cmn_unit *)fup, FORE_DEV_NAME, fore_services) != 0 )
811 * Registration failed - back everything out
814 * Modload calls UNLOAD if it get's a failure - don't
815 * call fore_unload() here.
821 * Initialize the CP microcode program.
823 fore_initialize(fup);
832 * Device probe routine
834 * Determine if this driver will support the identified device. If we claim
835 * to support the device, our attach routine will (later) be called for the
839 * config_id device's PCI configuration ID
840 * device_id device's PCI Vendor/Device ID
843 * name device identification string
844 * NULL device not claimed by this driver
848 fore_pci_probe(config_id, device_id)
854 * Initialize driver stuff
856 if (fore_inited == 0) {
861 if ((device_id & 0xffff) != FORE_VENDOR_ID)
864 if (((device_id >> 16) & 0xffff) == FORE_PCA200E_ID)
865 return ("FORE Systems PCA-200E ATM");
872 * Device attach routine
874 * Attach a device we've previously claimed to support. Walk through its
875 * register set and map, as required. Determine what level the device will
876 * be interrupting at and then register an interrupt handler for it. If we
877 * succeed, then reset the adapter and initialize the microcode.
878 * Last, register the interface with the kernel ATM services.
881 * config_id device's PCI configuration ID
882 * unit device unit number
889 fore_pci_attach(config_id, unit)
898 int err_count = BOOT_LOOPS;
903 if (unit >= FORE_MAX_UNITS) {
904 log(LOG_ERR, "%s%d: too many devices\n",
905 FORE_DEV_NAME, unit);
910 * Make sure this isn't a duplicate unit
912 if (fore_units[unit] != NULL)
916 * Allocate a new unit structure
918 fup = (Fore_unit *) atm_dev_alloc(sizeof(Fore_unit), sizeof(int), 0);
923 * Start initializing it
926 fup->fu_mtu = FORE_IFF_MTU;
927 fup->fu_pcitag = config_id;
928 fup->fu_vcc_pool = &fore_vcc_pool;
929 fup->fu_nif_pool = &fore_nif_pool;
930 fup->fu_ioctl = fore_atm_ioctl;
931 fup->fu_instvcc = fore_instvcc;
932 fup->fu_openvcc = fore_openvcc;
933 fup->fu_closevcc = fore_closevcc;
934 fup->fu_output = fore_output;
935 callout_handle_init(&fup->fu_thandle);
938 * Get our device type
940 device_id = pci_conf_read ( config_id, PCI_ID_REG );
941 switch ((device_id >> 16) & 0xffff) {
943 case FORE_PCA200E_ID:
944 fup->fu_config.ac_device = DEV_FORE_PCA200E;
948 fup->fu_config.ac_device = DEV_UNKNOWN;
952 * Enable Memory Mapping / Bus Mastering
954 val = pci_conf_read(config_id, PCI_COMMAND_STATUS_REG);
955 val |= (PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN);
956 pci_conf_write(config_id, PCI_COMMAND_STATUS_REG, val);
961 val = pci_conf_read(config_id, PCI_COMMAND_STATUS_REG);
962 if ((val & PCIM_CMD_MEMEN) == 0) {
963 log(LOG_ERR, "%s%d: memory mapping not enabled\n",
964 FORE_DEV_NAME, unit);
967 if ((pci_map_mem(config_id, PCA200E_PCI_MEMBASE, &va, &pa)) == 0) {
968 log(LOG_ERR, "%s%d: unable to map memory\n",
969 FORE_DEV_NAME, unit);
972 fup->fu_ram = (Fore_mem *)va;
973 fup->fu_ramsize = PCA200E_RAM_SIZE;
974 fup->fu_mon = (Mon960 *)(fup->fu_ram + MON960_BASE);
975 fup->fu_ctlreg = (Fore_reg *)(va + PCA200E_HCR_OFFSET);
976 fup->fu_imask = (Fore_reg *)(va + PCA200E_IMASK_OFFSET);
977 fup->fu_psr = (Fore_reg *)(va + PCA200E_PSR_OFFSET);
980 * Convert Endianess of Slave RAM accesses
982 val = pci_conf_read(config_id, PCA200E_PCI_MCTL);
983 val |= PCA200E_MCTL_SWAP;
984 pci_conf_write(config_id, PCA200E_PCI_MCTL, val);
989 if ( !pci_map_int( config_id, fore_intr, fup, &net_imask ) ) {
990 log(LOG_ERR, "%s%d: unable to map interrupt\n",
991 FORE_DEV_NAME, unit);
996 * Poke the hardware - boot the CP and prepare it for downloading
1001 * Wait for the monitor to perform self-test
1003 while (CP_READ(fup->fu_mon->mon_bstat) != BOOT_MONREADY) {
1004 if (CP_READ(fup->fu_mon->mon_bstat) == BOOT_FAILTEST) {
1005 log(LOG_ERR, "%s%d: failed self-test\n",
1006 FORE_DEV_NAME, unit);
1008 } else if ( --err_count == 0 ) {
1009 log(LOG_ERR, "%s%d: unable to boot - status=0x%lx\n",
1010 FORE_DEV_NAME, unit,
1011 (u_long)CP_READ(fup->fu_mon->mon_bstat));
1014 DELAY ( BOOT_DELAY );
1018 * Setup the adapter config info - at least as much as we can
1020 fup->fu_config.ac_vendor = VENDOR_FORE;
1021 fup->fu_config.ac_vendapi = VENDAPI_FORE_1;
1022 fup->fu_config.ac_media = MEDIA_OC3C;
1023 fup->fu_pif.pif_pcr = ATM_PCR_OC3C;
1024 fup->fu_config.ac_bustype = BUS_PCI;
1025 fup->fu_config.ac_busslot = config_id->bus << 8 | config_id->slot;
1028 * Save device ram info for user-level programs
1030 fup->fu_config.ac_ram = (long)fup->fu_ram;
1031 fup->fu_config.ac_ramsize = fup->fu_ramsize;
1034 * Set device capabilities
1036 fup->fu_pif.pif_maxvpi = FORE_MAX_VPI;
1037 fup->fu_pif.pif_maxvci = FORE_MAX_VCI;
1040 * Register this interface with ATM core services
1042 if ( atm_physif_register
1043 ((Cmn_unit *)fup, FORE_DEV_NAME, fore_services) != 0 )
1046 * Registration failed - back everything out
1051 fore_units[unit] = fup;
1056 * Add hook to our shutdown function
1058 EVENTHANDLER_REGISTER(shutdown_post_sync, fore_pci_shutdown, fup,
1059 SHUTDOWN_PRI_DEFAULT);
1063 * Initialize the CP microcode program.
1065 fore_initialize(fup);
1071 * Unattach the device from the system
1076 * Free any Fore-specific device resources
1078 fore_interface_free(fup);
1088 * Device shutdown routine
1091 * kdc pointer to device's configuration table
1092 * force forced shutdown flag
1099 fore_pci_shutdown(kdc, force)
1100 struct kern_devconf *kdc;
1105 if (kdc->kdc_unit < fore_nunits) {
1107 fup = fore_units[kdc->kdc_unit];
1113 (void) dev_detach(kdc);
1118 * Device shutdown routine
1121 * howto type of shutdown
1122 * fup pointer to device unit structure
1129 fore_pci_shutdown(fup, howto)
1134 fore_reset((Fore_unit *) fup);
1138 #endif /* BSD < 199506 */
1139 #endif /* __FreeBSD__ */
1143 * Device unattach routine
1145 * Reset the physical device, remove any pending timeouts,
1146 * unmap any register sets, and unregister any interrupts.
1149 * fup pointer to device unit structure
1159 struct dev_info *devinfo_p = fup->fu_devinfo;
1160 struct dev_reg *dev_reg_p;
1161 struct dev_intr *dev_intr_p;
1167 * Reset the board and return it to cold_start state.
1168 * Hopefully, this will prevent use of resources as
1169 * we're trying to free things up.
1174 * Lock out all device interrupts
1176 DEVICE_LOCK((Cmn_unit *)fup);
1179 * Remove any pending timeout()'s
1181 (void)untimeout((KTimeout_ret(*) __P((void *)))fore_initialize,
1182 (void *)fup, fup->fu_thandle);
1186 * Remove any mappings of the device
1188 for ( dev_reg_p = devinfo_p->devi_reg, i = 1;
1189 i <= devinfo_p->devi_nreg; i++, ++dev_reg_p )
1191 if ( dev_reg_p == NULL )
1200 * Each device type has different register sets
1202 switch (fup->fu_config.ac_device) {
1205 case DEV_FORE_SBA200E:
1210 * Host Control Register (HCR)
1213 unmap_regs((addr_t)fup->fu_ctlreg,
1218 * SBus Burst Transfer Configuration Register
1227 * SBus Interrupt Level Select Register
1230 unmap_regs((addr_t)fup->fu_intlvl,
1238 unmap_regs((addr_t)fup->fu_ram,
1244 case DEV_FORE_SBA200:
1249 * Board Control Register (BCR)
1252 unmap_regs((addr_t)fup->fu_ctlreg,
1260 unmap_regs((addr_t)fup->fu_ram,
1265 #endif /* FORE_SBUS */
1270 * Remove the interrupt vector(s)
1272 dev_intr_p = devinfo_p->devi_intr;
1273 for ( i = devinfo_p->devi_nintr; i > 0; --i, ++dev_intr_p )
1275 if ( dev_intr_p == NULL )
1282 (void) remintr ( dev_intr_p->int_pri, fore_poll );
1288 * Unmap the device interrupt
1290 (void) pci_unmap_int(fup->fu_pcitag);
1296 (void) pci_unmap_mem(fup->fu_pcitag, PCA200E_PCI_MEMBASE);
1298 #endif /* __FreeBSD__ */
1300 DEVICE_UNLOCK((Cmn_unit *)fup);
1305 * Device reset routine
1307 * Reset the physical device
1310 * fup pointer to device unit structure
1322 * Reset the board and return it to cold_start state
1325 fup->fu_mon->mon_bstat = CP_WRITE(BOOT_COLDSTART);
1327 if (fup->fu_ctlreg) {
1329 switch (fup->fu_config.ac_device) {
1332 case DEV_FORE_SBA200E:
1334 * Reset i960 by setting and clearing RESET
1336 SBA200E_HCR_INIT(*fup->fu_ctlreg, SBA200E_RESET);
1337 SBA200E_HCR_CLR(*fup->fu_ctlreg, SBA200E_RESET);
1340 case DEV_FORE_SBA200:
1342 * Reset i960 by setting and clearing RESET
1344 * SBA200 will NOT reset if bit is OR'd in!
1346 *fup->fu_ctlreg = SBA200_RESET;
1347 *fup->fu_ctlreg = SBA200_RESET_CLR;
1349 #endif /* FORE_SBUS */
1351 case DEV_FORE_PCA200E:
1353 * Reset i960 by setting and clearing RESET
1355 PCA200E_HCR_INIT(*fup->fu_ctlreg, PCA200E_RESET);
1357 PCA200E_HCR_CLR(*fup->fu_ctlreg, PCA200E_RESET);
1371 *******************************************************************
1373 * Loadable Module Support
1375 *******************************************************************
1380 * Generic module load processing
1382 * This function is called by an OS-specific function when this
1383 * module is being loaded.
1389 * 0 load was successful
1390 * errno load failed - reason indicated
1403 /* Problems, clean up */
1411 * Generic module unload processing
1413 * This function is called by an OS-specific function when this
1414 * module is being unloaded.
1420 * 0 unload was successful
1421 * errno unload failed - reason indicated
1430 * OK, try to clean up our mess
1439 * Loadable driver description
1441 static struct vdldrv fore_drv = {
1442 VDMAGIC_DRV, /* Device Driver */
1443 "fore_mod", /* name */
1444 &fore_ops, /* dev_ops */
1453 * Loadable module support entry point
1455 * This is the routine called by the vd driver for all loadable module
1456 * functions for this pseudo driver. This routine name must be specified
1457 * on the modload(1) command. This routine will be called whenever the
1458 * modload(1), modunload(1) or modstat(1) commands are issued for this
1462 * cmd vd command code
1463 * vdp pointer to vd driver's structure
1464 * vdi pointer to command-specific vdioctl_* structure
1465 * vds pointer to status structure (VDSTAT only)
1468 * 0 command was successful
1469 * errno command failed - reason indicated
1473 fore_mod(cmd, vdp, vdi, vds)
1487 * We dont support any user configuration
1489 err = fore_doload();
1491 /* Let vd driver know about us */
1492 vdp->vdd_vdtab = (struct vdlinkage *)&fore_drv;
1499 err = fore_dounload();
1507 /* Not much to say at the moment */
1512 log(LOG_ERR, "fore_mod: Unknown vd command 0x%x\n", cmd);
1524 * Driver entry points
1526 static struct cdevsw fore_cdev = {
1528 /* close */ noclose,
1530 /* write */ nowrite,
1531 /* ioctl */ noioctl,
1534 /* strategy */ nostrategy,
1538 /* psize */ nopsize,
1545 * Loadable device driver module description
1548 MOD_DEV("fore_mod", LM_DT_CHAR, -1, (void *)&fore_cdev);
1550 MOD_DEV(fore, LM_DT_CHAR, -1, (void *)&fore_cdev);
1555 * Loadable module support "load" entry point
1557 * This is the routine called by the lkm driver whenever the
1558 * modload(1) command is issued for this module.
1561 * lkmtp pointer to lkm drivers's structure
1562 * cmd lkm command code
1565 * 0 command was successful
1566 * errno command failed - reason indicated
1570 fore_load(lkmtp, cmd)
1571 struct lkm_table *lkmtp;
1574 return(fore_doload());
1579 * Loadable module support "unload" entry point
1581 * This is the routine called by the lkm driver whenever the
1582 * modunload(1) command is issued for this module.
1585 * lkmtp pointer to lkm drivers's structure
1586 * cmd lkm command code
1589 * 0 command was successful
1590 * errno command failed - reason indicated
1594 fore_unload(lkmtp, cmd)
1595 struct lkm_table *lkmtp;
1598 return(fore_dounload());
1603 * Loadable module support entry point
1605 * This is the routine called by the lkm driver for all loadable module
1606 * functions for this driver. This routine name must be specified
1607 * on the modload(1) command. This routine will be called whenever the
1608 * modload(1), modunload(1) or modstat(1) commands are issued for this
1612 * lkmtp pointer to lkm drivers's structure
1613 * cmd lkm command code
1617 * 0 command was successful
1618 * errno command failed - reason indicated
1622 fore_mod(lkmtp, cmd, ver)
1623 struct lkm_table *lkmtp;
1628 DISPATCH(lkmtp, cmd, ver, fore_load, fore_unload, nosys);
1630 DISPATCH(lkmtp, cmd, ver, fore_load, fore_unload, lkm_nullcmd);
1634 #endif /* __FreeBSD__ */
1636 #endif /* ATM_LINKED */