^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) Linux Driver for BusLogic MultiMaster and FlashPoint SCSI Host Adapters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) Copyright 1995-1998 by Leonard N. Zubkoff <lnz@dandelion.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) The author respectfully requests that any modifications to this software be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) sent directly to him for evaluation and testing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) Special thanks to Wayne Yen, Jin-Lon Hon, and Alex Win of BusLogic, whose
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) advice has been invaluable, to David Gentzel, for writing the original Linux
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) BusLogic driver, and to Paul Gortmaker, for being such a dedicated test site.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) Finally, special thanks to Mylex/BusLogic for making the FlashPoint SCCB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) Manager available as freely redistributable source code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define blogic_drvr_version "2.1.17"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define blogic_drvr_date "12 September 2013"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/blkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/msdos_partition.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <scsi/scsicam.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <asm/dma.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <scsi/scsi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <scsi/scsi_cmnd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <scsi/scsi_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <scsi/scsi_host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include <scsi/scsi_tcq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include "BusLogic.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #include "FlashPoint.c"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #ifndef FAILURE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define FAILURE (-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) static struct scsi_host_template blogic_template;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) blogic_drvr_options_count is a count of the number of BusLogic Driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) Options specifications provided via the Linux Kernel Command Line or via
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) the Loadable Kernel Module Installation Facility.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) static int blogic_drvr_options_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) blogic_drvr_options is an array of Driver Options structures representing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) BusLogic Driver Options specifications provided via the Linux Kernel Command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) Line or via the Loadable Kernel Module Installation Facility.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) static struct blogic_drvr_options blogic_drvr_options[BLOGIC_MAX_ADAPTERS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) BusLogic can be assigned a string by insmod.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #ifdef MODULE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) static char *BusLogic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) module_param(BusLogic, charp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) blogic_probe_options is a set of Probe Options to be applied across
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) all BusLogic Host Adapters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) static struct blogic_probe_options blogic_probe_options;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) blogic_global_options is a set of Global Options to be applied across
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) all BusLogic Host Adapters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static struct blogic_global_options blogic_global_options;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static LIST_HEAD(blogic_host_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) blogic_probeinfo_count is the number of entries in blogic_probeinfo_list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static int blogic_probeinfo_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) blogic_probeinfo_list is the list of I/O Addresses and Bus Probe Information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) to be checked for potential BusLogic Host Adapters. It is initialized by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) interrogating the PCI Configuration Space on PCI machines as well as from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) list of standard BusLogic I/O Addresses.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) static struct blogic_probeinfo *blogic_probeinfo_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) blogic_cmd_failure_reason holds a string identifying the reason why a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) call to blogic_cmd failed. It is only non-NULL when blogic_cmd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) returns a failure code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static char *blogic_cmd_failure_reason;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) blogic_announce_drvr announces the Driver Version and Date, Author's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) Name, Copyright Notice, and Electronic Mail Address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) static void blogic_announce_drvr(struct blogic_adapter *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) blogic_announce("***** BusLogic SCSI Driver Version " blogic_drvr_version " of " blogic_drvr_date " *****\n", adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) blogic_announce("Copyright 1995-1998 by Leonard N. Zubkoff <lnz@dandelion.com>\n", adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) blogic_drvr_info returns the Host Adapter Name to identify this SCSI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) Driver and Host Adapter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) static const char *blogic_drvr_info(struct Scsi_Host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) struct blogic_adapter *adapter =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) (struct blogic_adapter *) host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return adapter->full_model;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) blogic_init_ccbs initializes a group of Command Control Blocks (CCBs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) for Host Adapter from the blk_size bytes located at blk_pointer. The newly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) created CCBs are added to Host Adapter's free list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) static void blogic_init_ccbs(struct blogic_adapter *adapter, void *blk_pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) int blk_size, dma_addr_t blkp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) struct blogic_ccb *ccb = (struct blogic_ccb *) blk_pointer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) unsigned int offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) memset(blk_pointer, 0, blk_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) ccb->allocgrp_head = blkp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) ccb->allocgrp_size = blk_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) while ((blk_size -= sizeof(struct blogic_ccb)) >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) ccb->status = BLOGIC_CCB_FREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) ccb->adapter = adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) ccb->dma_handle = (u32) blkp + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) if (blogic_flashpoint_type(adapter)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) ccb->callback = blogic_qcompleted_ccb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) ccb->base_addr = adapter->fpinfo.base_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) ccb->next = adapter->free_ccbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) ccb->next_all = adapter->all_ccbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) adapter->free_ccbs = ccb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) adapter->all_ccbs = ccb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) adapter->alloc_ccbs++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) ccb++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) offset += sizeof(struct blogic_ccb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) blogic_create_initccbs allocates the initial CCBs for Host Adapter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static bool __init blogic_create_initccbs(struct blogic_adapter *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) int blk_size = BLOGIC_CCB_GRP_ALLOCSIZE * sizeof(struct blogic_ccb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) void *blk_pointer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) dma_addr_t blkp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) while (adapter->alloc_ccbs < adapter->initccbs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) blk_pointer = dma_alloc_coherent(&adapter->pci_device->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) blk_size, &blkp, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if (blk_pointer == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) blogic_err("UNABLE TO ALLOCATE CCB GROUP - DETACHING\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) blogic_init_ccbs(adapter, blk_pointer, blk_size, blkp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) blogic_destroy_ccbs deallocates the CCBs for Host Adapter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) static void blogic_destroy_ccbs(struct blogic_adapter *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) struct blogic_ccb *next_ccb = adapter->all_ccbs, *ccb, *lastccb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) adapter->all_ccbs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) adapter->free_ccbs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) while ((ccb = next_ccb) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) next_ccb = ccb->next_all;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) if (ccb->allocgrp_head) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) if (lastccb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) dma_free_coherent(&adapter->pci_device->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) lastccb->allocgrp_size, lastccb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) lastccb->allocgrp_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) lastccb = ccb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (lastccb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) dma_free_coherent(&adapter->pci_device->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) lastccb->allocgrp_size, lastccb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) lastccb->allocgrp_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) blogic_create_addlccbs allocates Additional CCBs for Host Adapter. If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) allocation fails and there are no remaining CCBs available, the Driver Queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) Depth is decreased to a known safe value to avoid potential deadlocks when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) multiple host adapters share the same IRQ Channel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) static void blogic_create_addlccbs(struct blogic_adapter *adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) int addl_ccbs, bool print_success)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) int blk_size = BLOGIC_CCB_GRP_ALLOCSIZE * sizeof(struct blogic_ccb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) int prev_alloc = adapter->alloc_ccbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) void *blk_pointer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) dma_addr_t blkp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if (addl_ccbs <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) while (adapter->alloc_ccbs - prev_alloc < addl_ccbs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) blk_pointer = dma_alloc_coherent(&adapter->pci_device->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) blk_size, &blkp, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (blk_pointer == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) blogic_init_ccbs(adapter, blk_pointer, blk_size, blkp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) if (adapter->alloc_ccbs > prev_alloc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (print_success)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) blogic_notice("Allocated %d additional CCBs (total now %d)\n", adapter, adapter->alloc_ccbs - prev_alloc, adapter->alloc_ccbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) blogic_notice("Failed to allocate additional CCBs\n", adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) if (adapter->drvr_qdepth > adapter->alloc_ccbs - adapter->tgt_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) adapter->drvr_qdepth = adapter->alloc_ccbs - adapter->tgt_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) adapter->scsi_host->can_queue = adapter->drvr_qdepth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) blogic_alloc_ccb allocates a CCB from Host Adapter's free list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) allocating more memory from the Kernel if necessary. The Host Adapter's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) Lock should already have been acquired by the caller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) static struct blogic_ccb *blogic_alloc_ccb(struct blogic_adapter *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) static unsigned long serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) struct blogic_ccb *ccb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) ccb = adapter->free_ccbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) if (ccb != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) ccb->serial = ++serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) adapter->free_ccbs = ccb->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) ccb->next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) if (adapter->free_ccbs == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) blogic_create_addlccbs(adapter, adapter->inc_ccbs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) return ccb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) blogic_create_addlccbs(adapter, adapter->inc_ccbs, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) ccb = adapter->free_ccbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (ccb == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) ccb->serial = ++serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) adapter->free_ccbs = ccb->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) ccb->next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) return ccb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) blogic_dealloc_ccb deallocates a CCB, returning it to the Host Adapter's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) free list. The Host Adapter's Lock should already have been acquired by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) caller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) static void blogic_dealloc_ccb(struct blogic_ccb *ccb, int dma_unmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) struct blogic_adapter *adapter = ccb->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) if (ccb->command != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) scsi_dma_unmap(ccb->command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) if (dma_unmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) dma_unmap_single(&adapter->pci_device->dev, ccb->sensedata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) ccb->sense_datalen, DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) ccb->command = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) ccb->status = BLOGIC_CCB_FREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) ccb->next = adapter->free_ccbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) adapter->free_ccbs = ccb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) blogic_cmd sends the command opcode to adapter, optionally
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) providing paramlen bytes of param and receiving at most
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) replylen bytes of reply; any excess reply data is received but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) discarded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) On success, this function returns the number of reply bytes read from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) the Host Adapter (including any discarded data); on failure, it returns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) -1 if the command was invalid, or -2 if a timeout occurred.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) blogic_cmd is called exclusively during host adapter detection and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) initialization, so performance and latency are not critical, and exclusive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) access to the Host Adapter hardware is assumed. Once the host adapter and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) driver are initialized, the only Host Adapter command that is issued is the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) single byte Execute Mailbox Command operation code, which does not require
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) waiting for the Host Adapter Ready bit to be set in the Status Register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) static int blogic_cmd(struct blogic_adapter *adapter, enum blogic_opcode opcode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) void *param, int paramlen, void *reply, int replylen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) unsigned char *param_p = (unsigned char *) param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) unsigned char *reply_p = (unsigned char *) reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) union blogic_stat_reg statusreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) union blogic_int_reg intreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) unsigned long processor_flag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) int reply_b = 0, result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) long timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) Clear out the Reply Data if provided.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (replylen > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) memset(reply, 0, replylen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) If the IRQ Channel has not yet been acquired, then interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) must be disabled while issuing host adapter commands since a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) Command Complete interrupt could occur if the IRQ Channel was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) previously enabled by another BusLogic Host Adapter or another
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) driver sharing the same IRQ Channel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) if (!adapter->irq_acquired)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) local_irq_save(processor_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) Wait for the Host Adapter Ready bit to be set and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) Command/Parameter Register Busy bit to be reset in the Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) Register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) timeout = 10000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) while (--timeout >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) statusreg.all = blogic_rdstatus(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if (statusreg.sr.adapter_ready && !statusreg.sr.cmd_param_busy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) udelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if (timeout < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) blogic_cmd_failure_reason =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) "Timeout waiting for Host Adapter Ready";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) result = -2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) Write the opcode to the Command/Parameter Register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) adapter->adapter_cmd_complete = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) blogic_setcmdparam(adapter, opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) Write any additional Parameter Bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) timeout = 10000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) while (paramlen > 0 && --timeout >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) Wait 100 microseconds to give the Host Adapter enough
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) time to determine whether the last value written to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) Command/Parameter Register was valid or not. If the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) Command Complete bit is set in the Interrupt Register,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) then the Command Invalid bit in the Status Register will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) be reset if the Operation Code or Parameter was valid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) and the command has completed, or set if the Operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) Code or Parameter was invalid. If the Data In Register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) Ready bit is set in the Status Register, then the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) Operation Code was valid, and data is waiting to be read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) back from the Host Adapter. Otherwise, wait for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) Command/Parameter Register Busy bit in the Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) Register to be reset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) udelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) intreg.all = blogic_rdint(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) statusreg.all = blogic_rdstatus(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) if (intreg.ir.cmd_complete)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) if (adapter->adapter_cmd_complete)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) if (statusreg.sr.datain_ready)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) if (statusreg.sr.cmd_param_busy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) blogic_setcmdparam(adapter, *param_p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) paramlen--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (timeout < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) blogic_cmd_failure_reason =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) "Timeout waiting for Parameter Acceptance";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) result = -2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) The Modify I/O Address command does not cause a Command Complete
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) Interrupt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) if (opcode == BLOGIC_MOD_IOADDR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) statusreg.all = blogic_rdstatus(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) if (statusreg.sr.cmd_invalid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) blogic_cmd_failure_reason =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) "Modify I/O Address Invalid";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) result = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) if (blogic_global_options.trace_config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) blogic_notice("blogic_cmd(%02X) Status = %02X: (Modify I/O Address)\n", adapter, opcode, statusreg.all);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) Select an appropriate timeout value for awaiting command completion.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) switch (opcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) case BLOGIC_INQ_DEV0TO7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) case BLOGIC_INQ_DEV8TO15:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) case BLOGIC_INQ_DEV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) /* Approximately 60 seconds. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) timeout = 60 * 10000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) /* Approximately 1 second. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) timeout = 10000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) Receive any Reply Bytes, waiting for either the Command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) Complete bit to be set in the Interrupt Register, or for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) Interrupt Handler to set the Host Adapter Command Completed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) bit in the Host Adapter structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) while (--timeout >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) intreg.all = blogic_rdint(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) statusreg.all = blogic_rdstatus(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) if (intreg.ir.cmd_complete)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) if (adapter->adapter_cmd_complete)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) if (statusreg.sr.datain_ready) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) if (++reply_b <= replylen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) *reply_p++ = blogic_rddatain(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) blogic_rddatain(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) if (opcode == BLOGIC_FETCH_LOCALRAM &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) statusreg.sr.adapter_ready)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) udelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (timeout < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) blogic_cmd_failure_reason =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) "Timeout waiting for Command Complete";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) result = -2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) Clear any pending Command Complete Interrupt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) blogic_intreset(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) Provide tracing information if requested.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) if (blogic_global_options.trace_config) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) blogic_notice("blogic_cmd(%02X) Status = %02X: %2d ==> %2d:",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) adapter, opcode, statusreg.all, replylen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) reply_b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) if (replylen > reply_b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) replylen = reply_b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) for (i = 0; i < replylen; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) blogic_notice(" %02X", adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) ((unsigned char *) reply)[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) blogic_notice("\n", adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) Process Command Invalid conditions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) if (statusreg.sr.cmd_invalid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) Some early BusLogic Host Adapters may not recover
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) properly from a Command Invalid condition, so if this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) appears to be the case, a Soft Reset is issued to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) Host Adapter. Potentially invalid commands are never
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) attempted after Mailbox Initialization is performed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) so there should be no Host Adapter state lost by a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) Soft Reset in response to a Command Invalid condition.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) udelay(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) statusreg.all = blogic_rdstatus(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) if (statusreg.sr.cmd_invalid || statusreg.sr.rsvd ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) statusreg.sr.datain_ready ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) statusreg.sr.cmd_param_busy ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) !statusreg.sr.adapter_ready ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) !statusreg.sr.init_reqd ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) statusreg.sr.diag_active ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) statusreg.sr.diag_failed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) blogic_softreset(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) udelay(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) blogic_cmd_failure_reason = "Command Invalid";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) result = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) Handle Excess Parameters Supplied conditions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) if (paramlen > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) blogic_cmd_failure_reason = "Excess Parameters Supplied";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) result = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) Indicate the command completed successfully.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) blogic_cmd_failure_reason = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) result = reply_b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) Restore the interrupt status if necessary and return.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) if (!adapter->irq_acquired)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) local_irq_restore(processor_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) blogic_add_probeaddr_isa appends a single ISA I/O Address to the list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) of I/O Address and Bus Probe Information to be checked for potential BusLogic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) Host Adapters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) static void __init blogic_add_probeaddr_isa(unsigned long io_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) struct blogic_probeinfo *probeinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) if (blogic_probeinfo_count >= BLOGIC_MAX_ADAPTERS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) probeinfo = &blogic_probeinfo_list[blogic_probeinfo_count++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) probeinfo->adapter_type = BLOGIC_MULTIMASTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) probeinfo->adapter_bus_type = BLOGIC_ISA_BUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) probeinfo->io_addr = io_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) probeinfo->pci_device = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) blogic_init_probeinfo_isa initializes the list of I/O Address and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) Bus Probe Information to be checked for potential BusLogic SCSI Host Adapters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) only from the list of standard BusLogic MultiMaster ISA I/O Addresses.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) static void __init blogic_init_probeinfo_isa(struct blogic_adapter *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) If BusLogic Driver Options specifications requested that ISA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) Bus Probes be inhibited, do not proceed further.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) if (blogic_probe_options.noprobe_isa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) Append the list of standard BusLogic MultiMaster ISA I/O Addresses.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) if (!blogic_probe_options.limited_isa || blogic_probe_options.probe330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) blogic_add_probeaddr_isa(0x330);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) if (!blogic_probe_options.limited_isa || blogic_probe_options.probe334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) blogic_add_probeaddr_isa(0x334);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) if (!blogic_probe_options.limited_isa || blogic_probe_options.probe230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) blogic_add_probeaddr_isa(0x230);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) if (!blogic_probe_options.limited_isa || blogic_probe_options.probe234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) blogic_add_probeaddr_isa(0x234);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) if (!blogic_probe_options.limited_isa || blogic_probe_options.probe130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) blogic_add_probeaddr_isa(0x130);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) if (!blogic_probe_options.limited_isa || blogic_probe_options.probe134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) blogic_add_probeaddr_isa(0x134);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) #ifdef CONFIG_PCI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) blogic_sort_probeinfo sorts a section of blogic_probeinfo_list in order
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) of increasing PCI Bus and Device Number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) static void __init blogic_sort_probeinfo(struct blogic_probeinfo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) *probeinfo_list, int probeinfo_cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) int last_exchange = probeinfo_cnt - 1, bound, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) while (last_exchange > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) bound = last_exchange;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) last_exchange = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) for (j = 0; j < bound; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) struct blogic_probeinfo *probeinfo1 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) &probeinfo_list[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) struct blogic_probeinfo *probeinfo2 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) &probeinfo_list[j + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) if (probeinfo1->bus > probeinfo2->bus ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) (probeinfo1->bus == probeinfo2->bus &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) (probeinfo1->dev > probeinfo2->dev))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) struct blogic_probeinfo tmp_probeinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) memcpy(&tmp_probeinfo, probeinfo1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) sizeof(struct blogic_probeinfo));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) memcpy(probeinfo1, probeinfo2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) sizeof(struct blogic_probeinfo));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) memcpy(probeinfo2, &tmp_probeinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) sizeof(struct blogic_probeinfo));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) last_exchange = j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) blogic_init_mm_probeinfo initializes the list of I/O Address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) and Bus Probe Information to be checked for potential BusLogic MultiMaster
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) SCSI Host Adapters by interrogating the PCI Configuration Space on PCI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) machines as well as from the list of standard BusLogic MultiMaster ISA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) I/O Addresses. It returns the number of PCI MultiMaster Host Adapters found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) static int __init blogic_init_mm_probeinfo(struct blogic_adapter *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) struct blogic_probeinfo *pr_probeinfo =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) &blogic_probeinfo_list[blogic_probeinfo_count];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) int nonpr_mmindex = blogic_probeinfo_count + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) int nonpr_mmcount = 0, mmcount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) bool force_scan_order = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) bool force_scan_order_checked = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) bool addr_seen[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) struct pci_dev *pci_device = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) if (blogic_probeinfo_count >= BLOGIC_MAX_ADAPTERS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) blogic_probeinfo_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) for (i = 0; i < 6; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) addr_seen[i] = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) Iterate over the MultiMaster PCI Host Adapters. For each
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) enumerated host adapter, determine whether its ISA Compatible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) I/O Port is enabled and if so, whether it is assigned the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) Primary I/O Address. A host adapter that is assigned the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) Primary I/O Address will always be the preferred boot device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) The MultiMaster BIOS will first recognize a host adapter at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) the Primary I/O Address, then any other PCI host adapters,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) and finally any host adapters located at the remaining
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) standard ISA I/O Addresses. When a PCI host adapter is found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) with its ISA Compatible I/O Port enabled, a command is issued
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) to disable the ISA Compatible I/O Port, and it is noted that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) particular standard ISA I/O Address need not be probed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) pr_probeinfo->io_addr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) while ((pci_device = pci_get_device(PCI_VENDOR_ID_BUSLOGIC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) pci_device)) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) struct blogic_adapter *host_adapter = adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) struct blogic_adapter_info adapter_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) enum blogic_isa_ioport mod_ioaddr_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) unsigned char bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) unsigned char device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) unsigned int irq_ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) unsigned long base_addr0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) unsigned long base_addr1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) unsigned long io_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) unsigned long pci_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) if (pci_enable_device(pci_device))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) if (dma_set_mask(&pci_device->dev, DMA_BIT_MASK(32)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) bus = pci_device->bus->number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) device = pci_device->devfn >> 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) irq_ch = pci_device->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) io_addr = base_addr0 = pci_resource_start(pci_device, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) pci_addr = base_addr1 = pci_resource_start(pci_device, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) if (pci_resource_flags(pci_device, 0) & IORESOURCE_MEM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) blogic_err("BusLogic: Base Address0 0x%lX not I/O for MultiMaster Host Adapter\n", NULL, base_addr0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) blogic_err("at PCI Bus %d Device %d I/O Address 0x%lX\n", NULL, bus, device, io_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) if (pci_resource_flags(pci_device, 1) & IORESOURCE_IO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) blogic_err("BusLogic: Base Address1 0x%lX not Memory for MultiMaster Host Adapter\n", NULL, base_addr1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) blogic_err("at PCI Bus %d Device %d PCI Address 0x%lX\n", NULL, bus, device, pci_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) if (irq_ch == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) blogic_err("BusLogic: IRQ Channel %d invalid for MultiMaster Host Adapter\n", NULL, irq_ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) blogic_err("at PCI Bus %d Device %d I/O Address 0x%lX\n", NULL, bus, device, io_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) if (blogic_global_options.trace_probe) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) blogic_notice("BusLogic: PCI MultiMaster Host Adapter detected at\n", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) blogic_notice("BusLogic: PCI Bus %d Device %d I/O Address 0x%lX PCI Address 0x%lX\n", NULL, bus, device, io_addr, pci_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) Issue the Inquire PCI Host Adapter Information command to determine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) the ISA Compatible I/O Port. If the ISA Compatible I/O Port is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) known and enabled, note that the particular Standard ISA I/O
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) Address should not be probed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) host_adapter->io_addr = io_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) blogic_intreset(host_adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) if (blogic_cmd(host_adapter, BLOGIC_INQ_PCI_INFO, NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) &adapter_info, sizeof(adapter_info)) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) sizeof(adapter_info)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) if (adapter_info.isa_port < 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) addr_seen[adapter_info.isa_port] = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) adapter_info.isa_port = BLOGIC_IO_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) Issue the Modify I/O Address command to disable the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) ISA Compatible I/O Port. On PCI Host Adapters, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) Modify I/O Address command allows modification of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) ISA compatible I/O Address that the Host Adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) responds to; it does not affect the PCI compliant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) I/O Address assigned at system initialization.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) mod_ioaddr_req = BLOGIC_IO_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) blogic_cmd(host_adapter, BLOGIC_MOD_IOADDR, &mod_ioaddr_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) sizeof(mod_ioaddr_req), NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) For the first MultiMaster Host Adapter enumerated,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) issue the Fetch Host Adapter Local RAM command to read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) byte 45 of the AutoSCSI area, for the setting of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) "Use Bus And Device # For PCI Scanning Seq." option.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) Issue the Inquire Board ID command since this option is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) only valid for the BT-948/958/958D.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) if (!force_scan_order_checked) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) struct blogic_fetch_localram fetch_localram;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) struct blogic_autoscsi_byte45 autoscsi_byte45;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) struct blogic_board_id id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) fetch_localram.offset = BLOGIC_AUTOSCSI_BASE + 45;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) fetch_localram.count = sizeof(autoscsi_byte45);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) blogic_cmd(host_adapter, BLOGIC_FETCH_LOCALRAM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) &fetch_localram, sizeof(fetch_localram),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) &autoscsi_byte45,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) sizeof(autoscsi_byte45));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) blogic_cmd(host_adapter, BLOGIC_GET_BOARD_ID, NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) &id, sizeof(id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) if (id.fw_ver_digit1 == '5')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) force_scan_order =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) autoscsi_byte45.force_scan_order;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) force_scan_order_checked = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) Determine whether this MultiMaster Host Adapter has its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) ISA Compatible I/O Port enabled and is assigned the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) Primary I/O Address. If it does, then it is the Primary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) MultiMaster Host Adapter and must be recognized first.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) If it does not, then it is added to the list for probing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) after any Primary MultiMaster Host Adapter is probed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) if (adapter_info.isa_port == BLOGIC_IO_330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) pr_probeinfo->adapter_type = BLOGIC_MULTIMASTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) pr_probeinfo->adapter_bus_type = BLOGIC_PCI_BUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) pr_probeinfo->io_addr = io_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) pr_probeinfo->pci_addr = pci_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) pr_probeinfo->bus = bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) pr_probeinfo->dev = device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) pr_probeinfo->irq_ch = irq_ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) pr_probeinfo->pci_device = pci_dev_get(pci_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) mmcount++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) } else if (blogic_probeinfo_count < BLOGIC_MAX_ADAPTERS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) struct blogic_probeinfo *probeinfo =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) &blogic_probeinfo_list[blogic_probeinfo_count++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) probeinfo->adapter_type = BLOGIC_MULTIMASTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) probeinfo->adapter_bus_type = BLOGIC_PCI_BUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) probeinfo->io_addr = io_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) probeinfo->pci_addr = pci_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) probeinfo->bus = bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) probeinfo->dev = device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) probeinfo->irq_ch = irq_ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) probeinfo->pci_device = pci_dev_get(pci_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) nonpr_mmcount++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) mmcount++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) blogic_warn("BusLogic: Too many Host Adapters detected\n", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) If the AutoSCSI "Use Bus And Device # For PCI Scanning Seq."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) option is ON for the first enumerated MultiMaster Host Adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) and if that host adapter is a BT-948/958/958D, then the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) MultiMaster BIOS will recognize MultiMaster Host Adapters in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) the order of increasing PCI Bus and Device Number. In that case,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) sort the probe information into the same order the BIOS uses.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) If this option is OFF, then the MultiMaster BIOS will recognize
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) MultiMaster Host Adapters in the order they are enumerated by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) the PCI BIOS, and hence no sorting is necessary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) if (force_scan_order)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) blogic_sort_probeinfo(&blogic_probeinfo_list[nonpr_mmindex],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) nonpr_mmcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) If no PCI MultiMaster Host Adapter is assigned the Primary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) I/O Address, then the Primary I/O Address must be probed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) explicitly before any PCI host adapters are probed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) if (!blogic_probe_options.noprobe_isa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) if (pr_probeinfo->io_addr == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) (!blogic_probe_options.limited_isa ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) blogic_probe_options.probe330)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) pr_probeinfo->adapter_type = BLOGIC_MULTIMASTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) pr_probeinfo->adapter_bus_type = BLOGIC_ISA_BUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) pr_probeinfo->io_addr = 0x330;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) Append the list of standard BusLogic MultiMaster ISA I/O Addresses,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) omitting the Primary I/O Address which has already been handled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) if (!blogic_probe_options.noprobe_isa) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) if (!addr_seen[1] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) (!blogic_probe_options.limited_isa ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) blogic_probe_options.probe334))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) blogic_add_probeaddr_isa(0x334);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) if (!addr_seen[2] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) (!blogic_probe_options.limited_isa ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) blogic_probe_options.probe230))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) blogic_add_probeaddr_isa(0x230);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) if (!addr_seen[3] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) (!blogic_probe_options.limited_isa ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) blogic_probe_options.probe234))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) blogic_add_probeaddr_isa(0x234);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) if (!addr_seen[4] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) (!blogic_probe_options.limited_isa ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) blogic_probe_options.probe130))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) blogic_add_probeaddr_isa(0x130);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) if (!addr_seen[5] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) (!blogic_probe_options.limited_isa ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) blogic_probe_options.probe134))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) blogic_add_probeaddr_isa(0x134);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) Iterate over the older non-compliant MultiMaster PCI Host Adapters,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) noting the PCI bus location and assigned IRQ Channel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) pci_device = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) while ((pci_device = pci_get_device(PCI_VENDOR_ID_BUSLOGIC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) pci_device)) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) unsigned char bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) unsigned char device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) unsigned int irq_ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) unsigned long io_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) if (pci_enable_device(pci_device))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) if (dma_set_mask(&pci_device->dev, DMA_BIT_MASK(32)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) bus = pci_device->bus->number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) device = pci_device->devfn >> 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) irq_ch = pci_device->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) io_addr = pci_resource_start(pci_device, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) if (io_addr == 0 || irq_ch == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) for (i = 0; i < blogic_probeinfo_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) struct blogic_probeinfo *probeinfo =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) &blogic_probeinfo_list[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) if (probeinfo->io_addr == io_addr &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) probeinfo->adapter_type == BLOGIC_MULTIMASTER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) probeinfo->adapter_bus_type = BLOGIC_PCI_BUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) probeinfo->pci_addr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) probeinfo->bus = bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) probeinfo->dev = device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) probeinfo->irq_ch = irq_ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) probeinfo->pci_device = pci_dev_get(pci_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) return mmcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) blogic_init_fp_probeinfo initializes the list of I/O Address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) and Bus Probe Information to be checked for potential BusLogic FlashPoint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) Host Adapters by interrogating the PCI Configuration Space. It returns the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) number of FlashPoint Host Adapters found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) static int __init blogic_init_fp_probeinfo(struct blogic_adapter *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) int fpindex = blogic_probeinfo_count, fpcount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) struct pci_dev *pci_device = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) Interrogate PCI Configuration Space for any FlashPoint Host Adapters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) while ((pci_device = pci_get_device(PCI_VENDOR_ID_BUSLOGIC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) pci_device)) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) unsigned char bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) unsigned char device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) unsigned int irq_ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) unsigned long base_addr0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) unsigned long base_addr1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) unsigned long io_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) unsigned long pci_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) if (pci_enable_device(pci_device))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) if (dma_set_mask(&pci_device->dev, DMA_BIT_MASK(32)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) bus = pci_device->bus->number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) device = pci_device->devfn >> 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) irq_ch = pci_device->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) io_addr = base_addr0 = pci_resource_start(pci_device, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) pci_addr = base_addr1 = pci_resource_start(pci_device, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) #ifdef CONFIG_SCSI_FLASHPOINT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) if (pci_resource_flags(pci_device, 0) & IORESOURCE_MEM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) blogic_err("BusLogic: Base Address0 0x%lX not I/O for FlashPoint Host Adapter\n", NULL, base_addr0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) blogic_err("at PCI Bus %d Device %d I/O Address 0x%lX\n", NULL, bus, device, io_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) if (pci_resource_flags(pci_device, 1) & IORESOURCE_IO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) blogic_err("BusLogic: Base Address1 0x%lX not Memory for FlashPoint Host Adapter\n", NULL, base_addr1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) blogic_err("at PCI Bus %d Device %d PCI Address 0x%lX\n", NULL, bus, device, pci_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) if (irq_ch == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) blogic_err("BusLogic: IRQ Channel %d invalid for FlashPoint Host Adapter\n", NULL, irq_ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) blogic_err("at PCI Bus %d Device %d I/O Address 0x%lX\n", NULL, bus, device, io_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) if (blogic_global_options.trace_probe) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) blogic_notice("BusLogic: FlashPoint Host Adapter detected at\n", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) blogic_notice("BusLogic: PCI Bus %d Device %d I/O Address 0x%lX PCI Address 0x%lX\n", NULL, bus, device, io_addr, pci_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) if (blogic_probeinfo_count < BLOGIC_MAX_ADAPTERS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) struct blogic_probeinfo *probeinfo =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) &blogic_probeinfo_list[blogic_probeinfo_count++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) probeinfo->adapter_type = BLOGIC_FLASHPOINT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) probeinfo->adapter_bus_type = BLOGIC_PCI_BUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) probeinfo->io_addr = io_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) probeinfo->pci_addr = pci_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) probeinfo->bus = bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) probeinfo->dev = device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) probeinfo->irq_ch = irq_ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) probeinfo->pci_device = pci_dev_get(pci_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) fpcount++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) blogic_warn("BusLogic: Too many Host Adapters detected\n", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) blogic_err("BusLogic: FlashPoint Host Adapter detected at PCI Bus %d Device %d\n", NULL, bus, device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) blogic_err("BusLogic: I/O Address 0x%lX PCI Address 0x%lX, irq %d, but FlashPoint\n", NULL, io_addr, pci_addr, irq_ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) blogic_err("BusLogic: support was omitted in this kernel configuration.\n", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) The FlashPoint BIOS will scan for FlashPoint Host Adapters in the order of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) increasing PCI Bus and Device Number, so sort the probe information into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) the same order the BIOS uses.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) blogic_sort_probeinfo(&blogic_probeinfo_list[fpindex], fpcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) return fpcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) blogic_init_probeinfo_list initializes the list of I/O Address and Bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) Probe Information to be checked for potential BusLogic SCSI Host Adapters by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) interrogating the PCI Configuration Space on PCI machines as well as from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) list of standard BusLogic MultiMaster ISA I/O Addresses. By default, if both
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) FlashPoint and PCI MultiMaster Host Adapters are present, this driver will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) probe for FlashPoint Host Adapters first unless the BIOS primary disk is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) controlled by the first PCI MultiMaster Host Adapter, in which case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) MultiMaster Host Adapters will be probed first. The BusLogic Driver Options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) specifications "MultiMasterFirst" and "FlashPointFirst" can be used to force
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) a particular probe order.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) static void __init blogic_init_probeinfo_list(struct blogic_adapter *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) If a PCI BIOS is present, interrogate it for MultiMaster and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) FlashPoint Host Adapters; otherwise, default to the standard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) ISA MultiMaster probe.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) if (!blogic_probe_options.noprobe_pci) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) if (blogic_probe_options.multimaster_first) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) blogic_init_mm_probeinfo(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) blogic_init_fp_probeinfo(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) } else if (blogic_probe_options.flashpoint_first) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) blogic_init_fp_probeinfo(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) blogic_init_mm_probeinfo(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) int fpcount = blogic_init_fp_probeinfo(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) int mmcount = blogic_init_mm_probeinfo(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) if (fpcount > 0 && mmcount > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) struct blogic_probeinfo *probeinfo =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) &blogic_probeinfo_list[fpcount];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) struct blogic_adapter *myadapter = adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) struct blogic_fetch_localram fetch_localram;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) struct blogic_bios_drvmap d0_mapbyte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) while (probeinfo->adapter_bus_type !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) BLOGIC_PCI_BUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) probeinfo++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) myadapter->io_addr = probeinfo->io_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) fetch_localram.offset =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) BLOGIC_BIOS_BASE + BLOGIC_BIOS_DRVMAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) fetch_localram.count = sizeof(d0_mapbyte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) blogic_cmd(myadapter, BLOGIC_FETCH_LOCALRAM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) &fetch_localram,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) sizeof(fetch_localram),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) &d0_mapbyte,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) sizeof(d0_mapbyte));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) If the Map Byte for BIOS Drive 0 indicates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) that BIOS Drive 0 is controlled by this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) PCI MultiMaster Host Adapter, then reverse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) the probe order so that MultiMaster Host
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) Adapters are probed before FlashPoint Host
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) Adapters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) if (d0_mapbyte.diskgeom != BLOGIC_BIOS_NODISK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) struct blogic_probeinfo saved_probeinfo[BLOGIC_MAX_ADAPTERS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) int mmcount = blogic_probeinfo_count - fpcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) memcpy(saved_probeinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) blogic_probeinfo_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) blogic_probeinfo_count * sizeof(struct blogic_probeinfo));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) memcpy(&blogic_probeinfo_list[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) &saved_probeinfo[fpcount],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) mmcount * sizeof(struct blogic_probeinfo));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) memcpy(&blogic_probeinfo_list[mmcount],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) &saved_probeinfo[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) fpcount * sizeof(struct blogic_probeinfo));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) blogic_init_probeinfo_isa(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) #define blogic_init_probeinfo_list(adapter) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) blogic_init_probeinfo_isa(adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) #endif /* CONFIG_PCI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) blogic_failure prints a standardized error message, and then returns false.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) static bool blogic_failure(struct blogic_adapter *adapter, char *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) blogic_announce_drvr(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) if (adapter->adapter_bus_type == BLOGIC_PCI_BUS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) blogic_err("While configuring BusLogic PCI Host Adapter at\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) blogic_err("Bus %d Device %d I/O Address 0x%lX PCI Address 0x%lX:\n", adapter, adapter->bus, adapter->dev, adapter->io_addr, adapter->pci_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) blogic_err("While configuring BusLogic Host Adapter at I/O Address 0x%lX:\n", adapter, adapter->io_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) blogic_err("%s FAILED - DETACHING\n", adapter, msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) if (blogic_cmd_failure_reason != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) blogic_err("ADDITIONAL FAILURE INFO - %s\n", adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) blogic_cmd_failure_reason);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) blogic_probe probes for a BusLogic Host Adapter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) static bool __init blogic_probe(struct blogic_adapter *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) union blogic_stat_reg statusreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) union blogic_int_reg intreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) union blogic_geo_reg georeg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) FlashPoint Host Adapters are Probed by the FlashPoint SCCB Manager.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) if (blogic_flashpoint_type(adapter)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) struct fpoint_info *fpinfo = &adapter->fpinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) fpinfo->base_addr = (u32) adapter->io_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) fpinfo->irq_ch = adapter->irq_ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) fpinfo->present = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) if (!(FlashPoint_ProbeHostAdapter(fpinfo) == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) fpinfo->present)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) blogic_err("BusLogic: FlashPoint Host Adapter detected at PCI Bus %d Device %d\n", adapter, adapter->bus, adapter->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) blogic_err("BusLogic: I/O Address 0x%lX PCI Address 0x%lX, but FlashPoint\n", adapter, adapter->io_addr, adapter->pci_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) blogic_err("BusLogic: Probe Function failed to validate it.\n", adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) if (blogic_global_options.trace_probe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) blogic_notice("BusLogic_Probe(0x%lX): FlashPoint Found\n", adapter, adapter->io_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) Indicate the Host Adapter Probe completed successfully.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) Read the Status, Interrupt, and Geometry Registers to test if there are I/O
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) ports that respond, and to check the values to determine if they are from a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) BusLogic Host Adapter. A nonexistent I/O port will return 0xFF, in which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) case there is definitely no BusLogic Host Adapter at this base I/O Address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) The test here is a subset of that used by the BusLogic Host Adapter BIOS.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) statusreg.all = blogic_rdstatus(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) intreg.all = blogic_rdint(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) georeg.all = blogic_rdgeom(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) if (blogic_global_options.trace_probe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) blogic_notice("BusLogic_Probe(0x%lX): Status 0x%02X, Interrupt 0x%02X, Geometry 0x%02X\n", adapter, adapter->io_addr, statusreg.all, intreg.all, georeg.all);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) if (statusreg.all == 0 || statusreg.sr.diag_active ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) statusreg.sr.cmd_param_busy || statusreg.sr.rsvd ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) statusreg.sr.cmd_invalid || intreg.ir.rsvd != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) Check the undocumented Geometry Register to test if there is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) an I/O port that responded. Adaptec Host Adapters do not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) implement the Geometry Register, so this test helps serve to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) avoid incorrectly recognizing an Adaptec 1542A or 1542B as a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) BusLogic. Unfortunately, the Adaptec 1542C series does respond
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) to the Geometry Register I/O port, but it will be rejected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) later when the Inquire Extended Setup Information command is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) issued in blogic_checkadapter. The AMI FastDisk Host Adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) is a BusLogic clone that implements the same interface as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) earlier BusLogic Host Adapters, including the undocumented
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) commands, and is therefore supported by this driver. However,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) the AMI FastDisk always returns 0x00 upon reading the Geometry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) Register, so the extended translation option should always be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) left disabled on the AMI FastDisk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) if (georeg.all == 0xFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) Indicate the Host Adapter Probe completed successfully.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) blogic_hwreset issues a Hardware Reset to the Host Adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) and waits for Host Adapter Diagnostics to complete. If hard_reset is true, a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) Hard Reset is performed which also initiates a SCSI Bus Reset. Otherwise, a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) Soft Reset is performed which only resets the Host Adapter without forcing a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) SCSI Bus Reset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) static bool blogic_hwreset(struct blogic_adapter *adapter, bool hard_reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) union blogic_stat_reg statusreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) int timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) FlashPoint Host Adapters are Hard Reset by the FlashPoint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) SCCB Manager.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) if (blogic_flashpoint_type(adapter)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) struct fpoint_info *fpinfo = &adapter->fpinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) fpinfo->softreset = !hard_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) fpinfo->report_underrun = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) adapter->cardhandle =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) FlashPoint_HardwareResetHostAdapter(fpinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) if (adapter->cardhandle == (void *)FPOINT_BADCARD_HANDLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) Indicate the Host Adapter Hard Reset completed successfully.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) Issue a Hard Reset or Soft Reset Command to the Host Adapter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) The Host Adapter should respond by setting Diagnostic Active in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) the Status Register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) if (hard_reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) blogic_hardreset(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) blogic_softreset(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) Wait until Diagnostic Active is set in the Status Register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) timeout = 5 * 10000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) while (--timeout >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) statusreg.all = blogic_rdstatus(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) if (statusreg.sr.diag_active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) udelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) if (blogic_global_options.trace_hw_reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) blogic_notice("BusLogic_HardwareReset(0x%lX): Diagnostic Active, Status 0x%02X\n", adapter, adapter->io_addr, statusreg.all);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) if (timeout < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) Wait 100 microseconds to allow completion of any initial diagnostic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) activity which might leave the contents of the Status Register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) unpredictable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) udelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) Wait until Diagnostic Active is reset in the Status Register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) timeout = 10 * 10000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) while (--timeout >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) statusreg.all = blogic_rdstatus(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) if (!statusreg.sr.diag_active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) udelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) if (blogic_global_options.trace_hw_reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) blogic_notice("BusLogic_HardwareReset(0x%lX): Diagnostic Completed, Status 0x%02X\n", adapter, adapter->io_addr, statusreg.all);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) if (timeout < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) Wait until at least one of the Diagnostic Failure, Host Adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) Ready, or Data In Register Ready bits is set in the Status Register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) timeout = 10000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) while (--timeout >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) statusreg.all = blogic_rdstatus(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) if (statusreg.sr.diag_failed || statusreg.sr.adapter_ready ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) statusreg.sr.datain_ready)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) udelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) if (blogic_global_options.trace_hw_reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) blogic_notice("BusLogic_HardwareReset(0x%lX): Host Adapter Ready, Status 0x%02X\n", adapter, adapter->io_addr, statusreg.all);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) if (timeout < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) If Diagnostic Failure is set or Host Adapter Ready is reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) then an error occurred during the Host Adapter diagnostics.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) If Data In Register Ready is set, then there is an Error Code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) if (statusreg.sr.diag_failed || !statusreg.sr.adapter_ready) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) blogic_cmd_failure_reason = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) blogic_failure(adapter, "HARD RESET DIAGNOSTICS");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) blogic_err("HOST ADAPTER STATUS REGISTER = %02X\n", adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) statusreg.all);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) if (statusreg.sr.datain_ready)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) blogic_err("HOST ADAPTER ERROR CODE = %d\n", adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) blogic_rddatain(adapter));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) Indicate the Host Adapter Hard Reset completed successfully.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) blogic_checkadapter checks to be sure this really is a BusLogic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) Host Adapter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) static bool __init blogic_checkadapter(struct blogic_adapter *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) struct blogic_ext_setup ext_setupinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) unsigned char req_replylen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) bool result = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) FlashPoint Host Adapters do not require this protection.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) if (blogic_flashpoint_type(adapter))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) Issue the Inquire Extended Setup Information command. Only genuine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) BusLogic Host Adapters and true clones support this command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) Adaptec 1542C series Host Adapters that respond to the Geometry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) Register I/O port will fail this command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) req_replylen = sizeof(ext_setupinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) if (blogic_cmd(adapter, BLOGIC_INQ_EXTSETUP, &req_replylen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) sizeof(req_replylen), &ext_setupinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) sizeof(ext_setupinfo)) != sizeof(ext_setupinfo))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) result = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) Provide tracing information if requested and return.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) if (blogic_global_options.trace_probe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) blogic_notice("BusLogic_Check(0x%lX): MultiMaster %s\n", adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) adapter->io_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) (result ? "Found" : "Not Found"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) blogic_rdconfig reads the Configuration Information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) from Host Adapter and initializes the Host Adapter structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) static bool __init blogic_rdconfig(struct blogic_adapter *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) struct blogic_board_id id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) struct blogic_config config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) struct blogic_setup_info setupinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) struct blogic_ext_setup ext_setupinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) unsigned char model[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) unsigned char fw_ver_digit3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) unsigned char fw_ver_letter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) struct blogic_adapter_info adapter_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) struct blogic_fetch_localram fetch_localram;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) struct blogic_autoscsi autoscsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) union blogic_geo_reg georeg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) unsigned char req_replylen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) unsigned char *tgt, ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) int tgt_id, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) Configuration Information for FlashPoint Host Adapters is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) provided in the fpoint_info structure by the FlashPoint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) SCCB Manager's Probe Function. Initialize fields in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) Host Adapter structure from the fpoint_info structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) if (blogic_flashpoint_type(adapter)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) struct fpoint_info *fpinfo = &adapter->fpinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) tgt = adapter->model;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) *tgt++ = 'B';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) *tgt++ = 'T';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) *tgt++ = '-';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) for (i = 0; i < sizeof(fpinfo->model); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) *tgt++ = fpinfo->model[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) *tgt++ = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) strcpy(adapter->fw_ver, FLASHPOINT_FW_VER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) adapter->scsi_id = fpinfo->scsi_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) adapter->ext_trans_enable = fpinfo->ext_trans_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) adapter->parity = fpinfo->parity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) adapter->reset_enabled = !fpinfo->softreset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) adapter->level_int = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) adapter->wide = fpinfo->wide;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) adapter->differential = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) adapter->scam = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) adapter->ultra = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) adapter->ext_lun = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) adapter->terminfo_valid = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) adapter->low_term = fpinfo->low_term;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) adapter->high_term = fpinfo->high_term;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) adapter->scam_enabled = fpinfo->scam_enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) adapter->scam_lev2 = fpinfo->scam_lev2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) adapter->drvr_sglimit = BLOGIC_SG_LIMIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) adapter->maxdev = (adapter->wide ? 16 : 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) adapter->maxlun = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) adapter->initccbs = 4 * BLOGIC_CCB_GRP_ALLOCSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) adapter->inc_ccbs = BLOGIC_CCB_GRP_ALLOCSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) adapter->drvr_qdepth = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) adapter->adapter_qdepth = adapter->drvr_qdepth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) adapter->sync_ok = fpinfo->sync_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) adapter->fast_ok = fpinfo->fast_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) adapter->ultra_ok = fpinfo->ultra_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) adapter->wide_ok = fpinfo->wide_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) adapter->discon_ok = fpinfo->discon_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) adapter->tagq_ok = 0xFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) goto common;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) Issue the Inquire Board ID command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) if (blogic_cmd(adapter, BLOGIC_GET_BOARD_ID, NULL, 0, &id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) sizeof(id)) != sizeof(id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) return blogic_failure(adapter, "INQUIRE BOARD ID");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) Issue the Inquire Configuration command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) if (blogic_cmd(adapter, BLOGIC_INQ_CONFIG, NULL, 0, &config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) sizeof(config))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) != sizeof(config))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) return blogic_failure(adapter, "INQUIRE CONFIGURATION");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) Issue the Inquire Setup Information command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) req_replylen = sizeof(setupinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) if (blogic_cmd(adapter, BLOGIC_INQ_SETUPINFO, &req_replylen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) sizeof(req_replylen), &setupinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) sizeof(setupinfo)) != sizeof(setupinfo))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) return blogic_failure(adapter, "INQUIRE SETUP INFORMATION");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) Issue the Inquire Extended Setup Information command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) req_replylen = sizeof(ext_setupinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) if (blogic_cmd(adapter, BLOGIC_INQ_EXTSETUP, &req_replylen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) sizeof(req_replylen), &ext_setupinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) sizeof(ext_setupinfo)) != sizeof(ext_setupinfo))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) return blogic_failure(adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) "INQUIRE EXTENDED SETUP INFORMATION");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) Issue the Inquire Firmware Version 3rd Digit command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) fw_ver_digit3 = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) if (id.fw_ver_digit1 > '0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) if (blogic_cmd(adapter, BLOGIC_INQ_FWVER_D3, NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) &fw_ver_digit3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) sizeof(fw_ver_digit3)) != sizeof(fw_ver_digit3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) return blogic_failure(adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) "INQUIRE FIRMWARE 3RD DIGIT");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) Issue the Inquire Host Adapter Model Number command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) if (ext_setupinfo.bus_type == 'A' && id.fw_ver_digit1 == '2')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) /* BusLogic BT-542B ISA 2.xx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) strcpy(model, "542B");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) else if (ext_setupinfo.bus_type == 'E' && id.fw_ver_digit1 == '2' &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) (id.fw_ver_digit2 <= '1' || (id.fw_ver_digit2 == '2' &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) fw_ver_digit3 == '0')))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) /* BusLogic BT-742A EISA 2.1x or 2.20 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) strcpy(model, "742A");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) else if (ext_setupinfo.bus_type == 'E' && id.fw_ver_digit1 == '0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) /* AMI FastDisk EISA Series 441 0.x */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) strcpy(model, "747A");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) req_replylen = sizeof(model);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) if (blogic_cmd(adapter, BLOGIC_INQ_MODELNO, &req_replylen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) sizeof(req_replylen), &model,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) sizeof(model)) != sizeof(model))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) return blogic_failure(adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) "INQUIRE HOST ADAPTER MODEL NUMBER");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) BusLogic MultiMaster Host Adapters can be identified by their
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) model number and the major version number of their firmware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) as follows:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 5.xx BusLogic "W" Series Host Adapters:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) BT-948/958/958D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 4.xx BusLogic "C" Series Host Adapters:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) BT-946C/956C/956CD/747C/757C/757CD/445C/545C/540CF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 3.xx BusLogic "S" Series Host Adapters:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) BT-747S/747D/757S/757D/445S/545S/542D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) BT-542B/742A (revision H)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 2.xx BusLogic "A" Series Host Adapters:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) BT-542B/742A (revision G and below)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) 0.xx AMI FastDisk VLB/EISA BusLogic Clone Host Adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) Save the Model Name and Host Adapter Name in the Host Adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) tgt = adapter->model;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) *tgt++ = 'B';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) *tgt++ = 'T';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) *tgt++ = '-';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) for (i = 0; i < sizeof(model); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) ch = model[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) if (ch == ' ' || ch == '\0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) *tgt++ = ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) *tgt++ = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) Save the Firmware Version in the Host Adapter structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) tgt = adapter->fw_ver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) *tgt++ = id.fw_ver_digit1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) *tgt++ = '.';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) *tgt++ = id.fw_ver_digit2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) if (fw_ver_digit3 != ' ' && fw_ver_digit3 != '\0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) *tgt++ = fw_ver_digit3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) *tgt = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) Issue the Inquire Firmware Version Letter command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) if (strcmp(adapter->fw_ver, "3.3") >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) if (blogic_cmd(adapter, BLOGIC_INQ_FWVER_LETTER, NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) &fw_ver_letter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) sizeof(fw_ver_letter)) != sizeof(fw_ver_letter))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) return blogic_failure(adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) "INQUIRE FIRMWARE VERSION LETTER");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) if (fw_ver_letter != ' ' && fw_ver_letter != '\0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) *tgt++ = fw_ver_letter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) *tgt = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) Save the Host Adapter SCSI ID in the Host Adapter structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) adapter->scsi_id = config.id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) Determine the Bus Type and save it in the Host Adapter structure,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) determine and save the IRQ Channel if necessary, and determine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) and save the DMA Channel for ISA Host Adapters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) adapter->adapter_bus_type =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) blogic_adater_bus_types[adapter->model[3] - '4'];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) if (adapter->irq_ch == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) if (config.irq_ch9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) adapter->irq_ch = 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) else if (config.irq_ch10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) adapter->irq_ch = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) else if (config.irq_ch11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) adapter->irq_ch = 11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) else if (config.irq_ch12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) adapter->irq_ch = 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) else if (config.irq_ch14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) adapter->irq_ch = 14;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) else if (config.irq_ch15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) adapter->irq_ch = 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) if (adapter->adapter_bus_type == BLOGIC_ISA_BUS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) if (config.dma_ch5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) adapter->dma_ch = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) else if (config.dma_ch6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) adapter->dma_ch = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) else if (config.dma_ch7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) adapter->dma_ch = 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) Determine whether Extended Translation is enabled and save it in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) the Host Adapter structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) georeg.all = blogic_rdgeom(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) adapter->ext_trans_enable = georeg.gr.ext_trans_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) Save the Scatter Gather Limits, Level Sensitive Interrupt flag, Wide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) SCSI flag, Differential SCSI flag, SCAM Supported flag, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) Ultra SCSI flag in the Host Adapter structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) adapter->adapter_sglimit = ext_setupinfo.sg_limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) adapter->drvr_sglimit = adapter->adapter_sglimit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) if (adapter->adapter_sglimit > BLOGIC_SG_LIMIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) adapter->drvr_sglimit = BLOGIC_SG_LIMIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) if (ext_setupinfo.misc.level_int)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) adapter->level_int = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) adapter->wide = ext_setupinfo.wide;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) adapter->differential = ext_setupinfo.differential;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) adapter->scam = ext_setupinfo.scam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) adapter->ultra = ext_setupinfo.ultra;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) Determine whether Extended LUN Format CCBs are supported and save the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) information in the Host Adapter structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) if (adapter->fw_ver[0] == '5' || (adapter->fw_ver[0] == '4' &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) adapter->wide))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) adapter->ext_lun = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) Issue the Inquire PCI Host Adapter Information command to read the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) Termination Information from "W" series MultiMaster Host Adapters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) if (adapter->fw_ver[0] == '5') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) if (blogic_cmd(adapter, BLOGIC_INQ_PCI_INFO, NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) &adapter_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) sizeof(adapter_info)) != sizeof(adapter_info))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) return blogic_failure(adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) "INQUIRE PCI HOST ADAPTER INFORMATION");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) Save the Termination Information in the Host Adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) if (adapter_info.genericinfo_valid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) adapter->terminfo_valid = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) adapter->low_term = adapter_info.low_term;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) adapter->high_term = adapter_info.high_term;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) Issue the Fetch Host Adapter Local RAM command to read the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) AutoSCSI data from "W" and "C" series MultiMaster Host Adapters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) if (adapter->fw_ver[0] >= '4') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) fetch_localram.offset = BLOGIC_AUTOSCSI_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) fetch_localram.count = sizeof(autoscsi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) if (blogic_cmd(adapter, BLOGIC_FETCH_LOCALRAM, &fetch_localram,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) sizeof(fetch_localram), &autoscsi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) sizeof(autoscsi)) != sizeof(autoscsi))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) return blogic_failure(adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) "FETCH HOST ADAPTER LOCAL RAM");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) Save the Parity Checking Enabled, Bus Reset Enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) and Termination Information in the Host Adapter structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) adapter->parity = autoscsi.parity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) adapter->reset_enabled = autoscsi.reset_enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) if (adapter->fw_ver[0] == '4') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) adapter->terminfo_valid = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) adapter->low_term = autoscsi.low_term;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) adapter->high_term = autoscsi.high_term;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) Save the Wide Permitted, Fast Permitted, Synchronous
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) Permitted, Disconnect Permitted, Ultra Permitted, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) SCAM Information in the Host Adapter structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) adapter->wide_ok = autoscsi.wide_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) adapter->fast_ok = autoscsi.fast_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) adapter->sync_ok = autoscsi.sync_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) adapter->discon_ok = autoscsi.discon_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) if (adapter->ultra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) adapter->ultra_ok = autoscsi.ultra_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) if (adapter->scam) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) adapter->scam_enabled = autoscsi.scam_enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) adapter->scam_lev2 = autoscsi.scam_lev2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) Initialize fields in the Host Adapter structure for "S" and "A"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) series MultiMaster Host Adapters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) if (adapter->fw_ver[0] < '4') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) if (setupinfo.sync) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) adapter->sync_ok = 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) if (adapter->adapter_bus_type == BLOGIC_EISA_BUS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) if (ext_setupinfo.misc.fast_on_eisa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) adapter->fast_ok = 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) if (strcmp(adapter->model, "BT-757") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) adapter->wide_ok = 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) adapter->discon_ok = 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) adapter->parity = setupinfo.parity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) adapter->reset_enabled = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) Determine the maximum number of Target IDs and Logical Units
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) supported by this driver for Wide and Narrow Host Adapters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) adapter->maxdev = (adapter->wide ? 16 : 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) adapter->maxlun = (adapter->ext_lun ? 32 : 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) Select appropriate values for the Mailbox Count, Driver Queue Depth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) Initial CCBs, and Incremental CCBs variables based on whether
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) or not Strict Round Robin Mode is supported. If Strict Round
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) Robin Mode is supported, then there is no performance degradation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) in using the maximum possible number of Outgoing and Incoming
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) Mailboxes and allowing the Tagged and Untagged Queue Depths to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) determine the actual utilization. If Strict Round Robin Mode is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) not supported, then the Host Adapter must scan all the Outgoing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) Mailboxes whenever an Outgoing Mailbox entry is made, which can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) cause a substantial performance penalty. The host adapters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) actually have room to store the following number of CCBs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) internally; that is, they can internally queue and manage this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) many active commands on the SCSI bus simultaneously. Performance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) measurements demonstrate that the Driver Queue Depth should be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) set to the Mailbox Count, rather than the Host Adapter Queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) Depth (internal CCB capacity), as it is more efficient to have the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) queued commands waiting in Outgoing Mailboxes if necessary than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) to block the process in the higher levels of the SCSI Subsystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) 192 BT-948/958/958D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) 100 BT-946C/956C/956CD/747C/757C/757CD/445C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) 50 BT-545C/540CF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) 30 BT-747S/747D/757S/757D/445S/545S/542D/542B/742A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) if (adapter->fw_ver[0] == '5')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) adapter->adapter_qdepth = 192;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) else if (adapter->fw_ver[0] == '4')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) adapter->adapter_qdepth = (adapter->adapter_bus_type !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) BLOGIC_ISA_BUS ? 100 : 50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) adapter->adapter_qdepth = 30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) if (strcmp(adapter->fw_ver, "3.31") >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) adapter->strict_rr = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) adapter->mbox_count = BLOGIC_MAX_MAILBOX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) adapter->strict_rr = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) adapter->mbox_count = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) adapter->drvr_qdepth = adapter->mbox_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) adapter->initccbs = 4 * BLOGIC_CCB_GRP_ALLOCSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) adapter->inc_ccbs = BLOGIC_CCB_GRP_ALLOCSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) Tagged Queuing support is available and operates properly on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) all "W" series MultiMaster Host Adapters, on "C" series
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) MultiMaster Host Adapters with firmware version 4.22 and above,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) and on "S" series MultiMaster Host Adapters with firmware version
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) 3.35 and above.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) adapter->tagq_ok = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) switch (adapter->fw_ver[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) case '5':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) adapter->tagq_ok = 0xFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) case '4':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) if (strcmp(adapter->fw_ver, "4.22") >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) adapter->tagq_ok = 0xFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) case '3':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) if (strcmp(adapter->fw_ver, "3.35") >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) adapter->tagq_ok = 0xFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) Determine the Host Adapter BIOS Address if the BIOS is enabled and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) save it in the Host Adapter structure. The BIOS is disabled if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) bios_addr is 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) adapter->bios_addr = ext_setupinfo.bios_addr << 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) ISA Host Adapters require Bounce Buffers if there is more than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) 16MB memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) if (adapter->adapter_bus_type == BLOGIC_ISA_BUS &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) (void *) high_memory > (void *) MAX_DMA_ADDRESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) adapter->need_bouncebuf = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) BusLogic BT-445S Host Adapters prior to board revision E have a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) hardware bug whereby when the BIOS is enabled, transfers to/from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) the same address range the BIOS occupies modulo 16MB are handled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) incorrectly. Only properly functioning BT-445S Host Adapters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) have firmware version 3.37, so require that ISA Bounce Buffers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) be used for the buggy BT-445S models if there is more than 16MB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) if (adapter->bios_addr > 0 && strcmp(adapter->model, "BT-445S") == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) strcmp(adapter->fw_ver, "3.37") < 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) (void *) high_memory > (void *) MAX_DMA_ADDRESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) adapter->need_bouncebuf = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) Initialize parameters common to MultiMaster and FlashPoint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) Host Adapters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) common:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) Initialize the Host Adapter Full Model Name from the Model Name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) strcpy(adapter->full_model, "BusLogic ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) strcat(adapter->full_model, adapter->model);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) Select an appropriate value for the Tagged Queue Depth either from a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) BusLogic Driver Options specification, or based on whether this Host
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) Adapter requires that ISA Bounce Buffers be used. The Tagged Queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) Depth is left at 0 for automatic determination in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) BusLogic_SelectQueueDepths. Initialize the Untagged Queue Depth.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) for (tgt_id = 0; tgt_id < BLOGIC_MAXDEV; tgt_id++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) unsigned char qdepth = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) if (adapter->drvr_opts != NULL &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) adapter->drvr_opts->qdepth[tgt_id] > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) qdepth = adapter->drvr_opts->qdepth[tgt_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) else if (adapter->need_bouncebuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) qdepth = BLOGIC_TAG_DEPTH_BB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) adapter->qdepth[tgt_id] = qdepth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) if (adapter->need_bouncebuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) adapter->untag_qdepth = BLOGIC_UNTAG_DEPTH_BB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) adapter->untag_qdepth = BLOGIC_UNTAG_DEPTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) if (adapter->drvr_opts != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) adapter->common_qdepth = adapter->drvr_opts->common_qdepth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) if (adapter->common_qdepth > 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) adapter->common_qdepth < adapter->untag_qdepth)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) adapter->untag_qdepth = adapter->common_qdepth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) Tagged Queuing is only allowed if Disconnect/Reconnect is permitted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) Therefore, mask the Tagged Queuing Permitted Default bits with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) Disconnect/Reconnect Permitted bits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) adapter->tagq_ok &= adapter->discon_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) Combine the default Tagged Queuing Permitted bits with any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) BusLogic Driver Options Tagged Queuing specification.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) if (adapter->drvr_opts != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) adapter->tagq_ok = (adapter->drvr_opts->tagq_ok &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) adapter->drvr_opts->tagq_ok_mask) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) (adapter->tagq_ok & ~adapter->drvr_opts->tagq_ok_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) Select an appropriate value for Bus Settle Time either from a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) BusLogic Driver Options specification, or from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) BLOGIC_BUS_SETTLE_TIME.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) if (adapter->drvr_opts != NULL &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) adapter->drvr_opts->bus_settle_time > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) adapter->bus_settle_time = adapter->drvr_opts->bus_settle_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) adapter->bus_settle_time = BLOGIC_BUS_SETTLE_TIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) Indicate reading the Host Adapter Configuration completed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) successfully.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) blogic_reportconfig reports the configuration of Host Adapter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) static bool __init blogic_reportconfig(struct blogic_adapter *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) unsigned short alltgt_mask = (1 << adapter->maxdev) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) unsigned short sync_ok, fast_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) unsigned short ultra_ok, wide_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) unsigned short discon_ok, tagq_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) bool common_syncneg, common_tagq_depth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) char syncstr[BLOGIC_MAXDEV + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) char widestr[BLOGIC_MAXDEV + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) char discon_str[BLOGIC_MAXDEV + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) char tagq_str[BLOGIC_MAXDEV + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) char *syncmsg = syncstr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) char *widemsg = widestr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) char *discon_msg = discon_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) char *tagq_msg = tagq_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) int tgt_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) blogic_info("Configuring BusLogic Model %s %s%s%s%s SCSI Host Adapter\n", adapter, adapter->model, blogic_adapter_busnames[adapter->adapter_bus_type], (adapter->wide ? " Wide" : ""), (adapter->differential ? " Differential" : ""), (adapter->ultra ? " Ultra" : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) blogic_info(" Firmware Version: %s, I/O Address: 0x%lX, IRQ Channel: %d/%s\n", adapter, adapter->fw_ver, adapter->io_addr, adapter->irq_ch, (adapter->level_int ? "Level" : "Edge"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) if (adapter->adapter_bus_type != BLOGIC_PCI_BUS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) blogic_info(" DMA Channel: ", adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) if (adapter->dma_ch > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) blogic_info("%d, ", adapter, adapter->dma_ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) blogic_info("None, ", adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) if (adapter->bios_addr > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) blogic_info("BIOS Address: 0x%X, ", adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) adapter->bios_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) blogic_info("BIOS Address: None, ", adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) blogic_info(" PCI Bus: %d, Device: %d, Address: ", adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) adapter->bus, adapter->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) if (adapter->pci_addr > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) blogic_info("0x%lX, ", adapter, adapter->pci_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) blogic_info("Unassigned, ", adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) blogic_info("Host Adapter SCSI ID: %d\n", adapter, adapter->scsi_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) blogic_info(" Parity Checking: %s, Extended Translation: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) adapter, (adapter->parity ? "Enabled" : "Disabled"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) (adapter->ext_trans_enable ? "Enabled" : "Disabled"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) alltgt_mask &= ~(1 << adapter->scsi_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) sync_ok = adapter->sync_ok & alltgt_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) fast_ok = adapter->fast_ok & alltgt_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) ultra_ok = adapter->ultra_ok & alltgt_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) if ((blogic_multimaster_type(adapter) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) (adapter->fw_ver[0] >= '4' ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) adapter->adapter_bus_type == BLOGIC_EISA_BUS)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) blogic_flashpoint_type(adapter)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) common_syncneg = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) if (sync_ok == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) syncmsg = "Disabled";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) common_syncneg = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) } else if (sync_ok == alltgt_mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) if (fast_ok == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) syncmsg = "Slow";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) common_syncneg = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) } else if (fast_ok == alltgt_mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) if (ultra_ok == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) syncmsg = "Fast";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) common_syncneg = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) } else if (ultra_ok == alltgt_mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) syncmsg = "Ultra";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) common_syncneg = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) if (!common_syncneg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) syncstr[tgt_id] = ((!(sync_ok & (1 << tgt_id))) ? 'N' : (!(fast_ok & (1 << tgt_id)) ? 'S' : (!(ultra_ok & (1 << tgt_id)) ? 'F' : 'U')));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) syncstr[adapter->scsi_id] = '#';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) syncstr[adapter->maxdev] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) syncmsg = (sync_ok == 0 ? "Disabled" : "Enabled");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) wide_ok = adapter->wide_ok & alltgt_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) if (wide_ok == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) widemsg = "Disabled";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) else if (wide_ok == alltgt_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) widemsg = "Enabled";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) widestr[tgt_id] = ((wide_ok & (1 << tgt_id)) ? 'Y' : 'N');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) widestr[adapter->scsi_id] = '#';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) widestr[adapter->maxdev] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) discon_ok = adapter->discon_ok & alltgt_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) if (discon_ok == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) discon_msg = "Disabled";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) else if (discon_ok == alltgt_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) discon_msg = "Enabled";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) discon_str[tgt_id] = ((discon_ok & (1 << tgt_id)) ? 'Y' : 'N');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) discon_str[adapter->scsi_id] = '#';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) discon_str[adapter->maxdev] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) tagq_ok = adapter->tagq_ok & alltgt_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) if (tagq_ok == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) tagq_msg = "Disabled";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) else if (tagq_ok == alltgt_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) tagq_msg = "Enabled";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) tagq_str[tgt_id] = ((tagq_ok & (1 << tgt_id)) ? 'Y' : 'N');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) tagq_str[adapter->scsi_id] = '#';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) tagq_str[adapter->maxdev] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) blogic_info(" Synchronous Negotiation: %s, Wide Negotiation: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) adapter, syncmsg, widemsg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) blogic_info(" Disconnect/Reconnect: %s, Tagged Queuing: %s\n", adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) discon_msg, tagq_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) if (blogic_multimaster_type(adapter)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) blogic_info(" Scatter/Gather Limit: %d of %d segments, Mailboxes: %d\n", adapter, adapter->drvr_sglimit, adapter->adapter_sglimit, adapter->mbox_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) blogic_info(" Driver Queue Depth: %d, Host Adapter Queue Depth: %d\n", adapter, adapter->drvr_qdepth, adapter->adapter_qdepth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) blogic_info(" Driver Queue Depth: %d, Scatter/Gather Limit: %d segments\n", adapter, adapter->drvr_qdepth, adapter->drvr_sglimit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) blogic_info(" Tagged Queue Depth: ", adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) common_tagq_depth = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) for (tgt_id = 1; tgt_id < adapter->maxdev; tgt_id++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) if (adapter->qdepth[tgt_id] != adapter->qdepth[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) common_tagq_depth = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) if (common_tagq_depth) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) if (adapter->qdepth[0] > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) blogic_info("%d", adapter, adapter->qdepth[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) blogic_info("Automatic", adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) blogic_info("Individual", adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) blogic_info(", Untagged Queue Depth: %d\n", adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) adapter->untag_qdepth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) if (adapter->terminfo_valid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) if (adapter->wide)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) blogic_info(" SCSI Bus Termination: %s", adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) (adapter->low_term ? (adapter->high_term ? "Both Enabled" : "Low Enabled") : (adapter->high_term ? "High Enabled" : "Both Disabled")));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) blogic_info(" SCSI Bus Termination: %s", adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) (adapter->low_term ? "Enabled" : "Disabled"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) if (adapter->scam)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) blogic_info(", SCAM: %s", adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) (adapter->scam_enabled ? (adapter->scam_lev2 ? "Enabled, Level 2" : "Enabled, Level 1") : "Disabled"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) blogic_info("\n", adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) Indicate reporting the Host Adapter configuration completed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) successfully.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) blogic_getres acquires the system resources necessary to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) Host Adapter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) static bool __init blogic_getres(struct blogic_adapter *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) if (adapter->irq_ch == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) blogic_err("NO LEGAL INTERRUPT CHANNEL ASSIGNED - DETACHING\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) Acquire shared access to the IRQ Channel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) if (request_irq(adapter->irq_ch, blogic_inthandler, IRQF_SHARED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) adapter->full_model, adapter) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) blogic_err("UNABLE TO ACQUIRE IRQ CHANNEL %d - DETACHING\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) adapter, adapter->irq_ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) adapter->irq_acquired = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) Acquire exclusive access to the DMA Channel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) if (adapter->dma_ch > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) if (request_dma(adapter->dma_ch, adapter->full_model) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) blogic_err("UNABLE TO ACQUIRE DMA CHANNEL %d - DETACHING\n", adapter, adapter->dma_ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) set_dma_mode(adapter->dma_ch, DMA_MODE_CASCADE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) enable_dma(adapter->dma_ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) adapter->dma_chan_acquired = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) Indicate the System Resource Acquisition completed successfully,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) blogic_relres releases any system resources previously acquired
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) by blogic_getres.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) static void blogic_relres(struct blogic_adapter *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) Release shared access to the IRQ Channel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) if (adapter->irq_acquired)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) free_irq(adapter->irq_ch, adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) Release exclusive access to the DMA Channel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) if (adapter->dma_chan_acquired)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) free_dma(adapter->dma_ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) Release any allocated memory structs not released elsewhere
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) if (adapter->mbox_space)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) dma_free_coherent(&adapter->pci_device->dev, adapter->mbox_sz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) adapter->mbox_space, adapter->mbox_space_handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) pci_dev_put(adapter->pci_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) adapter->mbox_space = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) adapter->mbox_space_handle = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) adapter->mbox_sz = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) blogic_initadapter initializes Host Adapter. This is the only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) function called during SCSI Host Adapter detection which modifies the state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) of the Host Adapter from its initial power on or hard reset state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) static bool blogic_initadapter(struct blogic_adapter *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) struct blogic_extmbox_req extmbox_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) enum blogic_rr_req rr_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) enum blogic_setccb_fmt setccb_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) int tgt_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) Initialize the pointers to the first and last CCBs that are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) queued for completion processing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) adapter->firstccb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) adapter->lastccb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) Initialize the Bus Device Reset Pending CCB, Tagged Queuing Active,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) Command Successful Flag, Active Commands, and Commands Since Reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) for each Target Device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) adapter->bdr_pend[tgt_id] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) adapter->tgt_flags[tgt_id].tagq_active = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) adapter->tgt_flags[tgt_id].cmd_good = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) adapter->active_cmds[tgt_id] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) adapter->cmds_since_rst[tgt_id] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) FlashPoint Host Adapters do not use Outgoing and Incoming Mailboxes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) if (blogic_flashpoint_type(adapter))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) Initialize the Outgoing and Incoming Mailbox pointers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) adapter->mbox_sz = adapter->mbox_count * (sizeof(struct blogic_outbox) + sizeof(struct blogic_inbox));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) adapter->mbox_space = dma_alloc_coherent(&adapter->pci_device->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) adapter->mbox_sz, &adapter->mbox_space_handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) if (adapter->mbox_space == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) return blogic_failure(adapter, "MAILBOX ALLOCATION");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) adapter->first_outbox = (struct blogic_outbox *) adapter->mbox_space;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) adapter->last_outbox = adapter->first_outbox + adapter->mbox_count - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) adapter->next_outbox = adapter->first_outbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) adapter->first_inbox = (struct blogic_inbox *) (adapter->last_outbox + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) adapter->last_inbox = adapter->first_inbox + adapter->mbox_count - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) adapter->next_inbox = adapter->first_inbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) Initialize the Outgoing and Incoming Mailbox structures.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) memset(adapter->first_outbox, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) adapter->mbox_count * sizeof(struct blogic_outbox));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) memset(adapter->first_inbox, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) adapter->mbox_count * sizeof(struct blogic_inbox));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) Initialize the Host Adapter's Pointer to the Outgoing/Incoming
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) Mailboxes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) extmbox_req.mbox_count = adapter->mbox_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) extmbox_req.base_mbox_addr = (u32) adapter->mbox_space_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) if (blogic_cmd(adapter, BLOGIC_INIT_EXT_MBOX, &extmbox_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) sizeof(extmbox_req), NULL, 0) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) return blogic_failure(adapter, "MAILBOX INITIALIZATION");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) Enable Strict Round Robin Mode if supported by the Host Adapter. In
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) Strict Round Robin Mode, the Host Adapter only looks at the next
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) Outgoing Mailbox for each new command, rather than scanning
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) through all the Outgoing Mailboxes to find any that have new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) commands in them. Strict Round Robin Mode is significantly more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) efficient.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) if (adapter->strict_rr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) rr_req = BLOGIC_STRICT_RR_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) if (blogic_cmd(adapter, BLOGIC_STRICT_RR, &rr_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) sizeof(rr_req), NULL, 0) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) return blogic_failure(adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) "ENABLE STRICT ROUND ROBIN MODE");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) For Host Adapters that support Extended LUN Format CCBs, issue the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) Set CCB Format command to allow 32 Logical Units per Target Device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) if (adapter->ext_lun) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) setccb_fmt = BLOGIC_EXT_LUN_CCB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) if (blogic_cmd(adapter, BLOGIC_SETCCB_FMT, &setccb_fmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) sizeof(setccb_fmt), NULL, 0) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) return blogic_failure(adapter, "SET CCB FORMAT");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) Announce Successful Initialization.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) if (!adapter->adapter_initd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) blogic_info("*** %s Initialized Successfully ***\n", adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) adapter->full_model);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) blogic_info("\n", adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) blogic_warn("*** %s Initialized Successfully ***\n", adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) adapter->full_model);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) adapter->adapter_initd = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) Indicate the Host Adapter Initialization completed successfully.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) blogic_inquiry inquires about the Target Devices accessible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) through Host Adapter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) static bool __init blogic_inquiry(struct blogic_adapter *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) u16 installed_devs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) u8 installed_devs0to7[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) struct blogic_setup_info setupinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) u8 sync_period[BLOGIC_MAXDEV];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) unsigned char req_replylen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) int tgt_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) Wait a few seconds between the Host Adapter Hard Reset which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) initiates a SCSI Bus Reset and issuing any SCSI Commands. Some
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) SCSI devices get confused if they receive SCSI Commands too soon
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) after a SCSI Bus Reset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) blogic_delay(adapter->bus_settle_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) FlashPoint Host Adapters do not provide for Target Device Inquiry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) if (blogic_flashpoint_type(adapter))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) Inhibit the Target Device Inquiry if requested.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) if (adapter->drvr_opts != NULL && adapter->drvr_opts->stop_tgt_inquiry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) Issue the Inquire Target Devices command for host adapters with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) firmware version 4.25 or later, or the Inquire Installed Devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) ID 0 to 7 command for older host adapters. This is necessary to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) force Synchronous Transfer Negotiation so that the Inquire Setup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) Information and Inquire Synchronous Period commands will return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) valid data. The Inquire Target Devices command is preferable to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) Inquire Installed Devices ID 0 to 7 since it only probes Logical
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) Unit 0 of each Target Device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) if (strcmp(adapter->fw_ver, "4.25") >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) Issue a Inquire Target Devices command. Inquire Target
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) Devices only tests Logical Unit 0 of each Target Device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) unlike the Inquire Installed Devices commands which test
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) Logical Units 0 - 7. Two bytes are returned, where byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) 0 bit 0 set indicates that Target Device 0 exists, and so on.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) if (blogic_cmd(adapter, BLOGIC_INQ_DEV, NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) &installed_devs, sizeof(installed_devs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) != sizeof(installed_devs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) return blogic_failure(adapter, "INQUIRE TARGET DEVICES");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) adapter->tgt_flags[tgt_id].tgt_exists =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) (installed_devs & (1 << tgt_id) ? true : false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) Issue an Inquire Installed Devices command. For each
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) Target Device, a byte is returned where bit 0 set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) indicates that Logical Unit 0 * exists, bit 1 set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) indicates that Logical Unit 1 exists, and so on.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) if (blogic_cmd(adapter, BLOGIC_INQ_DEV0TO7, NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) &installed_devs0to7, sizeof(installed_devs0to7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) != sizeof(installed_devs0to7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) return blogic_failure(adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) "INQUIRE INSTALLED DEVICES ID 0 TO 7");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) for (tgt_id = 0; tgt_id < 8; tgt_id++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) adapter->tgt_flags[tgt_id].tgt_exists =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) installed_devs0to7[tgt_id] != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) Issue the Inquire Setup Information command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) req_replylen = sizeof(setupinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) if (blogic_cmd(adapter, BLOGIC_INQ_SETUPINFO, &req_replylen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) sizeof(req_replylen), &setupinfo, sizeof(setupinfo))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) != sizeof(setupinfo))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) return blogic_failure(adapter, "INQUIRE SETUP INFORMATION");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) adapter->sync_offset[tgt_id] = (tgt_id < 8 ? setupinfo.sync0to7[tgt_id].offset : setupinfo.sync8to15[tgt_id - 8].offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) if (strcmp(adapter->fw_ver, "5.06L") >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) adapter->tgt_flags[tgt_id].wide_active = (tgt_id < 8 ? (setupinfo.wide_tx_active0to7 & (1 << tgt_id) ? true : false) : (setupinfo.wide_tx_active8to15 & (1 << (tgt_id - 8)) ? true : false));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) Issue the Inquire Synchronous Period command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) if (adapter->fw_ver[0] >= '3') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) /* Issue a Inquire Synchronous Period command. For each
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) Target Device, a byte is returned which represents the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) Synchronous Transfer Period in units of 10 nanoseconds.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) req_replylen = sizeof(sync_period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) if (blogic_cmd(adapter, BLOGIC_INQ_SYNC_PERIOD, &req_replylen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) sizeof(req_replylen), &sync_period,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) sizeof(sync_period)) != sizeof(sync_period))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) return blogic_failure(adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) "INQUIRE SYNCHRONOUS PERIOD");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) adapter->sync_period[tgt_id] = sync_period[tgt_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) if (setupinfo.sync0to7[tgt_id].offset > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) adapter->sync_period[tgt_id] = 20 + 5 * setupinfo.sync0to7[tgt_id].tx_period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) Indicate the Target Device Inquiry completed successfully.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) blogic_inithoststruct initializes the fields in the SCSI Host
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) structure. The base, io_port, n_io_ports, irq, and dma_channel fields in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) SCSI Host structure are intentionally left uninitialized, as this driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) handles acquisition and release of these resources explicitly, as well as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) ensuring exclusive access to the Host Adapter hardware and data structures
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) through explicit acquisition and release of the Host Adapter's Lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) static void __init blogic_inithoststruct(struct blogic_adapter *adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) struct Scsi_Host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) host->max_id = adapter->maxdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) host->max_lun = adapter->maxlun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) host->max_channel = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) host->unique_id = adapter->io_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) host->this_id = adapter->scsi_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) host->can_queue = adapter->drvr_qdepth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) host->sg_tablesize = adapter->drvr_sglimit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) host->unchecked_isa_dma = adapter->need_bouncebuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) host->cmd_per_lun = adapter->untag_qdepth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) blogic_slaveconfig will actually set the queue depth on individual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) scsi devices as they are permanently added to the device chain. We
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) shamelessly rip off the SelectQueueDepths code to make this work mostly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) like it used to. Since we don't get called once at the end of the scan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) but instead get called for each device, we have to do things a bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) differently.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) static int blogic_slaveconfig(struct scsi_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) struct blogic_adapter *adapter =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) (struct blogic_adapter *) dev->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) int tgt_id = dev->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) int qdepth = adapter->qdepth[tgt_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) if (adapter->tgt_flags[tgt_id].tagq_ok &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) (adapter->tagq_ok & (1 << tgt_id))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) if (qdepth == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) qdepth = BLOGIC_MAX_AUTO_TAG_DEPTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) adapter->qdepth[tgt_id] = qdepth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) scsi_change_queue_depth(dev, qdepth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) adapter->tagq_ok &= ~(1 << tgt_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) qdepth = adapter->untag_qdepth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) adapter->qdepth[tgt_id] = qdepth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) scsi_change_queue_depth(dev, qdepth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) qdepth = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) if (adapter->tgt_flags[tgt_id].tgt_exists)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) qdepth += adapter->qdepth[tgt_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) if (qdepth > adapter->alloc_ccbs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) blogic_create_addlccbs(adapter, qdepth - adapter->alloc_ccbs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) blogic_init probes for BusLogic Host Adapters at the standard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) I/O Addresses where they may be located, initializing, registering, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) reporting the configuration of each BusLogic Host Adapter it finds. It
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) returns the number of BusLogic Host Adapters successfully initialized and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) registered.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) static int __init blogic_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) int adapter_count = 0, drvr_optindex = 0, probeindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) struct blogic_adapter *adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) #ifdef MODULE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) if (BusLogic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) blogic_setup(BusLogic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) if (blogic_probe_options.noprobe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) blogic_probeinfo_list =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) kcalloc(BLOGIC_MAX_ADAPTERS, sizeof(struct blogic_probeinfo),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) if (blogic_probeinfo_list == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) blogic_err("BusLogic: Unable to allocate Probe Info List\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) adapter = kzalloc(sizeof(struct blogic_adapter), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) if (adapter == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) kfree(blogic_probeinfo_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) blogic_err("BusLogic: Unable to allocate Prototype Host Adapter\n", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) #ifdef MODULE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) if (BusLogic != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) blogic_setup(BusLogic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) blogic_init_probeinfo_list(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) for (probeindex = 0; probeindex < blogic_probeinfo_count; probeindex++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) struct blogic_probeinfo *probeinfo =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) &blogic_probeinfo_list[probeindex];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) struct blogic_adapter *myadapter = adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) struct Scsi_Host *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) if (probeinfo->io_addr == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) memset(myadapter, 0, sizeof(struct blogic_adapter));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) myadapter->adapter_type = probeinfo->adapter_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) myadapter->adapter_bus_type = probeinfo->adapter_bus_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) myadapter->io_addr = probeinfo->io_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) myadapter->pci_addr = probeinfo->pci_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) myadapter->bus = probeinfo->bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) myadapter->dev = probeinfo->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) myadapter->pci_device = probeinfo->pci_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) myadapter->irq_ch = probeinfo->irq_ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) myadapter->addr_count =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) blogic_adapter_addr_count[myadapter->adapter_type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) Make sure region is free prior to probing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) if (!request_region(myadapter->io_addr, myadapter->addr_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) "BusLogic"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) Probe the Host Adapter. If unsuccessful, abort further
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) initialization.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) if (!blogic_probe(myadapter)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) release_region(myadapter->io_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) myadapter->addr_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) Hard Reset the Host Adapter. If unsuccessful, abort further
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) initialization.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) if (!blogic_hwreset(myadapter, true)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) release_region(myadapter->io_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) myadapter->addr_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) Check the Host Adapter. If unsuccessful, abort further
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) initialization.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) if (!blogic_checkadapter(myadapter)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) release_region(myadapter->io_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) myadapter->addr_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) Initialize the Driver Options field if provided.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) if (drvr_optindex < blogic_drvr_options_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) myadapter->drvr_opts =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) &blogic_drvr_options[drvr_optindex++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) Announce the Driver Version and Date, Author's Name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) Copyright Notice, and Electronic Mail Address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) blogic_announce_drvr(myadapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) Register the SCSI Host structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) host = scsi_host_alloc(&blogic_template,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) sizeof(struct blogic_adapter));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) if (host == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) release_region(myadapter->io_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) myadapter->addr_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) myadapter = (struct blogic_adapter *) host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) memcpy(myadapter, adapter, sizeof(struct blogic_adapter));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) myadapter->scsi_host = host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) myadapter->host_no = host->host_no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) Add Host Adapter to the end of the list of registered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) BusLogic Host Adapters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) list_add_tail(&myadapter->host_list, &blogic_host_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) Read the Host Adapter Configuration, Configure the Host
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) Adapter, Acquire the System Resources necessary to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) the Host Adapter, then Create the Initial CCBs, Initialize
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) the Host Adapter, and finally perform Target Device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) Inquiry. From this point onward, any failure will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) assumed to be due to a problem with the Host Adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) rather than due to having mistakenly identified this port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) as belonging to a BusLogic Host Adapter. The I/O Address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) range will not be released, thereby preventing it from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) being incorrectly identified as any other type of Host
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) Adapter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) if (blogic_rdconfig(myadapter) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) blogic_reportconfig(myadapter) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) blogic_getres(myadapter) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) blogic_create_initccbs(myadapter) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) blogic_initadapter(myadapter) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) blogic_inquiry(myadapter)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) Initialization has been completed successfully.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) Release and re-register usage of the I/O Address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) range so that the Model Name of the Host Adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) will appear, and initialize the SCSI Host structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) release_region(myadapter->io_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) myadapter->addr_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) if (!request_region(myadapter->io_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) myadapter->addr_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) myadapter->full_model)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) "BusLogic: Release and re-register of "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) "port 0x%04lx failed \n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) (unsigned long)myadapter->io_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) blogic_destroy_ccbs(myadapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) blogic_relres(myadapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) list_del(&myadapter->host_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) scsi_host_put(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) blogic_inithoststruct(myadapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) if (scsi_add_host(host, myadapter->pci_device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) ? &myadapter->pci_device->dev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) : NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) "BusLogic: scsi_add_host()"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) "failed!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) blogic_destroy_ccbs(myadapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) blogic_relres(myadapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) list_del(&myadapter->host_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) scsi_host_put(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) scsi_scan_host(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) adapter_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) An error occurred during Host Adapter Configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) Querying, Host Adapter Configuration, Resource
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) Acquisition, CCB Creation, Host Adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) Initialization, or Target Device Inquiry, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) remove Host Adapter from the list of registered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) BusLogic Host Adapters, destroy the CCBs, Release
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) the System Resources, and Unregister the SCSI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) Host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) blogic_destroy_ccbs(myadapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) blogic_relres(myadapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) list_del(&myadapter->host_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) scsi_host_put(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) kfree(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) kfree(blogic_probeinfo_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) blogic_probeinfo_list = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) blogic_deladapter releases all resources previously acquired to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) support a specific Host Adapter, including the I/O Address range, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) unregisters the BusLogic Host Adapter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) static int __exit blogic_deladapter(struct blogic_adapter *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) struct Scsi_Host *host = adapter->scsi_host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) scsi_remove_host(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) FlashPoint Host Adapters must first be released by the FlashPoint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) SCCB Manager.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) if (blogic_flashpoint_type(adapter))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) FlashPoint_ReleaseHostAdapter(adapter->cardhandle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) Destroy the CCBs and release any system resources acquired to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) support Host Adapter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) blogic_destroy_ccbs(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) blogic_relres(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) Release usage of the I/O Address range.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) release_region(adapter->io_addr, adapter->addr_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) Remove Host Adapter from the list of registered BusLogic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) Host Adapters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) list_del(&adapter->host_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) scsi_host_put(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) blogic_qcompleted_ccb queues CCB for completion processing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) static void blogic_qcompleted_ccb(struct blogic_ccb *ccb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) struct blogic_adapter *adapter = ccb->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) ccb->status = BLOGIC_CCB_COMPLETE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) ccb->next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) if (adapter->firstccb == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) adapter->firstccb = ccb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) adapter->lastccb = ccb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) adapter->lastccb->next = ccb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) adapter->lastccb = ccb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) adapter->active_cmds[ccb->tgt_id]--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) blogic_resultcode computes a SCSI Subsystem Result Code from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) the Host Adapter Status and Target Device Status.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) static int blogic_resultcode(struct blogic_adapter *adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) enum blogic_adapter_status adapter_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) enum blogic_tgt_status tgt_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) int hoststatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) switch (adapter_status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) case BLOGIC_CMD_CMPLT_NORMAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) case BLOGIC_LINK_CMD_CMPLT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) case BLOGIC_LINK_CMD_CMPLT_FLAG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) hoststatus = DID_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) case BLOGIC_SELECT_TIMEOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) hoststatus = DID_TIME_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) case BLOGIC_INVALID_OUTBOX_CODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) case BLOGIC_INVALID_CMD_CODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) case BLOGIC_BAD_CMD_PARAM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) blogic_warn("BusLogic Driver Protocol Error 0x%02X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) adapter, adapter_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) case BLOGIC_DATA_UNDERRUN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) case BLOGIC_DATA_OVERRUN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) case BLOGIC_NOEXPECT_BUSFREE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) case BLOGIC_LINKCCB_BADLUN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) case BLOGIC_AUTOREQSENSE_FAIL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) case BLOGIC_TAGQUEUE_REJECT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) case BLOGIC_BAD_MSG_RCVD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) case BLOGIC_HW_FAIL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) case BLOGIC_BAD_RECONNECT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) case BLOGIC_ABRT_QUEUE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) case BLOGIC_ADAPTER_SW_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) case BLOGIC_HW_TIMEOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) case BLOGIC_PARITY_ERR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) hoststatus = DID_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) case BLOGIC_INVALID_BUSPHASE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) case BLOGIC_NORESPONSE_TO_ATN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) case BLOGIC_HW_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) case BLOGIC_RST_FROM_OTHERDEV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) case BLOGIC_HW_BDR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) hoststatus = DID_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) blogic_warn("Unknown Host Adapter Status 0x%02X\n", adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) adapter_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) hoststatus = DID_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) return (hoststatus << 16) | tgt_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) blogic_scan_inbox scans the Incoming Mailboxes saving any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) Incoming Mailbox entries for completion processing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) static void blogic_scan_inbox(struct blogic_adapter *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) Scan through the Incoming Mailboxes in Strict Round Robin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) fashion, saving any completed CCBs for further processing. It
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) is essential that for each CCB and SCSI Command issued, command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) completion processing is performed exactly once. Therefore,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) only Incoming Mailboxes with completion code Command Completed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) Without Error, Command Completed With Error, or Command Aborted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) At Host Request are saved for completion processing. When an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) Incoming Mailbox has a completion code of Aborted Command Not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) Found, the CCB had already completed or been aborted before the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) current Abort request was processed, and so completion processing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) has already occurred and no further action should be taken.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) struct blogic_inbox *next_inbox = adapter->next_inbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) enum blogic_cmplt_code comp_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) while ((comp_code = next_inbox->comp_code) != BLOGIC_INBOX_FREE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) We are only allowed to do this because we limit our
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) architectures we run on to machines where bus_to_virt(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) actually works. There *needs* to be a dma_addr_to_virt()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) in the new PCI DMA mapping interface to replace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) bus_to_virt() or else this code is going to become very
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) innefficient.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) struct blogic_ccb *ccb =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) (struct blogic_ccb *) bus_to_virt(next_inbox->ccb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) if (comp_code != BLOGIC_CMD_NOTFOUND) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) if (ccb->status == BLOGIC_CCB_ACTIVE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) ccb->status == BLOGIC_CCB_RESET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) Save the Completion Code for this CCB and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) queue the CCB for completion processing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) ccb->comp_code = comp_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) blogic_qcompleted_ccb(ccb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) If a CCB ever appears in an Incoming Mailbox
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) and is not marked as status Active or Reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) then there is most likely a bug in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) the Host Adapter firmware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) blogic_warn("Illegal CCB #%ld status %d in Incoming Mailbox\n", adapter, ccb->serial, ccb->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) next_inbox->comp_code = BLOGIC_INBOX_FREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) if (++next_inbox > adapter->last_inbox)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) next_inbox = adapter->first_inbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) adapter->next_inbox = next_inbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) blogic_process_ccbs iterates over the completed CCBs for Host
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) Adapter setting the SCSI Command Result Codes, deallocating the CCBs, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) calling the SCSI Subsystem Completion Routines. The Host Adapter's Lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) should already have been acquired by the caller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) static void blogic_process_ccbs(struct blogic_adapter *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) if (adapter->processing_ccbs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) adapter->processing_ccbs = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) while (adapter->firstccb != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) struct blogic_ccb *ccb = adapter->firstccb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) struct scsi_cmnd *command = ccb->command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) adapter->firstccb = ccb->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) if (adapter->firstccb == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) adapter->lastccb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) Process the Completed CCB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) if (ccb->opcode == BLOGIC_BDR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) int tgt_id = ccb->tgt_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) blogic_warn("Bus Device Reset CCB #%ld to Target %d Completed\n", adapter, ccb->serial, tgt_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) blogic_inc_count(&adapter->tgt_stats[tgt_id].bdr_done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) adapter->tgt_flags[tgt_id].tagq_active = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) adapter->cmds_since_rst[tgt_id] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) adapter->last_resetdone[tgt_id] = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) Place CCB back on the Host Adapter's free list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) blogic_dealloc_ccb(ccb, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) #if 0 /* this needs to be redone different for new EH */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) Bus Device Reset CCBs have the command field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) non-NULL only when a Bus Device Reset was requested
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) for a command that did not have a currently active
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) CCB in the Host Adapter (i.e., a Synchronous Bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) Device Reset), and hence would not have its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) Completion Routine called otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) while (command != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) struct scsi_cmnd *nxt_cmd =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) command->reset_chain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) command->reset_chain = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) command->result = DID_RESET << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) command->scsi_done(command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) command = nxt_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) Iterate over the CCBs for this Host Adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) performing completion processing for any CCBs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) marked as Reset for this Target.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) for (ccb = adapter->all_ccbs; ccb != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) ccb = ccb->next_all)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) if (ccb->status == BLOGIC_CCB_RESET &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) ccb->tgt_id == tgt_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) command = ccb->command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) blogic_dealloc_ccb(ccb, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) adapter->active_cmds[tgt_id]--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) command->result = DID_RESET << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) command->scsi_done(command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) adapter->bdr_pend[tgt_id] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) Translate the Completion Code, Host Adapter Status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) and Target Device Status into a SCSI Subsystem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) Result Code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) switch (ccb->comp_code) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) case BLOGIC_INBOX_FREE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) case BLOGIC_CMD_NOTFOUND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) case BLOGIC_INVALID_CCB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) blogic_warn("CCB #%ld to Target %d Impossible State\n", adapter, ccb->serial, ccb->tgt_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) case BLOGIC_CMD_COMPLETE_GOOD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) adapter->tgt_stats[ccb->tgt_id]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) .cmds_complete++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) adapter->tgt_flags[ccb->tgt_id]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) .cmd_good = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) command->result = DID_OK << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) case BLOGIC_CMD_ABORT_BY_HOST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) blogic_warn("CCB #%ld to Target %d Aborted\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) adapter, ccb->serial, ccb->tgt_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) blogic_inc_count(&adapter->tgt_stats[ccb->tgt_id].aborts_done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) command->result = DID_ABORT << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) case BLOGIC_CMD_COMPLETE_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) command->result = blogic_resultcode(adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) ccb->adapter_status, ccb->tgt_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) if (ccb->adapter_status != BLOGIC_SELECT_TIMEOUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) adapter->tgt_stats[ccb->tgt_id]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) .cmds_complete++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) if (blogic_global_options.trace_err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) blogic_notice("CCB #%ld Target %d: Result %X Host "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) "Adapter Status %02X Target Status %02X\n", adapter, ccb->serial, ccb->tgt_id, command->result, ccb->adapter_status, ccb->tgt_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) blogic_notice("CDB ", adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) for (i = 0; i < ccb->cdblen; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) blogic_notice(" %02X", adapter, ccb->cdb[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) blogic_notice("\n", adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) blogic_notice("Sense ", adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) for (i = 0; i < ccb->sense_datalen; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) blogic_notice(" %02X", adapter, command->sense_buffer[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) blogic_notice("\n", adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) When an INQUIRY command completes normally, save the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) CmdQue (Tagged Queuing Supported) and WBus16 (16 Bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) Wide Data Transfers Supported) bits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) if (ccb->cdb[0] == INQUIRY && ccb->cdb[1] == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) ccb->adapter_status == BLOGIC_CMD_CMPLT_NORMAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) struct blogic_tgt_flags *tgt_flags =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) &adapter->tgt_flags[ccb->tgt_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) struct scsi_inquiry *inquiry =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) (struct scsi_inquiry *) scsi_sglist(command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) tgt_flags->tgt_exists = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) tgt_flags->tagq_ok = inquiry->CmdQue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) tgt_flags->wide_ok = inquiry->WBus16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) Place CCB back on the Host Adapter's free list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) blogic_dealloc_ccb(ccb, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) Call the SCSI Command Completion Routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) command->scsi_done(command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) adapter->processing_ccbs = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) blogic_inthandler handles hardware interrupts from BusLogic Host
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) Adapters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) static irqreturn_t blogic_inthandler(int irq_ch, void *devid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) struct blogic_adapter *adapter = (struct blogic_adapter *) devid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) unsigned long processor_flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) Acquire exclusive access to Host Adapter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) spin_lock_irqsave(adapter->scsi_host->host_lock, processor_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) Handle Interrupts appropriately for each Host Adapter type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) if (blogic_multimaster_type(adapter)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) union blogic_int_reg intreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) Read the Host Adapter Interrupt Register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) intreg.all = blogic_rdint(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) if (intreg.ir.int_valid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) Acknowledge the interrupt and reset the Host Adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) Interrupt Register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) blogic_intreset(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) Process valid External SCSI Bus Reset and Incoming
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) Mailbox Loaded Interrupts. Command Complete
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) Interrupts are noted, and Outgoing Mailbox Available
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) Interrupts are ignored, as they are never enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) if (intreg.ir.ext_busreset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) adapter->adapter_extreset = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) else if (intreg.ir.mailin_loaded)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) blogic_scan_inbox(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) else if (intreg.ir.cmd_complete)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) adapter->adapter_cmd_complete = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) Check if there is a pending interrupt for this Host Adapter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) if (FlashPoint_InterruptPending(adapter->cardhandle))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) switch (FlashPoint_HandleInterrupt(adapter->cardhandle)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) case FPOINT_NORMAL_INT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) case FPOINT_EXT_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) adapter->adapter_extreset = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) case FPOINT_INTERN_ERR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) blogic_warn("Internal FlashPoint Error detected - Resetting Host Adapter\n", adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) adapter->adapter_intern_err = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) Process any completed CCBs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) if (adapter->firstccb != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) blogic_process_ccbs(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) Reset the Host Adapter if requested.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) if (adapter->adapter_extreset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) blogic_warn("Resetting %s due to External SCSI Bus Reset\n", adapter, adapter->full_model);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) blogic_inc_count(&adapter->ext_resets);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) blogic_resetadapter(adapter, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) adapter->adapter_extreset = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) } else if (adapter->adapter_intern_err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) blogic_warn("Resetting %s due to Host Adapter Internal Error\n", adapter, adapter->full_model);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) blogic_inc_count(&adapter->adapter_intern_errors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) blogic_resetadapter(adapter, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) adapter->adapter_intern_err = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) Release exclusive access to Host Adapter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) spin_unlock_irqrestore(adapter->scsi_host->host_lock, processor_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) blogic_write_outbox places CCB and Action Code into an Outgoing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) Mailbox for execution by Host Adapter. The Host Adapter's Lock should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) already have been acquired by the caller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) static bool blogic_write_outbox(struct blogic_adapter *adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) enum blogic_action action, struct blogic_ccb *ccb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) struct blogic_outbox *next_outbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) next_outbox = adapter->next_outbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) if (next_outbox->action == BLOGIC_OUTBOX_FREE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) ccb->status = BLOGIC_CCB_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) The CCB field must be written before the Action Code field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) since the Host Adapter is operating asynchronously and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) locking code does not protect against simultaneous access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) by the Host Adapter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) next_outbox->ccb = ccb->dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) next_outbox->action = action;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) blogic_execmbox(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) if (++next_outbox > adapter->last_outbox)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) next_outbox = adapter->first_outbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) adapter->next_outbox = next_outbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) if (action == BLOGIC_MBOX_START) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) adapter->active_cmds[ccb->tgt_id]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) if (ccb->opcode != BLOGIC_BDR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) adapter->tgt_stats[ccb->tgt_id].cmds_tried++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) /* Error Handling (EH) support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) static int blogic_hostreset(struct scsi_cmnd *SCpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) struct blogic_adapter *adapter =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) (struct blogic_adapter *) SCpnt->device->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) unsigned int id = SCpnt->device->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) struct blogic_tgt_stats *stats = &adapter->tgt_stats[id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) spin_lock_irq(SCpnt->device->host->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) blogic_inc_count(&stats->adapter_reset_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) rc = blogic_resetadapter(adapter, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) spin_unlock_irq(SCpnt->device->host->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) blogic_qcmd creates a CCB for Command and places it into an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) Outgoing Mailbox for execution by the associated Host Adapter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) static int blogic_qcmd_lck(struct scsi_cmnd *command,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) void (*comp_cb) (struct scsi_cmnd *))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) struct blogic_adapter *adapter =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) (struct blogic_adapter *) command->device->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) struct blogic_tgt_flags *tgt_flags =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) &adapter->tgt_flags[command->device->id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) struct blogic_tgt_stats *tgt_stats = adapter->tgt_stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) unsigned char *cdb = command->cmnd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) int cdblen = command->cmd_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) int tgt_id = command->device->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) int lun = command->device->lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) int buflen = scsi_bufflen(command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) struct blogic_ccb *ccb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) dma_addr_t sense_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) SCSI REQUEST_SENSE commands will be executed automatically by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) Host Adapter for any errors, so they should not be executed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) explicitly unless the Sense Data is zero indicating that no error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) occurred.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) if (cdb[0] == REQUEST_SENSE && command->sense_buffer[0] != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) command->result = DID_OK << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) comp_cb(command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) Allocate a CCB from the Host Adapter's free list. In the unlikely
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) event that there are none available and memory allocation fails,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) wait 1 second and try again. If that fails, the Host Adapter is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) probably hung so signal an error as a Host Adapter Hard Reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) should be initiated soon.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) ccb = blogic_alloc_ccb(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) if (ccb == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) spin_unlock_irq(adapter->scsi_host->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) blogic_delay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) spin_lock_irq(adapter->scsi_host->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) ccb = blogic_alloc_ccb(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) if (ccb == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) command->result = DID_ERROR << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) comp_cb(command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) Initialize the fields in the BusLogic Command Control Block (CCB).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) count = scsi_dma_map(command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) BUG_ON(count < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) if (count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) struct scatterlist *sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) ccb->opcode = BLOGIC_INITIATOR_CCB_SG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) ccb->datalen = count * sizeof(struct blogic_sg_seg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) if (blogic_multimaster_type(adapter))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) ccb->data = (unsigned int) ccb->dma_handle +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) ((unsigned long) &ccb->sglist -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) (unsigned long) ccb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) ccb->data = virt_to_32bit_virt(ccb->sglist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) scsi_for_each_sg(command, sg, count, i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) ccb->sglist[i].segbytes = sg_dma_len(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) ccb->sglist[i].segdata = sg_dma_address(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) } else if (!count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) ccb->opcode = BLOGIC_INITIATOR_CCB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) ccb->datalen = buflen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) ccb->data = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) switch (cdb[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) case READ_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) case READ_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) ccb->datadir = BLOGIC_DATAIN_CHECKED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) tgt_stats[tgt_id].read_cmds++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) blogic_addcount(&tgt_stats[tgt_id].bytesread, buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) blogic_incszbucket(tgt_stats[tgt_id].read_sz_buckets, buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) case WRITE_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) case WRITE_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) ccb->datadir = BLOGIC_DATAOUT_CHECKED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) tgt_stats[tgt_id].write_cmds++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) blogic_addcount(&tgt_stats[tgt_id].byteswritten, buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) blogic_incszbucket(tgt_stats[tgt_id].write_sz_buckets, buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) ccb->datadir = BLOGIC_UNCHECKED_TX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) ccb->cdblen = cdblen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) ccb->adapter_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) ccb->tgt_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) ccb->tgt_id = tgt_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) ccb->lun = lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) ccb->tag_enable = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) ccb->legacytag_enable = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) BusLogic recommends that after a Reset the first couple of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) commands that are sent to a Target Device be sent in a non
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) Tagged Queue fashion so that the Host Adapter and Target Device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) can establish Synchronous and Wide Transfer before Queue Tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) messages can interfere with the Synchronous and Wide Negotiation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) messages. By waiting to enable Tagged Queuing until after the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) first BLOGIC_MAX_TAG_DEPTH commands have been queued, it is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) assured that after a Reset any pending commands are requeued
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) before Tagged Queuing is enabled and that the Tagged Queuing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) message will not occur while the partition table is being printed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) In addition, some devices do not properly handle the transition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) from non-tagged to tagged commands, so it is necessary to wait
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) until there are no pending commands for a target device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) before queuing tagged commands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) if (adapter->cmds_since_rst[tgt_id]++ >= BLOGIC_MAX_TAG_DEPTH &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) !tgt_flags->tagq_active &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) adapter->active_cmds[tgt_id] == 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) && tgt_flags->tagq_ok &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) (adapter->tagq_ok & (1 << tgt_id))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) tgt_flags->tagq_active = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) blogic_notice("Tagged Queuing now active for Target %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) adapter, tgt_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) if (tgt_flags->tagq_active) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) enum blogic_queuetag queuetag = BLOGIC_SIMPLETAG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) When using Tagged Queuing with Simple Queue Tags, it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) appears that disk drive controllers do not guarantee that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) a queued command will not remain in a disconnected state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) indefinitely if commands that read or write nearer the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) head position continue to arrive without interruption.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) Therefore, for each Target Device this driver keeps track
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) of the last time either the queue was empty or an Ordered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) Queue Tag was issued. If more than 4 seconds (one fifth
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) of the 20 second disk timeout) have elapsed since this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) last sequence point, this command will be issued with an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) Ordered Queue Tag rather than a Simple Queue Tag, which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) forces the Target Device to complete all previously
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) queued commands before this command may be executed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) if (adapter->active_cmds[tgt_id] == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) adapter->last_seqpoint[tgt_id] = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) else if (time_after(jiffies,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) adapter->last_seqpoint[tgt_id] + 4 * HZ)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) adapter->last_seqpoint[tgt_id] = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) queuetag = BLOGIC_ORDEREDTAG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) if (adapter->ext_lun) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) ccb->tag_enable = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) ccb->queuetag = queuetag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) ccb->legacytag_enable = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) ccb->legacy_tag = queuetag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) memcpy(ccb->cdb, cdb, cdblen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) ccb->sense_datalen = SCSI_SENSE_BUFFERSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) ccb->command = command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) sense_buf = dma_map_single(&adapter->pci_device->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) command->sense_buffer, ccb->sense_datalen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) if (dma_mapping_error(&adapter->pci_device->dev, sense_buf)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) blogic_err("DMA mapping for sense data buffer failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) blogic_dealloc_ccb(ccb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) return SCSI_MLQUEUE_HOST_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) ccb->sensedata = sense_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) command->scsi_done = comp_cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) if (blogic_multimaster_type(adapter)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) Place the CCB in an Outgoing Mailbox. The higher levels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) of the SCSI Subsystem should not attempt to queue more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) commands than can be placed in Outgoing Mailboxes, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) there should always be one free. In the unlikely event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) that there are none available, wait 1 second and try
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) again. If that fails, the Host Adapter is probably hung
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) so signal an error as a Host Adapter Hard Reset should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) be initiated soon.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) if (!blogic_write_outbox(adapter, BLOGIC_MBOX_START, ccb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) spin_unlock_irq(adapter->scsi_host->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) blogic_warn("Unable to write Outgoing Mailbox - Pausing for 1 second\n", adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) blogic_delay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) spin_lock_irq(adapter->scsi_host->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) if (!blogic_write_outbox(adapter, BLOGIC_MBOX_START,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) ccb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) blogic_warn("Still unable to write Outgoing Mailbox - Host Adapter Dead?\n", adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) blogic_dealloc_ccb(ccb, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) command->result = DID_ERROR << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) command->scsi_done(command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) Call the FlashPoint SCCB Manager to start execution of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) the CCB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) ccb->status = BLOGIC_CCB_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) adapter->active_cmds[tgt_id]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) tgt_stats[tgt_id].cmds_tried++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) FlashPoint_StartCCB(adapter->cardhandle, ccb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) The Command may have already completed and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) blogic_qcompleted_ccb been called, or it may still be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) pending.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) if (ccb->status == BLOGIC_CCB_COMPLETE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) blogic_process_ccbs(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) static DEF_SCSI_QCMD(blogic_qcmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) blogic_abort aborts Command if possible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) static int blogic_abort(struct scsi_cmnd *command)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) struct blogic_adapter *adapter =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) (struct blogic_adapter *) command->device->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) int tgt_id = command->device->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) struct blogic_ccb *ccb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) blogic_inc_count(&adapter->tgt_stats[tgt_id].aborts_request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) Attempt to find an Active CCB for this Command. If no Active
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) CCB for this Command is found, then no Abort is necessary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) for (ccb = adapter->all_ccbs; ccb != NULL; ccb = ccb->next_all)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) if (ccb->command == command)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) if (ccb == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) blogic_warn("Unable to Abort Command to Target %d - No CCB Found\n", adapter, tgt_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) return SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) } else if (ccb->status == BLOGIC_CCB_COMPLETE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) blogic_warn("Unable to Abort Command to Target %d - CCB Completed\n", adapter, tgt_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) return SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) } else if (ccb->status == BLOGIC_CCB_RESET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) blogic_warn("Unable to Abort Command to Target %d - CCB Reset\n", adapter, tgt_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) return SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) if (blogic_multimaster_type(adapter)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) Attempt to Abort this CCB. MultiMaster Firmware versions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) prior to 5.xx do not generate Abort Tag messages, but only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) generate the non-tagged Abort message. Since non-tagged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) commands are not sent by the Host Adapter until the queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) of outstanding tagged commands has completed, and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) Abort message is treated as a non-tagged command, it is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) effectively impossible to abort commands when Tagged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) Queuing is active. Firmware version 5.xx does generate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) Abort Tag messages, so it is possible to abort commands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) when Tagged Queuing is active.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) if (adapter->tgt_flags[tgt_id].tagq_active &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) adapter->fw_ver[0] < '5') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) blogic_warn("Unable to Abort CCB #%ld to Target %d - Abort Tag Not Supported\n", adapter, ccb->serial, tgt_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) return FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) } else if (blogic_write_outbox(adapter, BLOGIC_MBOX_ABORT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) ccb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) blogic_warn("Aborting CCB #%ld to Target %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) adapter, ccb->serial, tgt_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) blogic_inc_count(&adapter->tgt_stats[tgt_id].aborts_tried);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) return SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) blogic_warn("Unable to Abort CCB #%ld to Target %d - No Outgoing Mailboxes\n", adapter, ccb->serial, tgt_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) return FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) Call the FlashPoint SCCB Manager to abort execution of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) the CCB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) blogic_warn("Aborting CCB #%ld to Target %d\n", adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) ccb->serial, tgt_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) blogic_inc_count(&adapter->tgt_stats[tgt_id].aborts_tried);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) FlashPoint_AbortCCB(adapter->cardhandle, ccb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) The Abort may have already been completed and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) blogic_qcompleted_ccb been called, or it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) may still be pending.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) if (ccb->status == BLOGIC_CCB_COMPLETE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) blogic_process_ccbs(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) return SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) return SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) blogic_resetadapter resets Host Adapter if possible, marking all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) currently executing SCSI Commands as having been Reset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) static int blogic_resetadapter(struct blogic_adapter *adapter, bool hard_reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) struct blogic_ccb *ccb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) int tgt_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) * Attempt to Reset and Reinitialize the Host Adapter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) if (!(blogic_hwreset(adapter, hard_reset) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) blogic_initadapter(adapter))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) blogic_err("Resetting %s Failed\n", adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) adapter->full_model);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) return FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) * Deallocate all currently executing CCBs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) for (ccb = adapter->all_ccbs; ccb != NULL; ccb = ccb->next_all)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) if (ccb->status == BLOGIC_CCB_ACTIVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) blogic_dealloc_ccb(ccb, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) * Wait a few seconds between the Host Adapter Hard Reset which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) * initiates a SCSI Bus Reset and issuing any SCSI Commands. Some
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) * SCSI devices get confused if they receive SCSI Commands too soon
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) * after a SCSI Bus Reset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) if (hard_reset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356) spin_unlock_irq(adapter->scsi_host->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) blogic_delay(adapter->bus_settle_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358) spin_lock_irq(adapter->scsi_host->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) adapter->last_resettried[tgt_id] = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) adapter->last_resetdone[tgt_id] = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) return SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) blogic_diskparam returns the Heads/Sectors/Cylinders BIOS Disk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) Parameters for Disk. The default disk geometry is 64 heads, 32 sectors, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) the appropriate number of cylinders so as not to exceed drive capacity. In
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) order for disks equal to or larger than 1 GB to be addressable by the BIOS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) without exceeding the BIOS limitation of 1024 cylinders, Extended Translation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) may be enabled in AutoSCSI on FlashPoint Host Adapters and on "W" and "C"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) series MultiMaster Host Adapters, or by a dip switch setting on "S" and "A"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) series MultiMaster Host Adapters. With Extended Translation enabled, drives
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) between 1 GB inclusive and 2 GB exclusive are given a disk geometry of 128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) heads and 32 sectors, and drives above 2 GB inclusive are given a disk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) geometry of 255 heads and 63 sectors. However, if the BIOS detects that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) Extended Translation setting does not match the geometry in the partition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) table, then the translation inferred from the partition table will be used by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) the BIOS, and a warning may be displayed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) static int blogic_diskparam(struct scsi_device *sdev, struct block_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) sector_t capacity, int *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) struct blogic_adapter *adapter =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) (struct blogic_adapter *) sdev->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) struct bios_diskparam *diskparam = (struct bios_diskparam *) params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) unsigned char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) if (adapter->ext_trans_enable && capacity >= 2 * 1024 * 1024 /* 1 GB in 512 byte sectors */) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) if (capacity >= 4 * 1024 * 1024 /* 2 GB in 512 byte sectors */) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) diskparam->heads = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396) diskparam->sectors = 63;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) diskparam->heads = 128;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) diskparam->sectors = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) diskparam->heads = 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) diskparam->sectors = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) diskparam->cylinders = (unsigned long) capacity / (diskparam->heads * diskparam->sectors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) buf = scsi_bios_ptable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) if (buf == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) If the boot sector partition table flag is valid, search for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) a partition table entry whose end_head matches one of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) standard BusLogic geometry translations (64/32, 128/32, or 255/63).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) if (*(unsigned short *) (buf + 64) == MSDOS_LABEL_MAGIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) struct msdos_partition *part1_entry =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) (struct msdos_partition *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) struct msdos_partition *part_entry = part1_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) int saved_cyl = diskparam->cylinders, part_no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) unsigned char part_end_head = 0, part_end_sector = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) for (part_no = 0; part_no < 4; part_no++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) part_end_head = part_entry->end_head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) part_end_sector = part_entry->end_sector & 0x3F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) if (part_end_head == 64 - 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) diskparam->heads = 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) diskparam->sectors = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) } else if (part_end_head == 128 - 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) diskparam->heads = 128;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) diskparam->sectors = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) } else if (part_end_head == 255 - 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) diskparam->heads = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) diskparam->sectors = 63;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) part_entry++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439) if (part_no == 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) part_end_head = part1_entry->end_head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) part_end_sector = part1_entry->end_sector & 0x3F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443) diskparam->cylinders = (unsigned long) capacity / (diskparam->heads * diskparam->sectors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) if (part_no < 4 && part_end_sector == diskparam->sectors) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) if (diskparam->cylinders != saved_cyl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) blogic_warn("Adopting Geometry %d/%d from Partition Table\n", adapter, diskparam->heads, diskparam->sectors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) } else if (part_end_head > 0 || part_end_sector > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) blogic_warn("Warning: Partition Table appears to have Geometry %d/%d which is\n", adapter, part_end_head + 1, part_end_sector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) blogic_warn("not compatible with current BusLogic Host Adapter Geometry %d/%d\n", adapter, diskparam->heads, diskparam->sectors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) BugLogic_ProcDirectoryInfo implements /proc/scsi/BusLogic/<N>.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461) static int blogic_write_info(struct Scsi_Host *shost, char *procbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) int bytes_avail)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) struct blogic_adapter *adapter =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) (struct blogic_adapter *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) struct blogic_tgt_stats *tgt_stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) tgt_stats = adapter->tgt_stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) adapter->ext_resets = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) adapter->adapter_intern_errors = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) memset(tgt_stats, 0, BLOGIC_MAXDEV * sizeof(struct blogic_tgt_stats));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) static int blogic_show_info(struct seq_file *m, struct Scsi_Host *shost)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) struct blogic_adapter *adapter = (struct blogic_adapter *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478) struct blogic_tgt_stats *tgt_stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) int tgt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) tgt_stats = adapter->tgt_stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) seq_write(m, adapter->msgbuf, adapter->msgbuflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483) seq_printf(m, "\n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484) Current Driver Queue Depth: %d\n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485) Currently Allocated CCBs: %d\n", adapter->drvr_qdepth, adapter->alloc_ccbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) seq_puts(m, "\n\n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) DATA TRANSFER STATISTICS\n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) \n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489) Target Tagged Queuing Queue Depth Active Attempted Completed\n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) ====== ============== =========== ====== ========= =========\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491) for (tgt = 0; tgt < adapter->maxdev; tgt++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) struct blogic_tgt_flags *tgt_flags = &adapter->tgt_flags[tgt];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) if (!tgt_flags->tgt_exists)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) seq_printf(m, " %2d %s", tgt, (tgt_flags->tagq_ok ? (tgt_flags->tagq_active ? " Active" : (adapter->tagq_ok & (1 << tgt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) ? " Permitted" : " Disabled"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497) : "Not Supported"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) " %3d %3u %9u %9u\n", adapter->qdepth[tgt], adapter->active_cmds[tgt], tgt_stats[tgt].cmds_tried, tgt_stats[tgt].cmds_complete);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) seq_puts(m, "\n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) Target Read Commands Write Commands Total Bytes Read Total Bytes Written\n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) ====== ============= ============== =================== ===================\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) for (tgt = 0; tgt < adapter->maxdev; tgt++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) struct blogic_tgt_flags *tgt_flags = &adapter->tgt_flags[tgt];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) if (!tgt_flags->tgt_exists)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) seq_printf(m, " %2d %9u %9u", tgt, tgt_stats[tgt].read_cmds, tgt_stats[tgt].write_cmds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) if (tgt_stats[tgt].bytesread.billions > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) seq_printf(m, " %9u%09u", tgt_stats[tgt].bytesread.billions, tgt_stats[tgt].bytesread.units);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) seq_printf(m, " %9u", tgt_stats[tgt].bytesread.units);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) if (tgt_stats[tgt].byteswritten.billions > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) seq_printf(m, " %9u%09u\n", tgt_stats[tgt].byteswritten.billions, tgt_stats[tgt].byteswritten.units);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) seq_printf(m, " %9u\n", tgt_stats[tgt].byteswritten.units);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518) seq_puts(m, "\n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) Target Command 0-1KB 1-2KB 2-4KB 4-8KB 8-16KB\n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520) ====== ======= ========= ========= ========= ========= =========\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) for (tgt = 0; tgt < adapter->maxdev; tgt++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) struct blogic_tgt_flags *tgt_flags = &adapter->tgt_flags[tgt];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) if (!tgt_flags->tgt_exists)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) " %2d Read %9u %9u %9u %9u %9u\n", tgt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527) tgt_stats[tgt].read_sz_buckets[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528) tgt_stats[tgt].read_sz_buckets[1], tgt_stats[tgt].read_sz_buckets[2], tgt_stats[tgt].read_sz_buckets[3], tgt_stats[tgt].read_sz_buckets[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530) " %2d Write %9u %9u %9u %9u %9u\n", tgt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) tgt_stats[tgt].write_sz_buckets[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) tgt_stats[tgt].write_sz_buckets[1], tgt_stats[tgt].write_sz_buckets[2], tgt_stats[tgt].write_sz_buckets[3], tgt_stats[tgt].write_sz_buckets[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) seq_puts(m, "\n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) Target Command 16-32KB 32-64KB 64-128KB 128-256KB 256KB+\n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536) ====== ======= ========= ========= ========= ========= =========\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) for (tgt = 0; tgt < adapter->maxdev; tgt++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) struct blogic_tgt_flags *tgt_flags = &adapter->tgt_flags[tgt];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539) if (!tgt_flags->tgt_exists)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541) seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) " %2d Read %9u %9u %9u %9u %9u\n", tgt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) tgt_stats[tgt].read_sz_buckets[5],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) tgt_stats[tgt].read_sz_buckets[6], tgt_stats[tgt].read_sz_buckets[7], tgt_stats[tgt].read_sz_buckets[8], tgt_stats[tgt].read_sz_buckets[9]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546) " %2d Write %9u %9u %9u %9u %9u\n", tgt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) tgt_stats[tgt].write_sz_buckets[5],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) tgt_stats[tgt].write_sz_buckets[6], tgt_stats[tgt].write_sz_buckets[7], tgt_stats[tgt].write_sz_buckets[8], tgt_stats[tgt].write_sz_buckets[9]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) seq_puts(m, "\n\n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) ERROR RECOVERY STATISTICS\n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552) \n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553) Command Aborts Bus Device Resets Host Adapter Resets\n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) Target Requested Completed Requested Completed Requested Completed\n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555) ID \\\\\\\\ Attempted //// \\\\\\\\ Attempted //// \\\\\\\\ Attempted ////\n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556) ====== ===== ===== ===== ===== ===== ===== ===== ===== =====\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) for (tgt = 0; tgt < adapter->maxdev; tgt++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) struct blogic_tgt_flags *tgt_flags = &adapter->tgt_flags[tgt];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) if (!tgt_flags->tgt_exists)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) seq_printf(m, " %2d %5d %5d %5d %5d %5d %5d %5d %5d %5d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) tgt, tgt_stats[tgt].aborts_request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) tgt_stats[tgt].aborts_tried,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) tgt_stats[tgt].aborts_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565) tgt_stats[tgt].bdr_request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) tgt_stats[tgt].bdr_tried,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567) tgt_stats[tgt].bdr_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) tgt_stats[tgt].adapter_reset_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) tgt_stats[tgt].adapter_reset_attempt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570) tgt_stats[tgt].adapter_reset_done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) seq_printf(m, "\nExternal Host Adapter Resets: %d\n", adapter->ext_resets);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573) seq_printf(m, "Host Adapter Internal Errors: %d\n", adapter->adapter_intern_errors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) blogic_msg prints Driver Messages.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) static void blogic_msg(enum blogic_msglevel msglevel, char *fmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) struct blogic_adapter *adapter, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) static char buf[BLOGIC_LINEBUF_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586) static bool begin = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) va_list args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) int len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) va_start(args, adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591) len = vsprintf(buf, fmt, args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592) va_end(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) if (msglevel == BLOGIC_ANNOUNCE_LEVEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) static int msglines = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) strcpy(&adapter->msgbuf[adapter->msgbuflen], buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) adapter->msgbuflen += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) if (++msglines <= 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) printk("%sscsi: %s", blogic_msglevelmap[msglevel], buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) } else if (msglevel == BLOGIC_INFO_LEVEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600) strcpy(&adapter->msgbuf[adapter->msgbuflen], buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601) adapter->msgbuflen += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) if (begin) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) if (buf[0] != '\n' || len > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) printk("%sscsi%d: %s", blogic_msglevelmap[msglevel], adapter->host_no, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) pr_cont("%s", buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) if (begin) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609) if (adapter != NULL && adapter->adapter_initd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) printk("%sscsi%d: %s", blogic_msglevelmap[msglevel], adapter->host_no, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612) printk("%s%s", blogic_msglevelmap[msglevel], buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) pr_cont("%s", buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) begin = (buf[len - 1] == '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) blogic_parse parses an individual option keyword. It returns true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) and updates the pointer if the keyword is recognized and false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) static bool __init blogic_parse(char **str, char *keyword)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) char *pointer = *str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628) while (*keyword != '\0') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629) char strch = *pointer++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630) char keywordch = *keyword++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) if (strch >= 'A' && strch <= 'Z')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) strch += 'a' - 'Z';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) if (keywordch >= 'A' && keywordch <= 'Z')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634) keywordch += 'a' - 'Z';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) if (strch != keywordch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) *str = pointer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644) blogic_parseopts handles processing of BusLogic Driver Options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645) specifications.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647) BusLogic Driver Options may be specified either via the Linux Kernel Command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648) Line or via the Loadable Kernel Module Installation Facility. Driver Options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) for multiple host adapters may be specified either by separating the option
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650) strings by a semicolon, or by specifying multiple "BusLogic=" strings on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651) command line. Individual option specifications for a single host adapter are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652) separated by commas. The Probing and Debugging Options apply to all host
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653) adapters whereas the remaining options apply individually only to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) selected host adapter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) The BusLogic Driver Probing Options are described in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657) <file:Documentation/scsi/BusLogic.rst>.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) static int __init blogic_parseopts(char *options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662) while (true) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663) struct blogic_drvr_options *drvr_opts =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664) &blogic_drvr_options[blogic_drvr_options_count++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) int tgt_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) memset(drvr_opts, 0, sizeof(struct blogic_drvr_options));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668) while (*options != '\0' && *options != ';') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669) /* Probing Options. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670) if (blogic_parse(&options, "IO:")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671) unsigned long io_addr = simple_strtoul(options,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672) &options, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673) blogic_probe_options.limited_isa = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674) switch (io_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675) case 0x330:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676) blogic_probe_options.probe330 = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678) case 0x334:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679) blogic_probe_options.probe334 = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681) case 0x230:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682) blogic_probe_options.probe230 = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684) case 0x234:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685) blogic_probe_options.probe234 = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687) case 0x130:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688) blogic_probe_options.probe130 = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690) case 0x134:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691) blogic_probe_options.probe134 = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694) blogic_err("BusLogic: Invalid Driver Options (invalid I/O Address 0x%lX)\n", NULL, io_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697) } else if (blogic_parse(&options, "NoProbeISA"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698) blogic_probe_options.noprobe_isa = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699) else if (blogic_parse(&options, "NoProbePCI"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700) blogic_probe_options.noprobe_pci = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701) else if (blogic_parse(&options, "NoProbe"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702) blogic_probe_options.noprobe = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703) else if (blogic_parse(&options, "NoSortPCI"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704) blogic_probe_options.nosort_pci = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3705) else if (blogic_parse(&options, "MultiMasterFirst"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706) blogic_probe_options.multimaster_first = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707) else if (blogic_parse(&options, "FlashPointFirst"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3708) blogic_probe_options.flashpoint_first = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3709) /* Tagged Queuing Options. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3710) else if (blogic_parse(&options, "QueueDepth:[") ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3711) blogic_parse(&options, "QD:[")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712) for (tgt_id = 0; tgt_id < BLOGIC_MAXDEV; tgt_id++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713) unsigned short qdepth = simple_strtoul(options, &options, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) if (qdepth > BLOGIC_MAX_TAG_DEPTH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715) blogic_err("BusLogic: Invalid Driver Options (invalid Queue Depth %d)\n", NULL, qdepth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718) drvr_opts->qdepth[tgt_id] = qdepth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719) if (*options == ',')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720) options++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721) else if (*options == ']')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724) blogic_err("BusLogic: Invalid Driver Options (',' or ']' expected at '%s')\n", NULL, options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728) if (*options != ']') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729) blogic_err("BusLogic: Invalid Driver Options (']' expected at '%s')\n", NULL, options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732) options++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733) } else if (blogic_parse(&options, "QueueDepth:") || blogic_parse(&options, "QD:")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734) unsigned short qdepth = simple_strtoul(options, &options, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735) if (qdepth == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736) qdepth > BLOGIC_MAX_TAG_DEPTH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737) blogic_err("BusLogic: Invalid Driver Options (invalid Queue Depth %d)\n", NULL, qdepth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740) drvr_opts->common_qdepth = qdepth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741) for (tgt_id = 0; tgt_id < BLOGIC_MAXDEV; tgt_id++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742) drvr_opts->qdepth[tgt_id] = qdepth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743) } else if (blogic_parse(&options, "TaggedQueuing:") ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) blogic_parse(&options, "TQ:")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745) if (blogic_parse(&options, "Default")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746) drvr_opts->tagq_ok = 0x0000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747) drvr_opts->tagq_ok_mask = 0x0000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748) } else if (blogic_parse(&options, "Enable")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749) drvr_opts->tagq_ok = 0xFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750) drvr_opts->tagq_ok_mask = 0xFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751) } else if (blogic_parse(&options, "Disable")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752) drvr_opts->tagq_ok = 0x0000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753) drvr_opts->tagq_ok_mask = 0xFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755) unsigned short tgt_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756) for (tgt_id = 0, tgt_bit = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757) tgt_id < BLOGIC_MAXDEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758) tgt_id++, tgt_bit <<= 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759) switch (*options++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760) case 'Y':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761) drvr_opts->tagq_ok |= tgt_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762) drvr_opts->tagq_ok_mask |= tgt_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764) case 'N':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3765) drvr_opts->tagq_ok &= ~tgt_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3766) drvr_opts->tagq_ok_mask |= tgt_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3767) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768) case 'X':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771) options--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772) tgt_id = BLOGIC_MAXDEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777) /* Miscellaneous Options. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778) else if (blogic_parse(&options, "BusSettleTime:") ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779) blogic_parse(&options, "BST:")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780) unsigned short bus_settle_time =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781) simple_strtoul(options, &options, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782) if (bus_settle_time > 5 * 60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783) blogic_err("BusLogic: Invalid Driver Options (invalid Bus Settle Time %d)\n", NULL, bus_settle_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3786) drvr_opts->bus_settle_time = bus_settle_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3787) } else if (blogic_parse(&options,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3788) "InhibitTargetInquiry"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3789) drvr_opts->stop_tgt_inquiry = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790) /* Debugging Options. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791) else if (blogic_parse(&options, "TraceProbe"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3792) blogic_global_options.trace_probe = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3793) else if (blogic_parse(&options, "TraceHardwareReset"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3794) blogic_global_options.trace_hw_reset = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3795) else if (blogic_parse(&options, "TraceConfiguration"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3796) blogic_global_options.trace_config = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3797) else if (blogic_parse(&options, "TraceErrors"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798) blogic_global_options.trace_err = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799) else if (blogic_parse(&options, "Debug")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800) blogic_global_options.trace_probe = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801) blogic_global_options.trace_hw_reset = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802) blogic_global_options.trace_config = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803) blogic_global_options.trace_err = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805) if (*options == ',')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806) options++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807) else if (*options != ';' && *options != '\0') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808) blogic_err("BusLogic: Unexpected Driver Option '%s' ignored\n", NULL, options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809) *options = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812) if (!(blogic_drvr_options_count == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813) blogic_probeinfo_count == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814) blogic_drvr_options_count == blogic_probeinfo_count)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815) blogic_err("BusLogic: Invalid Driver Options (all or no I/O Addresses must be specified)\n", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819) Tagged Queuing is disabled when the Queue Depth is 1 since queuing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820) multiple commands is not possible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822) for (tgt_id = 0; tgt_id < BLOGIC_MAXDEV; tgt_id++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823) if (drvr_opts->qdepth[tgt_id] == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824) unsigned short tgt_bit = 1 << tgt_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825) drvr_opts->tagq_ok &= ~tgt_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826) drvr_opts->tagq_ok_mask |= tgt_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828) if (*options == ';')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3829) options++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3830) if (*options == '\0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3831) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837) Get it all started
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840) static struct scsi_host_template blogic_template = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841) .module = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842) .proc_name = "BusLogic",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843) .write_info = blogic_write_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844) .show_info = blogic_show_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845) .name = "BusLogic",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) .info = blogic_drvr_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847) .queuecommand = blogic_qcmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3848) .slave_configure = blogic_slaveconfig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3849) .bios_param = blogic_diskparam,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3850) .eh_host_reset_handler = blogic_hostreset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3851) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3852) .eh_abort_handler = blogic_abort,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3853) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3854) .unchecked_isa_dma = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3855) .max_sectors = 128,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3856) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3858) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3859) blogic_setup handles processing of Kernel Command Line Arguments.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3860) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3862) static int __init blogic_setup(char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3863) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3864) int ints[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3866) (void) get_options(str, ARRAY_SIZE(ints), ints);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3868) if (ints[0] != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3869) blogic_err("BusLogic: Obsolete Command Line Entry Format Ignored\n", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3870) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3872) if (str == NULL || *str == '\0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3873) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3874) return blogic_parseopts(str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3877) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3878) * Exit function. Deletes all hosts associated with this driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3879) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3881) static void __exit blogic_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3882) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3883) struct blogic_adapter *ha, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3885) list_for_each_entry_safe(ha, next, &blogic_host_list, host_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3886) blogic_deladapter(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3887) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3889) __setup("BusLogic=", blogic_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3891) #ifdef MODULE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3892) /*static struct pci_device_id blogic_pci_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3893) { PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3894) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3895) { PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3896) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3897) { PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3898) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3899) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3900) };*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3901) static const struct pci_device_id blogic_pci_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3902) {PCI_DEVICE(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3903) {PCI_DEVICE(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3904) {PCI_DEVICE(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3905) {0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3906) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3907) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3908) MODULE_DEVICE_TABLE(pci, blogic_pci_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3910) module_init(blogic_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3911) module_exit(blogic_exit);