dpt_pci.c revision 32801
132801Sjulian/* 232801Sjulian * Copyright (c) 1997 by Simon Shapiro 332801Sjulian * All Rights Reserved 432801Sjulian * 532801Sjulian * Redistribution and use in source and binary forms, with or without 632801Sjulian * modification, are permitted provided that the following conditions 732801Sjulian * are met: 832801Sjulian * 1. Redistributions of source code must retain the above copyright 932801Sjulian * notice, this list of conditions, and the following disclaimer, 1032801Sjulian * without modification, immediately at the beginning of the file. 1132801Sjulian * 2. Redistributions in binary form must reproduce the above copyright 1232801Sjulian * notice, this list of conditions and the following disclaimer in the 1332801Sjulian * documentation and/or other materials provided with the distribution. 1432801Sjulian * 3. The name of the author may not be used to endorse or promote products 1532801Sjulian * derived from this software without specific prior written permission. 1632801Sjulian * 1732801Sjulian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1832801Sjulian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1932801Sjulian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2032801Sjulian * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 2132801Sjulian * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2232801Sjulian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2332801Sjulian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2432801Sjulian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2532801Sjulian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2632801Sjulian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2732801Sjulian * SUCH DAMAGE. 2832801Sjulian * 2932801Sjulian */ 3032801Sjulian 3132801Sjulian/* 3232801Sjulian * dptpci.c: Pseudo device drivers for DPT on PCI on FreeBSD 3332801Sjulian * 3432801Sjulian * caveats: We may need an eisa and an isa files too 3532801Sjulian */ 3632801Sjulian 3732801Sjulian#ident "$Id: dpt_pci.c,v 1.10 1998/01/21 04:38:47 ShimonR Exp $" 3832801Sjulian 3932801Sjulian#include "opt_dpt.h" 4032801Sjulian#include <pci.h> 4132801Sjulian 4232801Sjulian#include <sys/param.h> 4332801Sjulian#include <sys/systm.h> 4432801Sjulian#include <sys/malloc.h> 4532801Sjulian#include <sys/buf.h> 4632801Sjulian#include <sys/proc.h> 4732801Sjulian#include <sys/kernel.h> 4832801Sjulian 4932801Sjulian#include <scsi/scsi_all.h> 5032801Sjulian#include <scsi/scsi_message.h> 5132801Sjulian#include <scsi/scsiconf.h> 5232801Sjulian 5332801Sjulian#include <pci/pcireg.h> 5432801Sjulian#include <sys/queue.h> 5532801Sjulian#include <pci/pcivar.h> 5632801Sjulian 5732801Sjulian#include <sys/dpt.h> 5832801Sjulian#include <pci/dpt_pci.h> 5932801Sjulian 6032801Sjulian#include <machine/clock.h> 6132801Sjulian 6232801Sjulian#include <vm/vm.h> 6332801Sjulian#include <vm/vm_param.h> 6432801Sjulian#include <vm/pmap.h> 6532801Sjulian 6632801Sjulian#define PCI_BASEADR0 PCI_MAP_REG_START /* I/O Address */ 6732801Sjulian#define PCI_BASEADR1 PCI_MAP_REG_START + 4 /* Mem I/O Address */ 6832801Sjulian 6932801Sjulian#define ISA_PRIMARY_WD_ADDRESS 0x1f8 7032801Sjulian 7132801Sjulian/* Global variables */ 7232801Sjulian 7332801Sjulianint dpt_controllers_present = 0; 7432801Sjulian 7532801Sjulian/* Function Prototypes */ 7632801Sjulian 7732801Sjulianchar *dpt_pci_probe(pcici_t tag, pcidi_t type); 7832801Sjulianvoid dpt_pci_attach(pcici_t config_id, int unit); 7932801Sjulianint dpt_pci_shutdown(int foo, int bar); 8032801Sjulian 8132801Sjulianextern struct cdevsw dpt_cdevsw; 8232801Sjulian 8332801Sjulianstatic struct pci_device dpt_pci_driver = 8432801Sjulian{ 8532801Sjulian "dpt", 8632801Sjulian dpt_pci_probe, 8732801Sjulian dpt_pci_attach, 8832801Sjulian &dpt_unit, 8932801Sjulian dpt_pci_shutdown 9032801Sjulian}; 9132801Sjulian 9232801SjulianDATA_SET(pcidevice_set, dpt_pci_driver); 9332801Sjulian 9432801Sjulian/* 9532801Sjulian * Probe the PCI device. 9632801Sjulian * Some of this work will have to be duplicated in _attach 9732801Sjulian * because we do not know for sure how the two relate. 9832801Sjulian */ 9932801Sjulian 10032801Sjulianchar * 10132801Sjuliandpt_pci_probe(pcici_t tag, pcidi_t type) 10232801Sjulian{ 10332801Sjulian static char silly_message[64]; 10432801Sjulian static int already_announced = 0; 10532801Sjulian 10632801Sjulian u_int32_t dpt_id; 10732801Sjulian u_int32_t command; 10832801Sjulian u_int32_t class; 10932801Sjulian 11032801Sjulian#define pci_device tag.cfg2.port 11132801Sjulian#define pci_bus tag.cfg2.forward 11232801Sjulian#define pci_index tag.cfg2.enable 11332801Sjulian 11432801Sjulian#ifndef PCI_COMMAND_MASTER_ENABLE 11532801Sjulian#define PCI_COMMAND_MASTER_ENABLE 0x00000004 11632801Sjulian#endif 11732801Sjulian 11832801Sjulian#ifndef PCI_SUBCLASS_MASS_STORAGE_SCSI 11932801Sjulian#define PCI_SUBCLASS_MASS_STORAGE_SCSI 0x00000000 12032801Sjulian#endif 12132801Sjulian 12232801Sjulian if ( !already_announced ) { 12332801Sjulian printf("DPT: PCI SCSI HBA Driver, version %d.%d.%d\n", 12432801Sjulian DPT_RELEASE, DPT_VERSION, DPT_PATCH); 12532801Sjulian ++already_announced; 12632801Sjulian } 12732801Sjulian 12832801Sjulian if ((dpt_id = (type & 0xffff0000) >> 16) == DPT_DEVICE_ID) { 12932801Sjulian /* This one appears to belong to us, but what is it? */ 13032801Sjulian class = pci_conf_read(tag, PCI_CLASS_REG); 13132801Sjulian if (((class & PCI_CLASS_MASK) == PCI_CLASS_MASS_STORAGE) && 13232801Sjulian ((class & PCI_SUBCLASS_MASK) == PCI_SUBCLASS_MASS_STORAGE_SCSI) ) { 13332801Sjulian /* It is a SCSI storage device. How do talk to it? */ 13432801Sjulian command = pci_conf_read(tag, PCI_COMMAND_STATUS_REG); 13532801Sjulian#ifdef DPT_ALLOW_MEMIO 13632801Sjulian if ( ((command & PCI_COMMAND_IO_ENABLE) == 0) 13732801Sjulian && ((command & PCI_COMMAND_MEM_ENABLE) == 0) ) 13832801Sjulian#else 13932801Sjulian if ( ((command & PCI_COMMAND_IO_ENABLE) == 0) ) 14032801Sjulian#endif /* DPT_ALLOW_MEMIO */ 14132801Sjulian { 14232801Sjulian printf("DPT: Cannot map the controller registers :-(\n"); 14332801Sjulian return(NULL); 14432801Sjulian } 14532801Sjulian } else { 14632801Sjulian printf("DPT: Device is not Mass Storage, nor SCSI controller\n"); 14732801Sjulian return(NULL); 14832801Sjulian } 14932801Sjulian 15032801Sjulian command = pci_conf_read(tag, PCI_COMMAND_STATUS_REG); 15132801Sjulian if ( (command & PCI_COMMAND_MASTER_ENABLE) == 0 ) { 15232801Sjulian printf("DPT: Cannot be functional without BUSMASTER. :-(\n"); 15332801Sjulian return (NULL); 15432801Sjulian } 15532801Sjulian 15632801Sjulian#ifdef DPT_DEBUG_PCI 15732801Sjulian printf("DPT: Controller is %s mapable\n", 15832801Sjulian (command & PCI_COMMAND_MEM_ENABLE) 15932801Sjulian ? "MEMORY" 16032801Sjulian : ((command & PCI_COMMAND_IO_ENABLE) 16132801Sjulian ? "I/O" 16232801Sjulian : "NOT")); 16332801Sjulian#endif 16432801Sjulian return ("DPT Caching SCSI RAID Controller"); 16532801Sjulian } 16632801Sjulian 16732801Sjulian#if defined(DPT_DEBUG_PCI) && defined(DPT_DEBUG_WARN) 16832801Sjulian printf("DPT: Unknown Controller Type %x Found\n", dpt_id); 16932801Sjulian printf(" (class = %x, command = %x\n", class, command); 17032801Sjulian#endif 17132801Sjulian return (NULL); 17232801Sjulian} 17332801Sjulian 17432801Sjulianvoid 17532801Sjuliandpt_pci_attach(pcici_t config_id, int unit) 17632801Sjulian{ 17732801Sjulian int ospl; 17832801Sjulian int result; 17932801Sjulian int ndx; 18032801Sjulian 18132801Sjulian vm_offset_t vaddr; 18232801Sjulian vm_offset_t paddr; 18332801Sjulian u_int16_t io_base; 18432801Sjulian u_int32_t command; 18532801Sjulian u_int32_t data; 18632801Sjulian dpt_conf_t *config; 18732801Sjulian dpt_softc_t *dpt; 18832801Sjulian 18932801Sjulian if (dpt_controllers_present >= DPT_MAX_ADAPTERS) { 19032801Sjulian printf("dpt%d: More than %d Adapters found! Adapter rejected\n", 19132801Sjulian unit, DPT_MAX_ADAPTERS); 19232801Sjulian return; 19332801Sjulian } 19432801Sjulian 19532801Sjulian if ((dpt = (dpt_softc_t *) malloc(sizeof(dpt_softc_t), M_DEVBUF, M_NOWAIT)) 19632801Sjulian == NULL) { 19732801Sjulian printf("dpt%d: Failed to allocate %d bytes for a DPT softc\n", 19832801Sjulian unit, sizeof(dpt_softc_t)); 19932801Sjulian return; 20032801Sjulian } 20132801Sjulian 20232801Sjulian /* 20332801Sjulian * Initialize the queues. See dpt.h for details. We do this here, 20432801Sjulian * as we may get hit with interrupts at any moment and we want to 20532801Sjulian * have a minimal structure in place to handle them. We also want to 20632801Sjulian * register interrupts correctly. To do so, we need a valid dpt 20732801Sjulian * structure. To have that, we need this minimal setup here. 20832801Sjulian */ 20932801Sjulian bzero(dpt, sizeof(dpt_softc_t)); 21032801Sjulian 21132801Sjulian TAILQ_INIT(&dpt->free_ccbs); 21232801Sjulian TAILQ_INIT(&dpt->waiting_ccbs); 21332801Sjulian TAILQ_INIT(&dpt->submitted_ccbs); 21432801Sjulian TAILQ_INIT(&dpt->completed_ccbs); 21532801Sjulian 21632801Sjulian if (TAILQ_EMPTY(&dpt_softc_list)) { 21732801Sjulian TAILQ_INIT(&dpt_softc_list); 21832801Sjulian } 21932801Sjulian 22032801Sjulian TAILQ_INSERT_TAIL(&dpt_softc_list, dpt, links); 22132801Sjulian dpt->queue_status = DPT_QUEUES_NONE_ACTIVE; 22232801Sjulian dpt->commands_processed = 0; 22332801Sjulian 22432801Sjulian#ifdef DPT_MEASURE_PERFORMANCE 22532801Sjulian /* Zero out all command counters */ 22632801Sjulian bzero((void *)&dpt->performance, sizeof(dpt_perf_t)); 22732801Sjulian for ( ndx = 0; ndx < 256; ndx ++ ) 22832801Sjulian dpt->performance.min_command_time[ndx] = BIG_ENOUGH; 22932801Sjulian 23032801Sjulian dpt->performance.min_intr_time = BIG_ENOUGH; 23132801Sjulian dpt->performance.min_waiting_time = BIG_ENOUGH; 23232801Sjulian dpt->performance.min_submit_time = BIG_ENOUGH; 23332801Sjulian dpt->performance.min_complete_time = BIG_ENOUGH; 23432801Sjulian dpt->performance.min_eata_tries = BIG_ENOUGH; 23532801Sjulian 23632801Sjulian for (ndx = 0; ndx < 10; ndx++ ) { 23732801Sjulian dpt->performance.read_by_size_min_time[ndx] = BIG_ENOUGH; 23832801Sjulian dpt->performance.write_by_size_min_time[ndx] = BIG_ENOUGH; 23932801Sjulian } 24032801Sjulian#endif /* DPT_MEASURE_PERFORMANCE */ 24132801Sjulian 24232801Sjulian dpt->unit = unit; 24332801Sjulian dpt->handle_interrupts = 0; /* 24432801Sjulian * Do not set to 1 until all 24532801Sjulian * initialization is done 24632801Sjulian */ 24732801Sjulian dpt->v_membase = NULL; 24832801Sjulian dpt->p_membase = NULL; 24932801Sjulian io_base = 0; 25032801Sjulian vaddr = 0; 25132801Sjulian paddr = 0; 25232801Sjulian command = pci_conf_read(config_id, PCI_COMMAND_STATUS_REG); 25332801Sjulian 25432801Sjulian#ifdef DPT_ALLOW_MEMIO 25532801Sjulian if ( (command & PCI_COMMAND_MEM_ENABLE) == 0 ) { 25632801Sjulian#ifdef DPT_DEBUG_PCI 25732801Sjulian printf("dpt%d: Cannot be memory mapped\n", unit); 25832801Sjulian#endif 25932801Sjulian force_io: 26032801Sjulian if ((command & PCI_COMMAND_IO_ENABLE) == 0 ) { 26132801Sjulian printf("dpt%d: Cannot be I/O mapped either :-(\n", unit); 26232801Sjulian free(dpt, M_DEVBUF); 26332801Sjulian return; 26432801Sjulian } else { 26532801Sjulian data = pci_conf_read(config_id, PCI_MAP_REG_START); 26632801Sjulian if ( pci_map_port(config_id, PCI_MAP_REG_START, &io_base) == 0 ) { 26732801Sjulian#ifdef DPT_DEBUG_ERROR 26832801Sjulian printf("dpt%d: Failed to map as I/O :-(\n", unit); 26932801Sjulian#endif 27032801Sjulian free(dpt, M_DEVBUF); 27132801Sjulian return; 27232801Sjulian } else { 27332801Sjulian dpt->io_base = io_base + 0x10; 27432801Sjulian#ifdef DPT_DEBUG_PCI 27532801Sjulian printf("dpt%d: Mapped registers to I/O space, " 27632801Sjulian "starting at %x\n", 27732801Sjulian dpt->unit, dpt->io_base); 27832801Sjulian#endif 27932801Sjulian } 28032801Sjulian } 28132801Sjulian } else { 28232801Sjulian if ( pci_map_mem(config_id, PCI_MAP_REG_START + 4, &vaddr, 28332801Sjulian &paddr) == 0 ) { 28432801Sjulian#ifdef DPT_DEBUG_ERROR 28532801Sjulian printf("dpt%d: Failed to map as MEMORY.\n" 28632801Sjulian " Attemting to force I/O mapping\n", unit); 28732801Sjulian#endif 28832801Sjulian goto force_io; 28932801Sjulian } else { 29032801Sjulian dpt->v_membase = (volatile u_int8_t *)(vaddr + 0x10); 29132801Sjulian dpt->p_membase = (volatile u_int8_t *)(paddr + 0x10); 29232801Sjulian#ifdef DPT_DEBUG_PCI 29332801Sjulian printf("dpt%d: Mapped registers to MEMORY space, " 29432801Sjulian "starting at %x/%x\n", 29532801Sjulian dpt->unit, dpt->v_membase, dpt->p_membase); 29632801Sjulian#endif 29732801Sjulian } 29832801Sjulian } 29932801Sjulian 30032801Sjulian#else /* !DPT_ALLOW_MEMIO */ 30132801Sjulian data = pci_conf_read(config_id, PCI_MAP_REG_START); 30232801Sjulian if ((command & PCI_COMMAND_IO_ENABLE) == 0 ) { 30332801Sjulian printf("dpt%d: Registers cannot be I/O mapped :-(\n", unit); 30432801Sjulian free(dpt, M_DEVBUF); 30532801Sjulian return; 30632801Sjulian } else { 30732801Sjulian if ( pci_map_port(config_id, PCI_MAP_REG_START, &io_base) == 0 ) { 30832801Sjulian#ifdef DPT_DEBUG_ERROR 30932801Sjulian printf("dpt%d: Failed to map registers as I/O :-(\n", unit); 31032801Sjulian#endif 31132801Sjulian free(dpt, M_DEVBUF); 31232801Sjulian return; 31332801Sjulian } else { 31432801Sjulian dpt->io_base = io_base + 0x10; 31532801Sjulian#ifdef DPT_DEBUG_PCI 31632801Sjulian printf("dpt%d: Mapped registers to I/O space, starting at %x\n", 31732801Sjulian dpt->unit, dpt->io_base); 31832801Sjulian#endif 31932801Sjulian } 32032801Sjulian } 32132801Sjulian#endif /* !DPT_ALLOW_MEMIO */ 32232801Sjulian 32332801Sjulian if (pci_map_int(config_id, dpt_intr, (void *)dpt, &cam_imask) == 0) { 32432801Sjulian#ifdef DPT_DEBUG_WARN 32532801Sjulian printf("dpt%d: Failed to map interrupt :-(\n", unit); 32632801Sjulian#endif 32732801Sjulian free(dpt, M_DEVBUF); 32832801Sjulian return; 32932801Sjulian } 33032801Sjulian 33132801Sjulian /* If the DPT is mapped as an IDE controller, let it be IDE controller */ 33232801Sjulian if (io_base == (ISA_PRIMARY_WD_ADDRESS)) { 33332801Sjulian#ifdef DPT_DEBUG_WARN 33432801Sjulian printf("dpt%d: Mapped as an IDE controller. " 33532801Sjulian "Disabling SCSI setup\n", unit); 33632801Sjulian#endif 33732801Sjulian free(dpt, M_DEVBUF); 33832801Sjulian return; 33932801Sjulian } else { 34032801Sjulian if ((config = dpt_get_conf(dpt, 0xc1, 7, 34132801Sjulian sizeof(dpt_conf_t), 1)) == NULL) { 34232801Sjulian#ifdef DPT_DEBUG_ERROR 34332801Sjulian printf("dpt%d: Failed to get board configuration (%x)\n", 34432801Sjulian unit, BaseRegister(dpt)); 34532801Sjulian#endif 34632801Sjulian free(dpt, M_DEVBUF); 34732801Sjulian return; 34832801Sjulian } 34932801Sjulian } 35032801Sjulian 35132801Sjulian dpt->max_id = config->MAX_ID; 35232801Sjulian dpt->max_lun = config->MAX_LUN; 35332801Sjulian dpt->irq = config->IRQ; 35432801Sjulian dpt->channels = config->MAX_CHAN; 35532801Sjulian dpt->dma_channel = (8 - config->DMA_channel) & 7; 35632801Sjulian 35732801Sjulian#ifdef DPT_DEBUG_SETUP 35832801Sjulian printf("dpt%d: max_id = %d, max_chan = %d, max_lun = %d\n", 35932801Sjulian dpt->unit, dpt->max_id, dpt->channels, dpt->max_lun); 36032801Sjulian#endif 36132801Sjulian 36232801Sjulian if (result = dpt_setup(dpt, config)) { 36332801Sjulian free(config, M_TEMP); 36432801Sjulian free(dpt, M_DEVBUF); 36532801Sjulian printf("dpt%d: dpt_setup failed (%d). Driver Disabled :-(\n", 36632801Sjulian dpt->unit, result); 36732801Sjulian } else { 36832801Sjulian /* clean up the informational data, and display */ 36932801Sjulian char clean_vendor[9]; 37032801Sjulian char clean_model[17]; 37132801Sjulian char clean_firmware[5]; 37232801Sjulian char clean_protocol[5]; 37332801Sjulian char clean_other[7]; 37432801Sjulian 37532801Sjulian int ndx; 37632801Sjulian 37732801Sjulian strncpy(clean_other, dpt->board_data.otherData, 8); 37832801Sjulian clean_other[6] = '\0'; 37932801Sjulian for (ndx = 5; ndx >= 0; ndx--) { 38032801Sjulian if (clean_other[ndx] == ' ') 38132801Sjulian clean_other[ndx] = '\0'; 38232801Sjulian else 38332801Sjulian break; 38432801Sjulian } 38532801Sjulian strncpy(dpt->board_data.otherData, clean_other, 6); 38632801Sjulian 38732801Sjulian strncpy(clean_vendor, dpt->board_data.vendor, 8); 38832801Sjulian clean_vendor[8] = '\0'; 38932801Sjulian for (ndx = 7; ndx >= 0; ndx--) { 39032801Sjulian if (clean_vendor[ndx] == ' ') 39132801Sjulian clean_vendor[ndx] = '\0'; 39232801Sjulian else 39332801Sjulian break; 39432801Sjulian } 39532801Sjulian strncpy(dpt->board_data.vendor, clean_vendor, 8); 39632801Sjulian 39732801Sjulian strncpy(clean_model, dpt->board_data.modelNum, 16); 39832801Sjulian clean_model[16] = '\0'; 39932801Sjulian for (ndx = 15; ndx >= 0; ndx--) { 40032801Sjulian if (clean_model[ndx] == ' ') 40132801Sjulian clean_model[ndx] = '\0'; 40232801Sjulian else 40332801Sjulian break; 40432801Sjulian } 40532801Sjulian strncpy(dpt->board_data.modelNum, clean_model, 16); 40632801Sjulian 40732801Sjulian strncpy(clean_firmware, dpt->board_data.firmware, 4); 40832801Sjulian clean_firmware[4] = '\0'; 40932801Sjulian for (ndx = 3; ndx >= 0; ndx--) { 41032801Sjulian if (clean_firmware[ndx] == ' ') 41132801Sjulian clean_firmware[ndx] = '\0'; 41232801Sjulian else 41332801Sjulian break; 41432801Sjulian } 41532801Sjulian strncpy(dpt->board_data.firmware, clean_firmware, 4); 41632801Sjulian 41732801Sjulian strncpy(clean_protocol, dpt->board_data.protocol, 4); 41832801Sjulian clean_protocol[4] = '\0'; 41932801Sjulian for (ndx = 3; ndx >= 0; ndx--) { 42032801Sjulian if (clean_protocol[ndx] == ' ') 42132801Sjulian clean_protocol[ndx] = '\0'; 42232801Sjulian else 42332801Sjulian break; 42432801Sjulian } 42532801Sjulian strncpy(dpt->board_data.protocol, clean_protocol, 4); 42632801Sjulian 42732801Sjulian dpt_detect_cache(dpt); 42832801Sjulian 42932801Sjulian printf("dpt%d: %s type %x, model %s firmware %s, Protocol %s \n" 43032801Sjulian " on port %x with %s cache. LED = %s\n", 43132801Sjulian dpt->unit, clean_vendor, dpt->board_data.deviceType, 43232801Sjulian clean_model, clean_firmware, clean_protocol, dpt->io_base, 43332801Sjulian (dpt->cache_type == DPT_NO_CACHE) 43432801Sjulian ? "Disabled" 43532801Sjulian : (dpt->cache_type == DPT_CACHE_WRITETHROUGH) 43632801Sjulian ? "Write-Through" 43732801Sjulian : "Write-Back", 43832801Sjulian i2bin(dpt_blinking_led(dpt), 8)); 43932801Sjulian printf("dpt%d: Enabled Options:\n", dpt->unit); 44032801Sjulian#ifdef DPT_LOST_IRQ 44132801Sjulian printf(" Recover Lost Interrupts\n"); 44232801Sjulian#endif 44332801Sjulian#ifdef DPT_VERIFY_HINTR 44432801Sjulian printf(" Verify Lost Transactions\n"); 44532801Sjulian#endif 44632801Sjulian#ifdef DPT_RESTRICTED_FREELIST 44732801Sjulian printf(" Restrict the Freelist Size\n"); 44832801Sjulian#endif 44932801Sjulian#ifdef DPT_MEASURE_PERFORMANCE 45032801Sjulian printf(" Collect Metrics\n"); 45132801Sjulian#endif 45232801Sjulian#ifdef DPT_FREELIST_IS_STACK 45332801Sjulian printf(" Optimize CPU Cache\n"); 45432801Sjulian#endif 45532801Sjulian#ifdef DPT_HANDLE_TIMEOUTS 45632801Sjulian printf(" Handle Timeouts\n"); 45732801Sjulian#endif 45832801Sjulian#ifdef DPT_ALLOW_MEMIO 45932801Sjulian printf(" Allow I/O to be Memeory Mapped\n"); 46032801Sjulian#endif 46132801Sjulian#ifdef DPT_HINTR_CHECK_SOFTC 46232801Sjulian printf(" Validate SoftC at Interrupt\n"); 46332801Sjulian#endif 46432801Sjulian 46532801Sjulian /* register shutdown handlers */ 46632801Sjulian result = at_shutdown((bootlist_fn)dpt_shutdown, (void *)dpt, 46732801Sjulian SHUTDOWN_POST_SYNC); 46832801Sjulian switch ( result ) { 46932801Sjulian case 0: 47032801Sjulian#ifdef DPT_DEBUG_SHUTDOWN 47132801Sjulian printf("dpt%d: Shutdown handler registered\n", dpt->unit); 47232801Sjulian#endif 47332801Sjulian break; 47432801Sjulian default: 47532801Sjulian#ifdef DPT_DEBUG_WARN 47632801Sjulian printf("dpt%d: Failed to register shutdown handler (%d)\n", 47732801Sjulian dpt->unit, result); 47832801Sjulian#endif 47932801Sjulian break; 48032801Sjulian } 48132801Sjulian 48232801Sjulian /* Attach SCSI devices */ 48332801Sjulian dpt_attach(dpt); 48432801Sjulian ++dpt_controllers_present; 48532801Sjulian 48632801Sjulian /* 48732801Sjulian * Now we create the DEVFS entry. 48832801Sjulian * This would be normally done from dpt_control.c, 48932801Sjulian * But since it appears to be called before we do here, 49032801Sjulian * We never get the entries made. 49132801Sjulian */ 49232801Sjulian#ifdef DEVFS 49332801Sjulian dpt->devfs_data_token = devfs_add_devswf(&dpt_cdevsw, dpt->unit, DV_CHR, 49432801Sjulian UID_ROOT, GID_WHEEL, 0600, 49532801Sjulian "dpt%d", dpt->unit); 49632801Sjulian dpt->devfs_ctl_token = devfs_add_devswf(&dpt_cdevsw, 49732801Sjulian dpt->unit | SCSI_CONTROL_MASK, 49832801Sjulian DV_CHR, 49932801Sjulian UID_ROOT, GID_WHEEL, 0600, 50032801Sjulian "dpt%d.ctl", dpt->unit); 50132801Sjulian#endif 50232801Sjulian } 50332801Sjulian} 50432801Sjulian 50532801Sjulianint 50632801Sjuliandpt_pci_shutdown(int foo, int bar) 50732801Sjulian{ 50832801Sjulian#ifdef DPT_DEBUG_WARN 50932801Sjulian printf("dpt_pci_shutdown(%x, %x)\n", foo, bar); 51032801Sjulian#endif 51132801Sjulian return (0); 51232801Sjulian} 51332801Sjulian 51432801Sjulian/* End of the DPT PCI part of the driver */ 51532801Sjulian 51632801Sjulian/* 51732801Sjulian * Hello emacs, these are the 51832801Sjulian * Local Variables: 51932801Sjulian * c-indent-level: 8 52032801Sjulian * c-continued-statement-offset: 8 52132801Sjulian * c-continued-brace-offset: 0 52232801Sjulian * c-brace-offset: -8 52332801Sjulian * c-brace-imaginary-offset: 0 52432801Sjulian * c-argdecl-indent: 8 52532801Sjulian * c-label-offset: -8 52632801Sjulian * c++-hanging-braces: 1 52732801Sjulian * c++-access-specifier-offset: -8 52832801Sjulian * c++-empty-arglist-indent: 8 52932801Sjulian * c++-friend-offset: 0 53032801Sjulian * End: 53132801Sjulian */ 532