Home | History | Annotate | Download | only in adapters
      1     0    stevel /*
      2     0    stevel  * CDDL HEADER START
      3     0    stevel  *
      4     0    stevel  * The contents of this file are subject to the terms of the
      5  2840  carlsonj  * Common Development and Distribution License (the "License").
      6  2840  carlsonj  * You may not use this file except in compliance with the License.
      7     0    stevel  *
      8     0    stevel  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9     0    stevel  * or http://www.opensolaris.org/os/licensing.
     10     0    stevel  * See the License for the specific language governing permissions
     11     0    stevel  * and limitations under the License.
     12     0    stevel  *
     13     0    stevel  * When distributing Covered Code, include this CDDL HEADER in each
     14     0    stevel  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15     0    stevel  * If applicable, add the following below this CDDL HEADER, with the
     16     0    stevel  * fields enclosed by brackets "[]" replaced with your own identifying
     17     0    stevel  * information: Portions Copyright [yyyy] [name of copyright owner]
     18     0    stevel  *
     19     0    stevel  * CDDL HEADER END
     20     0    stevel  */
     21     0    stevel /*
     22  6640       cth  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     23     0    stevel  * Use is subject to license terms.
     24     0    stevel  */
     25     0    stevel 
     26     0    stevel 
     27     0    stevel /*
     28     0    stevel  * esp - Emulex SCSI Processor host adapter driver with FAS101/236,
     29     0    stevel  *	tagged and non-tagged queuing support
     30     0    stevel  */
     31     0    stevel #if defined(lint) && !defined(DEBUG)
     32     0    stevel #define	DEBUG	1
     33     0    stevel #define	ESP_CHECK
     34     0    stevel #endif
     35     0    stevel 
     36     0    stevel #include <sys/note.h>
     37     0    stevel 
     38     0    stevel #include <sys/modctl.h>
     39     0    stevel #include <sys/scsi/scsi.h>
     40     0    stevel 
     41     0    stevel /*
     42     0    stevel  * these are non-ddi compliant:
     43     0    stevel  */
     44     0    stevel #include <sys/varargs.h>
     45     0    stevel #include <sys/var.h>
     46     0    stevel #include <sys/proc.h>
     47     0    stevel #include <sys/thread.h>
     48     0    stevel #include <sys/utsname.h>
     49     0    stevel #include <sys/kstat.h>
     50     0    stevel #include <sys/vtrace.h>
     51     0    stevel #include <sys/kmem.h>
     52     0    stevel #include <sys/callb.h>
     53     0    stevel 
     54     0    stevel /*
     55     0    stevel  * private
     56     0    stevel  */
     57     0    stevel #include <sys/scsi/adapters/espvar.h>
     58     0    stevel #include <sys/scsi/adapters/espcmd.h>
     59     0    stevel #include <sys/scsi/impl/scsi_reset_notify.h>
     60     0    stevel 
     61     0    stevel /*
     62     0    stevel  * External references
     63     0    stevel  */
     64     0    stevel extern uchar_t	scsi_cdb_size[];
     65     0    stevel 
     66     0    stevel /*
     67     0    stevel  * tunables
     68     0    stevel  */
     69     0    stevel static int esp_burst_sizes_limit = 0xff; /* patch in case of hw problems */
     70     0    stevel static int esp_selection_timeout = 250; /* 250 milliseconds */
     71     0    stevel 
     72     0    stevel #ifdef ESP_KSTATS
     73     0    stevel static int esp_do_kstats = 1;
     74     0    stevel static int esp_do_bus_kstats = 1;
     75     0    stevel #endif
     76     0    stevel 
     77     0    stevel #ifdef	ESPDEBUG
     78     0    stevel static int espdebug = 0;
     79     0    stevel static int esp_no_sync_backoff = 0;
     80     0    stevel static void esp_stat_int_print(struct esp *esp);
     81     0    stevel static int esp_test_stop;
     82     0    stevel #endif	/* ESPDEBUG */
     83     0    stevel 
     84     0    stevel /*
     85     0    stevel  * Local static data
     86     0    stevel  * the global mutex protects some of these esp driver variables
     87     0    stevel  */
     88     0    stevel static kmutex_t esp_global_mutex;
     89     0    stevel static int esp_watchdog_running = 0;
     90     0    stevel static int esp_scsi_watchdog_tick;	/* in sec */
     91     0    stevel static clock_t esp_tick;		/* esp_watch() interval in Hz */
     92     0    stevel static timeout_id_t esp_reset_watch;
     93     0    stevel static timeout_id_t esp_timeout_id = 0;
     94     0    stevel static int esp_timeout_initted = 0;
     95     0    stevel static int esp_n_esps = 0;
     96     0    stevel static void *esp_state;
     97     0    stevel static kmutex_t esp_log_mutex;
     98     0    stevel static char esp_log_buf[256];
     99     0    stevel 
    100     0    stevel /*
    101     0    stevel  * readers/writer lock to protect the integrity of the softc structure
    102     0    stevel  * linked list while being traversed (or updated).
    103     0    stevel  */
    104     0    stevel static krwlock_t esp_global_rwlock;
    105     0    stevel static struct esp *esp_softc = (struct esp *)0;
    106     0    stevel static struct esp *esp_tail;
    107     0    stevel 
    108     0    stevel /*
    109     0    stevel  * variables & prototypes for torture testing
    110     0    stevel  */
    111     0    stevel #ifdef ESP_TEST_RQSENSE
    112     0    stevel static int esp_test_rqsense;
    113     0    stevel #endif /* ESP_TEST_RQSENSE */
    114     0    stevel 
    115     0    stevel #ifdef	ESP_TEST_PARITY
    116     0    stevel static int esp_ptest_emsgin;
    117     0    stevel static int esp_ptest_msgin;
    118     0    stevel static int esp_ptest_msg = -1;
    119     0    stevel static int esp_ptest_status;
    120     0    stevel static int esp_ptest_data_in;
    121     0    stevel #endif	/* ESP_TEST_PARITY */
    122     0    stevel 
    123     0    stevel #ifdef ESP_TEST_ABORT
    124     0    stevel static int esp_atest;
    125     0    stevel static int esp_atest_disc;
    126     0    stevel static int esp_atest_reconn;
    127     0    stevel static void esp_test_abort(struct esp *esp, int slot);
    128     0    stevel #endif /* ESP_TEST_ABORT */
    129     0    stevel 
    130     0    stevel #ifdef ESP_TEST_RESET
    131     0    stevel static int esp_rtest;
    132     0    stevel static int esp_rtest_type;
    133     0    stevel static void esp_test_reset(struct esp *esp, int slot);
    134     0    stevel #endif /* ESP_TEST_RESET */
    135     0    stevel 
    136     0    stevel #ifdef ESP_TEST_TIMEOUT
    137     0    stevel static int esp_force_timeout;
    138     0    stevel #endif /* ESP_TEST_TIMEOUT */
    139     0    stevel 
    140     0    stevel #ifdef ESP_TEST_BUS_RESET
    141     0    stevel static int esp_btest;
    142     0    stevel #endif /* ESP_TEST_BUS_RESET */
    143     0    stevel 
    144     0    stevel #ifdef ESP_TEST_UNTAGGED
    145     0    stevel static int esp_test_untagged;
    146     0    stevel static int esp_enable_untagged;
    147     0    stevel static int esp_test_stop;
    148     0    stevel #endif /* ESP_TEST_UNTAGGED */
    149     0    stevel #ifdef ESP_PERF
    150     0    stevel _NOTE(SCHEME_PROTECTS_DATA("Stable Data", esp_request_count))
    151     0    stevel _NOTE(SCHEME_PROTECTS_DATA("Stable Data", esp_sample_time))
    152     0    stevel _NOTE(SCHEME_PROTECTS_DATA("Stable Data", esp_intr_count))
    153     0    stevel _NOTE(SCHEME_PROTECTS_DATA("Stable Data", esp_ncmds))
    154     0    stevel _NOTE(SCHEME_PROTECTS_DATA("Stable Data", esp_ndisc))
    155     0    stevel _NOTE(SCHEME_PROTECTS_DATA("Stable Data", esp_ncmds_per_esp))
    156     0    stevel 
    157     0    stevel /*
    158     0    stevel  * these should really be protected but it is not really important
    159     0    stevel  * to be very accurate
    160     0    stevel  */
    161     0    stevel static int esp_request_count;
    162     0    stevel static int esp_sample_time = 0;
    163     0    stevel static int esp_intr_count;
    164     0    stevel static int esp_ncmds;
    165     0    stevel static int esp_ndisc;
    166     0    stevel #define	MAX_ESPS	80	/* should be enough */
    167     0    stevel static int esp_ncmds_per_esp[MAX_ESPS];
    168     0    stevel #endif
    169     0    stevel 
    170     0    stevel _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", \
    171     0    stevel 	scsi_pkt esp_cmd buf scsi_cdb scsi_status))
    172     0    stevel _NOTE(SCHEME_PROTECTS_DATA("stable data", scsi_address scsi_device))
    173     0    stevel _NOTE(SCHEME_PROTECTS_DATA("No Mutex Needed", esp_watchdog_running))
    174     0    stevel _NOTE(DATA_READABLE_WITHOUT_LOCK(esp_scsi_watchdog_tick))
    175     0    stevel _NOTE(DATA_READABLE_WITHOUT_LOCK(espdebug))
    176     0    stevel _NOTE(DATA_READABLE_WITHOUT_LOCK(dmaga))
    177     0    stevel 
    178     0    stevel /*
    179     0    stevel  * function prototypes
    180     0    stevel  *
    181     0    stevel  * scsa functions are exported by means of the transport table
    182     0    stevel  */
    183     0    stevel static int esp_scsi_tgt_probe(struct scsi_device *sd,
    184     0    stevel     int (*waitfunc)(void));
    185     0    stevel static int esp_scsi_tgt_init(dev_info_t *, dev_info_t *,
    186     0    stevel     scsi_hba_tran_t *, struct scsi_device *);
    187     0    stevel static int esp_start(struct scsi_address *ap, struct scsi_pkt *pkt);
    188     0    stevel static int esp_abort(struct scsi_address *ap, struct scsi_pkt *pkt);
    189     0    stevel static int esp_reset(struct scsi_address *ap, int level);
    190     0    stevel static int esp_commoncap(struct scsi_address *ap, char *cap, int val,
    191     0    stevel     int tgtonly, int doset);
    192     0    stevel static int esp_getcap(struct scsi_address *ap, char *cap, int whom);
    193     0    stevel static int esp_setcap(struct scsi_address *ap, char *cap, int value, int whom);
    194     0    stevel static struct scsi_pkt *esp_scsi_init_pkt(struct scsi_address *ap,
    195     0    stevel     struct scsi_pkt *pkt, struct buf *bp, int cmdlen, int statuslen,
    196     0    stevel     int tgtlen, int flags, int (*callback)(), caddr_t arg);
    197     0    stevel static void esp_scsi_destroy_pkt(struct scsi_address *ap, struct scsi_pkt *pkt);
    198     0    stevel static void esp_scsi_dmafree(struct scsi_address *ap,
    199     0    stevel     struct scsi_pkt *pkt);
    200     0    stevel static void esp_scsi_sync_pkt(struct scsi_address *ap,
    201     0    stevel     struct scsi_pkt *pkt);
    202     0    stevel 
    203     0    stevel /*
    204     0    stevel  * internal functions
    205     0    stevel  */
    206     0    stevel static int esp_ustart(struct esp *esp, short start_slot, short flag);
    207     0    stevel static int esp_startcmd(struct esp *esp, struct esp_cmd *sp);
    208     0    stevel static int esp_finish(struct esp *esp);
    209     0    stevel static void esp_handle_qfull(struct esp *esp, struct esp_cmd *sp, int slot);
    210     0    stevel static void esp_restart_cmd(void *);
    211     0    stevel static int esp_dopoll(struct esp *esp, int timeout);
    212     0    stevel static uint_t esp_intr(caddr_t arg);
    213     0    stevel static void espsvc(struct esp *esp);
    214     0    stevel static int esp_phasemanage(struct esp *esp);
    215     0    stevel static int esp_handle_unknown(struct esp *esp);
    216     0    stevel static int esp_handle_cmd_start(struct esp *esp);
    217     0    stevel static int esp_handle_cmd_done(struct esp *esp);
    218     0    stevel static int esp_handle_msg_out(struct esp *esp);
    219     0    stevel static int esp_handle_msg_out_done(struct esp *esp);
    220     0    stevel static int esp_handle_clearing(struct esp *esp);
    221     0    stevel static int esp_handle_data(struct esp *esp);
    222     0    stevel static int esp_handle_data_done(struct esp *esp);
    223     0    stevel static int esp_handle_c_cmplt(struct esp *esp);
    224     0    stevel static int esp_handle_msg_in(struct esp *esp);
    225     0    stevel static int esp_handle_more_msgin(struct esp *esp);
    226     0    stevel static int esp_handle_msg_in_done(struct esp *esp);
    227     0    stevel static int esp_onebyte_msg(struct esp *esp);
    228     0    stevel static int esp_twobyte_msg(struct esp *esp);
    229     0    stevel static int esp_multibyte_msg(struct esp *esp);
    230     0    stevel static int esp_finish_select(struct esp *esp);
    231     0    stevel static int esp_reconnect(struct esp *esp);
    232     0    stevel static int esp_istart(struct esp *esp);
    233     0    stevel static void esp_runpoll(struct esp *esp, short slot, struct esp_cmd *sp);
    234     0    stevel static int esp_reset_bus(struct esp *esp);
    235     0    stevel static int esp_reset_recovery(struct esp *esp);
    236     0    stevel static int esp_handle_selection(struct esp *esp);
    237     0    stevel static void esp_makeproxy_cmd(struct esp_cmd *sp,
    238     0    stevel     struct scsi_address *ap, int nmsg, ...);
    239     0    stevel static void esp_make_sdtr(struct esp *esp, int msgout_offset,
    240     0    stevel     int period, int offset);
    241     0    stevel static void esp_watch(void *);
    242     0    stevel static void esp_watchsubr(struct esp *esp);
    243     0    stevel static void esp_cmd_timeout(struct esp *esp, struct esp_cmd *sp, int slot);
    244     0    stevel static int esp_abort_curcmd(struct esp *esp);
    245     0    stevel static int esp_abort_cmd(struct esp *esp, struct esp_cmd *sp, int slot);
    246     0    stevel static int esp_abort_allcmds(struct esp *esp);
    247     0    stevel static void esp_internal_reset(struct esp *esp, int reset_action);
    248     0    stevel static void esp_sync_backoff(struct esp *esp, struct esp_cmd *sp, int slot);
    249     0    stevel static void esp_hw_reset(struct esp *esp, int action);
    250     0    stevel /*PRINTFLIKE3*/
    251     0    stevel static void esplog(struct esp *esp, int level, const char *fmt, ...)
    252     0    stevel 	__KPRINTFLIKE(3);
    253     0    stevel /*PRINTFLIKE2*/
    254     0    stevel static void eprintf(struct esp *esp, const char *fmt, ...)
    255     0    stevel 	__KPRINTFLIKE(2);
    256     0    stevel static void esp_printstate(struct esp *esp, char *msg);
    257     0    stevel static void esp_dump_cmd(struct esp_cmd *sp);
    258     0    stevel static void esp_dump_state(struct esp *esp);
    259     0    stevel static char *esp_state_name(ushort_t state);
    260     0    stevel static void esp_update_props(struct esp *esp, int tgt);
    261     0    stevel static int _esp_start(struct esp *esp, struct esp_cmd *sp, int flag);
    262     0    stevel static int _esp_abort(struct scsi_address *ap, struct scsi_pkt *pkt);
    263     0    stevel static int _esp_reset(struct scsi_address *ap, int level);
    264     0    stevel static int esp_alloc_tag(struct esp *esp, struct esp_cmd *sp);
    265     0    stevel static int esp_remove_readyQ(struct esp *esp, struct esp_cmd *sp, int slot);
    266     0    stevel static void esp_flush_readyQ(struct esp *esp, int slot);
    267     0    stevel static void esp_flush_tagQ(struct esp *esp, int slot);
    268     0    stevel static void esp_flush_cmd(struct esp *esp, struct esp_cmd *sp,
    269     0    stevel     uchar_t reason, uint_t stat);
    270     0    stevel static int esp_abort_connected_cmd(struct esp *esp, struct esp_cmd *sp,
    271     0    stevel     uchar_t msg);
    272     0    stevel static int esp_abort_disconnected_cmd(struct esp *esp, struct scsi_address *ap,
    273     0    stevel     struct esp_cmd *sp, uchar_t msg, int slot);
    274     0    stevel static void esp_mark_packets(struct esp *esp, int slot, uchar_t reason,
    275     0    stevel     uint_t stat);
    276     0    stevel static int esp_reset_connected_cmd(struct esp *esp, struct scsi_address *ap,
    277     0    stevel     int slot);
    278     0    stevel static int esp_reset_disconnected_cmd(struct esp *esp, struct scsi_address *ap,
    279     0    stevel     int slot);
    280     0    stevel static int esp_create_arq_pkt(struct esp *esp, struct scsi_address *ap,
    281     0    stevel     int size);
    282     0    stevel static int esp_start_arq_pkt(struct esp *esp, struct esp_cmd *sp);
    283     0    stevel static void esp_complete_arq_pkt(struct esp *esp, struct esp_cmd *sp,
    284     0    stevel     int slot);
    285     0    stevel static void esp_determine_chip_type(struct esp *esp);
    286     0    stevel static void esp_create_callback_thread(struct esp *esp);
    287     0    stevel static void esp_destroy_callback_thread(struct esp *);
    288     0    stevel static void esp_callback(struct esp *esp);
    289     0    stevel static void esp_call_pkt_comp(struct esp *esp, struct esp_cmd *sp);
    290     0    stevel static int esp_set_new_window(struct esp *esp, struct esp_cmd *sp);
    291     0    stevel static int esp_restore_pointers(struct esp *esp, struct esp_cmd *sp);
    292     0    stevel static int esp_next_window(struct esp *esp, struct esp_cmd *sp);
    293     0    stevel static void esp_start_watch_reset_delay(struct esp *);
    294     0    stevel static void esp_watch_reset_delay(void *arg);
    295     0    stevel static int esp_watch_reset_delay_subr(struct esp *esp);
    296     0    stevel void esp_wakeup_callback_thread(struct callback_info *cb_info);
    297     0    stevel static void esp_update_TQ_props(struct esp *esp, int tgt, int value);
    298     0    stevel static int esp_check_dma_error(struct esp *esp);
    299     0    stevel static void esp_reset_cleanup(struct esp *esp, int slot);
    300     0    stevel static int esp_scsi_reset_notify(struct scsi_address *ap, int flag,
    301     0    stevel     void (*callback)(caddr_t), caddr_t arg);
    302     0    stevel static void esp_set_throttles(struct esp *esp, int slot,
    303     0    stevel     int n, int what);
    304     0    stevel static void esp_set_all_lun_throttles(struct esp *esp, int slot, int what);
    305     0    stevel static void esp_save_throttles(struct esp *esp, int slot, int n,
    306     0    stevel     short *throttle);
    307     0    stevel static void esp_restore_throttles(struct esp *esp, int slot, int n,
    308     0    stevel     short *throttle);
    309     0    stevel static int esp_do_proxy_cmd(struct esp *esp, struct esp_cmd *sp,
    310     0    stevel     struct scsi_address *ap, int slot, char *what);
    311     0    stevel static void esp_remove_tagged_cmd(struct esp *esp, struct esp_cmd *sp,
    312     0    stevel     int slot, int timeout);
    313     0    stevel static void esp_decrement_ncmds(struct esp *esp, struct esp_cmd *sp);
    314     0    stevel static int esp_pkt_alloc_extern(struct esp *esp, struct esp_cmd *sp,
    315     0    stevel     int cmdlen, int tgtlen, int statuslen, int kf);
    316     0    stevel static void esp_pkt_destroy_extern(struct esp *esp, struct esp_cmd *sp);
    317     0    stevel static int esp_kmem_cache_constructor(void *buf, void *cdrarg, int kmflags);
    318     0    stevel static void esp_kmem_cache_destructor(void *buf, void *cdrarg);
    319     0    stevel 
    320     0    stevel static void esp_flush_fifo(struct esp *esp);
    321     0    stevel static void esp_empty_startQ(struct esp *esp);
    322     0    stevel 
    323     0    stevel #ifdef ESP_CHECK
    324     0    stevel static void esp_check_in_transport(struct esp *esp, struct esp_cmd *sp);
    325     0    stevel #else
    326     0    stevel #define	esp_check_in_transport(esp, sp)
    327     0    stevel #endif
    328     0    stevel 
    329     0    stevel /*
    330     0    stevel  * esp DMA attr for all supported dma engines:
    331     0    stevel  */
    332     0    stevel static ddi_dma_attr_t dma1_espattr = {
    333     0    stevel 	DMA_ATTR_V0, (unsigned long long)0,
    334     0    stevel 	(unsigned long long)0xffffffff, (unsigned long long)((1<<24)-1),
    335     0    stevel 	1, DEFAULT_BURSTSIZE, 1,
    336     0    stevel 	(unsigned long long)0xffffffff, (unsigned long long)((1<<24)-1),
    337     0    stevel 	1, 512, 0
    338     0    stevel };
    339     0    stevel 
    340     0    stevel /*
    341     0    stevel  * ESC1 esp dma attr
    342     0    stevel  */
    343     0    stevel static ddi_dma_attr_t esc1_espattr = {
    344     0    stevel 	DMA_ATTR_V0, (unsigned long long)0,
    345     0    stevel 	(unsigned long long)0xffffffff, (unsigned long long)((1<<24)-1),
    346     0    stevel 	1, DEFAULT_BURSTSIZE | BURST32, 4,
    347     0    stevel 	(unsigned long long)0xffffffff, (unsigned long long)((1<<24)-1),
    348     0    stevel 	1, 512, 0
    349     0    stevel };
    350     0    stevel 
    351     0    stevel /*
    352     0    stevel  * DMA2 esp dma attr
    353     0    stevel  */
    354     0    stevel static ddi_dma_attr_t dma2_espattr = {
    355     0    stevel 	DMA_ATTR_V0, (unsigned long long)0,
    356     0    stevel 	(unsigned long long)0xffffffff, (unsigned long long)((1<<24)-1),
    357     0    stevel 	1, DEFAULT_BURSTSIZE, 1,
    358     0    stevel 	(unsigned long long)0xffffffff, (unsigned long long)((1<<24)-1),
    359     0    stevel 	1, 512, 0
    360     0    stevel };
    361     0    stevel 
    362     0    stevel /*
    363     0    stevel  * DMA3 esp dma attr
    364     0    stevel  */
    365     0    stevel static ddi_dma_attr_t dma3_espattr = {
    366     0    stevel 	DMA_ATTR_V0, (unsigned long long)0x0,
    367     0    stevel 	(unsigned long long)0xffffffff, (unsigned long long)((1<<24)-1),
    368     0    stevel 	1, DEFAULT_BURSTSIZE | BURST32, 1,
    369     0    stevel 	(unsigned long long)0xffffffff, (unsigned long long)((1<<24)-1),
    370     0    stevel 	1, 512, 0
    371     0    stevel };
    372     0    stevel 
    373     0    stevel /*
    374     0    stevel  * autoconfiguration routines.
    375     0    stevel  */
    376     0    stevel static int esp_attach(dev_info_t *dev, ddi_attach_cmd_t cmd);
    377     0    stevel static int esp_detach(dev_info_t *dev, ddi_detach_cmd_t cmd);
    378     0    stevel static int esp_dr_detach(dev_info_t *dev);
    379     0    stevel 
    380     0    stevel static struct dev_ops esp_ops = {
    381     0    stevel 	DEVO_REV,		/* devo_rev, */
    382     0    stevel 	0,			/* refcnt  */
    383     0    stevel 	ddi_no_info,		/* info */
    384     0    stevel 	nulldev,		/* identify */
    385     0    stevel 	nulldev,		/* probe */
    386     0    stevel 	esp_attach,		/* attach */
    387     0    stevel 	esp_detach,		/* detach */
    388     0    stevel 	nodev,			/* reset */
    389     0    stevel 	NULL,			/* cb ops */
    390     0    stevel 	NULL,			/* bus operations */
    391  7656    Sherry 	ddi_power,		/* power */
    392  7656    Sherry 	ddi_quiesce_not_supported,	/* devo_quiesce */
    393     0    stevel };
    394     0    stevel 
    395     0    stevel char _depends_on[] = "misc/scsi";
    396     0    stevel 
    397     0    stevel static struct modldrv modldrv = {
    398     0    stevel 	&mod_driverops, /* Type of module. This one is a driver */
    399  7656    Sherry 	"ESP SCSI HBA Driver", /* Name of the module. */
    400     0    stevel 	&esp_ops,	/* driver ops */
    401     0    stevel };
    402     0    stevel 
    403     0    stevel static struct modlinkage modlinkage = {
    404     0    stevel 	MODREV_1, (void *)&modldrv, NULL
    405     0    stevel };
    406     0    stevel 
    407     0    stevel int
    408     0    stevel _init(void)
    409     0    stevel {
    410     0    stevel 	int	i;
    411     0    stevel 
    412     0    stevel 	/* CONSTCOND */
    413     0    stevel 	ASSERT(NO_COMPETING_THREADS);
    414     0    stevel 
    415     0    stevel 	i = ddi_soft_state_init(&esp_state, sizeof (struct esp),
    416     0    stevel 	    ESP_INIT_SOFT_STATE);
    417     0    stevel 	if (i != 0)
    418     0    stevel 		return (i);
    419     0    stevel 	if ((i = scsi_hba_init(&modlinkage)) != 0) {
    420     0    stevel 		ddi_soft_state_fini(&esp_state);
    421     0    stevel 		return (i);
    422     0    stevel 	}
    423     0    stevel 
    424     0    stevel 	mutex_init(&esp_global_mutex, NULL, MUTEX_DRIVER, NULL);
    425     0    stevel 	rw_init(&esp_global_rwlock, NULL, RW_DRIVER, NULL);
    426     0    stevel 
    427     0    stevel 	mutex_init(&esp_log_mutex, NULL, MUTEX_DRIVER, NULL);
    428     0    stevel 
    429     0    stevel 	if ((i = mod_install(&modlinkage)) != 0) {
    430     0    stevel 		mutex_destroy(&esp_log_mutex);
    431     0    stevel 		rw_destroy(&esp_global_rwlock);
    432     0    stevel 		mutex_destroy(&esp_global_mutex);
    433     0    stevel 		ddi_soft_state_fini(&esp_state);
    434     0    stevel 		scsi_hba_fini(&modlinkage);
    435     0    stevel 		return (i);
    436     0    stevel 	}
    437     0    stevel 
    438     0    stevel 	return (i);
    439     0    stevel }
    440     0    stevel 
    441     0    stevel int
    442     0    stevel _fini(void)
    443     0    stevel {
    444     0    stevel 	int	i;
    445     0    stevel 
    446     0    stevel 	/* CONSTCOND */
    447     0    stevel 	ASSERT(NO_COMPETING_THREADS);
    448     0    stevel 	if ((i = mod_remove(&modlinkage)) == 0) {
    449     0    stevel 		mutex_destroy(&esp_log_mutex);
    450     0    stevel 		scsi_hba_fini(&modlinkage);
    451     0    stevel 		rw_destroy(&esp_global_rwlock);
    452     0    stevel 		mutex_destroy(&esp_global_mutex);
    453     0    stevel 		ddi_soft_state_fini(&esp_state);
    454     0    stevel 	}
    455     0    stevel 	return (i);
    456     0    stevel }
    457     0    stevel 
    458     0    stevel int
    459     0    stevel _info(struct modinfo *modinfop)
    460     0    stevel {
    461     0    stevel 	return (mod_info(&modlinkage, modinfop));
    462     0    stevel }
    463     0    stevel 
    464     0    stevel static int
    465     0    stevel esp_scsi_tgt_probe(struct scsi_device *sd,
    466     0    stevel     int (*waitfunc)(void))
    467     0    stevel {
    468     0    stevel 	dev_info_t *dip = ddi_get_parent(sd->sd_dev);
    469     0    stevel 	int rval = SCSIPROBE_FAILURE;
    470     0    stevel 	scsi_hba_tran_t *tran;
    471     0    stevel 	struct esp *esp;
    472     0    stevel 	int tgt = sd->sd_address.a_target;
    473     0    stevel 
    474     0    stevel 	tran = ddi_get_driver_private(dip);
    475     0    stevel 	ASSERT(tran != NULL);
    476     0    stevel 	esp = TRAN2ESP(tran);
    477     0    stevel 
    478     0    stevel 	/*
    479     0    stevel 	 * force renegotiation since Inquiry cmds do not cause
    480     0    stevel 	 * check conditions
    481     0    stevel 	 */
    482     0    stevel 	mutex_enter(ESP_MUTEX);
    483     0    stevel 	esp->e_sync_known &= ~(1 << tgt);
    484     0    stevel 	mutex_exit(ESP_MUTEX);
    485     0    stevel 
    486     0    stevel 	rval = scsi_hba_probe(sd, waitfunc);
    487     0    stevel 
    488     0    stevel 	/*
    489     0    stevel 	 * the scsi-options precedence is:
    490     0    stevel 	 *	target-scsi-options		highest
    491     0    stevel 	 *	device-type-scsi-options
    492     0    stevel 	 *	per bus scsi-options
    493     0    stevel 	 *	global scsi-options		lowest
    494     0    stevel 	 */
    495     0    stevel 	mutex_enter(ESP_MUTEX);
    496     0    stevel 	if ((rval == SCSIPROBE_EXISTS) &&
    497     0    stevel 	    ((esp->e_target_scsi_options_defined & (1 << tgt)) == 0)) {
    498     0    stevel 		int options;
    499     0    stevel 
    500     0    stevel 		options = scsi_get_device_type_scsi_options(dip, sd, -1);
    501     0    stevel 		if (options != -1) {
    502     0    stevel 			esp->e_target_scsi_options[tgt] = options;
    503     0    stevel 			esplog(esp, CE_NOTE,
    504  7656    Sherry 			    "?target%x-scsi-options = 0x%x\n", tgt,
    505  7656    Sherry 			    esp->e_target_scsi_options[tgt]);
    506     0    stevel 
    507     0    stevel 			if (options & SCSI_OPTIONS_FAST) {
    508     0    stevel 				esp->e_default_period[tgt] = (uchar_t)
    509     0    stevel 				    MIN_SYNC_PERIOD(esp);
    510     0    stevel 			} else {
    511     0    stevel 				esp->e_default_period[tgt] = (uchar_t)
    512     0    stevel 				    CONVERT_PERIOD(DEFAULT_SYNC_PERIOD);
    513     0    stevel 			}
    514     0    stevel 			esp->e_neg_period[tgt] = 0;
    515     0    stevel 			esp->e_sync_known &= ~(1 << tgt);
    516     0    stevel 		}
    517     0    stevel 	}
    518     0    stevel 	mutex_exit(ESP_MUTEX);
    519     0    stevel 
    520     0    stevel 	IPRINTF2("target%x-scsi-options = 0x%x\n",
    521  7656    Sherry 	    tgt, esp->e_target_scsi_options[tgt]);
    522     0    stevel 
    523     0    stevel 	return (rval);
    524     0    stevel }
    525     0    stevel 
    526     0    stevel 
    527     0    stevel /*ARGSUSED*/
    528     0    stevel static int
    529     0    stevel esp_scsi_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip,
    530     0    stevel     scsi_hba_tran_t *hba_tran, struct scsi_device *sd)
    531     0    stevel {
    532     0    stevel 	return (((sd->sd_address.a_target < NTARGETS) &&
    533  7656    Sherry 	    (sd->sd_address.a_lun < NLUNS_PER_TARGET)) ?
    534  7656    Sherry 	    DDI_SUCCESS : DDI_FAILURE);
    535     0    stevel }
    536     0    stevel 
    537     0    stevel static char *prop_cfreq = "clock-frequency";
    538     0    stevel 
    539     0    stevel /*ARGSUSED*/
    540     0    stevel static int
    541     0    stevel esp_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
    542     0    stevel {
    543     0    stevel 	struct esp *esp;
    544     0    stevel 	volatile struct dmaga *dmar = NULL;
    545     0    stevel 	volatile struct espreg *ep;
    546     0    stevel 	ddi_dma_attr_t	*esp_dma_attr;
    547     0    stevel 	scsi_hba_tran_t *tran = NULL;
    548     0    stevel 	ddi_device_acc_attr_t dev_attr;
    549     0    stevel 
    550     0    stevel 	int		instance, i;
    551     0    stevel 	char		buf[64];
    552     0    stevel 	int		mutex_initialized = 0;
    553     0    stevel 	int		add_intr_done = 0;
    554     0    stevel 	int		bound_handle = 0;
    555     0    stevel 	uint_t		count;
    556     0    stevel 	size_t		rlen;
    557     0    stevel 	char		*prop_template = "target%d-scsi-options";
    558     0    stevel 	char		prop_str[32];
    559     0    stevel 
    560     0    stevel 	switch (cmd) {
    561     0    stevel 	case DDI_ATTACH:
    562     0    stevel 		break;
    563     0    stevel 
    564     0    stevel 	case DDI_RESUME:
    565     0    stevel 	case DDI_PM_RESUME:
    566     0    stevel 		if ((tran = ddi_get_driver_private(dip)) == NULL)
    567     0    stevel 			return (DDI_FAILURE);
    568     0    stevel 
    569     0    stevel 		esp = TRAN2ESP(tran);
    570     0    stevel 		if (!esp) {
    571     0    stevel 			return (DDI_FAILURE);
    572     0    stevel 		}
    573     0    stevel 		mutex_enter(ESP_MUTEX);
    574     0    stevel 
    575     0    stevel 		/*
    576     0    stevel 		 * Reset hardware and softc to "no outstanding commands"
    577     0    stevel 		 * Note that a check condition can result on first command
    578     0    stevel 		 * to a target.
    579     0    stevel 		 */
    580     0    stevel 		esp_internal_reset(esp,
    581     0    stevel 		    ESP_RESET_SOFTC|ESP_RESET_ESP|ESP_RESET_DMA);
    582     0    stevel 		(void) esp_reset_bus(esp);
    583     0    stevel 
    584     0    stevel 		/*
    585     0    stevel 		 * esp_watchdog_running was reset at checkpoint time,
    586     0    stevel 		 * enable it at resume time
    587     0    stevel 		 */
    588     0    stevel 		esp_watchdog_running = 1;
    589     0    stevel 
    590     0    stevel 		esp->e_suspended = 0;
    591     0    stevel 
    592     0    stevel 		mutex_enter(&esp_global_mutex);
    593     0    stevel 		if (esp_timeout_id == 0) {
    594     0    stevel 			esp_timeout_id = timeout(esp_watch, NULL, esp_tick);
    595     0    stevel 			esp_timeout_initted = 1;
    596     0    stevel 		}
    597     0    stevel 		mutex_exit(&esp_global_mutex);
    598     0    stevel 
    599     0    stevel 		/* make sure that things get started */
    600     0    stevel 		(void) esp_istart(esp);
    601     0    stevel 		ESP_CHECK_STARTQ_AND_ESP_MUTEX_EXIT(esp);
    602     0    stevel 		return (DDI_SUCCESS);
    603     0    stevel 
    604     0    stevel 	default:
    605     0    stevel 		return (DDI_FAILURE);
    606     0    stevel 	}
    607     0    stevel 
    608     0    stevel 	instance = ddi_get_instance(dip);
    609     0    stevel 
    610     0    stevel 	/*
    611     0    stevel 	 * Since we know that some instantiations of this device can
    612     0    stevel 	 * be plugged into slave-only SBus slots, check to see whether
    613     0    stevel 	 * this is one such.
    614     0    stevel 	 */
    615     0    stevel 	if (ddi_slaveonly(dip) == DDI_SUCCESS) {
    616     0    stevel 		cmn_err(CE_WARN,
    617     0    stevel 		    "esp%d: device in slave-only slot", instance);
    618     0    stevel 		return (DDI_FAILURE);
    619     0    stevel 	}
    620     0    stevel 
    621     0    stevel 	if (ddi_intr_hilevel(dip, 0)) {
    622     0    stevel 		/*
    623     0    stevel 		 * Interrupt number '0' is a high-level interrupt.
    624     0    stevel 		 * At this point you either add a special interrupt
    625     0    stevel 		 * handler that triggers a soft interrupt at a lower level,
    626     0    stevel 		 * or - more simply and appropriately here - you just
    627     0    stevel 		 * fail the attach.
    628     0    stevel 		 */
    629     0    stevel 		cmn_err(CE_WARN,
    630     0    stevel 		    "esp%d: Device is using a hilevel intr", instance);
    631     0    stevel 		return (DDI_FAILURE);
    632     0    stevel 	}
    633     0    stevel 
    634     0    stevel 	/*
    635     0    stevel 	 * Allocate softc information.
    636     0    stevel 	 */
    637     0    stevel 	if (ddi_soft_state_zalloc(esp_state, instance) != DDI_SUCCESS) {
    638     0    stevel 		cmn_err(CE_WARN,
    639     0    stevel 		    "esp%d: cannot allocate soft state", instance);
    640     0    stevel 		return (DDI_FAILURE);
    641     0    stevel 	}
    642     0    stevel 
    643     0    stevel 	esp = (struct esp *)ddi_get_soft_state(esp_state, instance);
    644     0    stevel 
    645     0    stevel 	if (esp == NULL) {
    646     0    stevel 		return (DDI_FAILURE);
    647     0    stevel 	}
    648     0    stevel 
    649     0    stevel 	/*
    650     0    stevel 	 * map in device registers
    651     0    stevel 	 */
    652     0    stevel 	dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
    653     0    stevel 	dev_attr.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC;
    654     0    stevel 	dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
    655     0    stevel 
    656     0    stevel 	if (ddi_regs_map_setup(dip, (uint_t)0, (caddr_t *)&ep,
    657     0    stevel 	    (off_t)0, (off_t)sizeof (struct espreg),
    658     0    stevel 	    &dev_attr, &esp->e_regs_acc_handle) != DDI_SUCCESS) {
    659     0    stevel 		cmn_err(CE_WARN, "esp%d: unable to map registers", instance);
    660     0    stevel 		goto exit;
    661     0    stevel 	}
    662     0    stevel 
    663     0    stevel 	dmar = dma_alloc(dip);
    664     0    stevel 	if (dmar == NULL) {
    665     0    stevel 		cmn_err(CE_WARN,
    666     0    stevel 		    "esp%d: cannot find dma controller", instance);
    667     0    stevel 		goto unmap;
    668     0    stevel 	}
    669     0    stevel 
    670     0    stevel 	/*
    671     0    stevel 	 * Initialize state of DMA gate array.
    672     0    stevel 	 * Must clear DMAGA_RESET on the ESC before accessing the esp.
    673     0    stevel 	 */
    674     0    stevel 	switch (DMAGA_REV(dmar)) {
    675     0    stevel 	case DMA_REV2:
    676     0    stevel 		esp_dma_attr = &dma2_espattr;
    677     0    stevel 		break;
    678     0    stevel 	case ESC1_REV1:
    679     0    stevel 		dmar->dmaga_csr &= ~DMAGA_RESET;
    680     0    stevel 		esp_dma_attr = &esc1_espattr;
    681     0    stevel 		break;
    682     0    stevel 	case DMA_REV3:
    683     0    stevel 		esp_dma_attr = &dma3_espattr;
    684     0    stevel 		break;
    685     0    stevel 	case DMA_REV1:
    686     0    stevel 	default:
    687     0    stevel 		esp_dma_attr = &dma1_espattr;
    688     0    stevel 		break;
    689     0    stevel 	}
    690     0    stevel 
    691     0    stevel 	dmar->dmaga_csr &= ~DMAGA_WRITE;
    692     0    stevel 
    693     0    stevel 	if (ddi_dma_alloc_handle(dip, esp_dma_attr,
    694     0    stevel 	    DDI_DMA_SLEEP, NULL, &esp->e_dmahandle) != DDI_SUCCESS) {
    695     0    stevel 		cmn_err(CE_WARN,
    696     0    stevel 		    "esp%d: cannot alloc dma handle", instance);
    697     0    stevel 		goto fail;
    698     0    stevel 	}
    699     0    stevel 
    700     0    stevel 	if (ddi_dma_mem_alloc(esp->e_dmahandle, (uint_t)FIFOSIZE,
    701     0    stevel 	    &dev_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP,
    702     0    stevel 	    NULL, (caddr_t *)&esp->e_cmdarea, &rlen,
    703     0    stevel 	    &esp->e_cmdarea_acc_handle) != DDI_SUCCESS) {
    704     0    stevel 		cmn_err(CE_WARN,
    705     0    stevel 		    "esp%d: cannot alloc cmd area", instance);
    706     0    stevel 		goto fail;
    707     0    stevel 	}
    708     0    stevel 	ASSERT(rlen >= FIFOSIZE);
    709     0    stevel 
    710     0    stevel 	if (ddi_dma_addr_bind_handle(esp->e_dmahandle,
    711     0    stevel 	    NULL, (caddr_t)esp->e_cmdarea,
    712     0    stevel 	    rlen, DDI_DMA_RDWR|DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL,
    713     0    stevel 	    &esp->e_dmacookie, &count) != DDI_DMA_MAPPED) {
    714     0    stevel 		cmn_err(CE_WARN,
    715     0    stevel 		    "esp%d: cannot bind cmdarea", instance);
    716     0    stevel 		goto fail;
    717     0    stevel 	}
    718     0    stevel 	bound_handle++;
    719     0    stevel 	ASSERT(count == 1);
    720     0    stevel 
    721     0    stevel 	/*
    722     0    stevel 	 * Allocate a transport structure
    723     0    stevel 	 */
    724     0    stevel 	tran = scsi_hba_tran_alloc(dip, SCSI_HBA_CANSLEEP);
    725     0    stevel 
    726  6640       cth 	/* Indicate that we are 'sizeof (scsi_*(9S))' clean. */
    727  6640       cth 	scsi_size_clean(dip);		/* SCSI_SIZE_CLEAN_VERIFY ok */
    728  6640       cth 
    729     0    stevel 	/*
    730     0    stevel 	 * the ESC has a rerun bug and the workaround is
    731     0    stevel 	 * to round up the ESC count; rather than
    732     0    stevel 	 * doing this on each xfer we do it once here
    733     0    stevel 	 * for the cmd area read xfers
    734     0    stevel 	 */
    735     0    stevel 	esp->e_dma_rev = DMAGA_REV(dmar);
    736     0    stevel 	if (esp->e_dma_rev == ESC1_REV1) {
    737     0    stevel 		uint32_t addr1 = esp->e_dmacookie.dmac_address;
    738     0    stevel 		uint32_t addr2 = roundup(addr1 + FIFOSIZE, ptob(1));
    739     0    stevel 		esp->e_esc_read_count = (uint32_t)(addr2 - addr1);
    740     0    stevel 	}
    741     0    stevel 
    742     0    stevel 	/*
    743     0    stevel 	 * By default we assume embedded devices and save time
    744     0    stevel 	 * checking for timeouts in esp_watch() by skipping the rest of luns
    745     0    stevel 	 * If we're talking to any non-embedded devices, we can't cheat
    746     0    stevel 	 * and skip over non-zero luns anymore in esp_watch().
    747     0    stevel 	 */
    748     0    stevel 	esp->e_dslot = NLUNS_PER_TARGET;
    749     0    stevel 
    750     0    stevel #ifdef	ESPDEBUG
    751     0    stevel 	/*
    752     0    stevel 	 * Initialize last state log.
    753     0    stevel 	 */
    754     0    stevel 	for (i = 0; i < NPHASE; i++) {
    755     0    stevel 		esp->e_phase[i].e_save_state = STATE_FREE;
    756     0    stevel 		esp->e_phase[i].e_save_stat = -1;
    757     0    stevel 		esp->e_phase[i].e_val1 = -1;
    758     0    stevel 		esp->e_phase[i].e_val2 = -1;
    759     0    stevel 	}
    760     0    stevel 	esp->e_phase_index = 0;
    761     0    stevel 	esp->e_xfer = 0;
    762     0    stevel #endif	/* ESPDEBUG */
    763     0    stevel 
    764     0    stevel 	/*
    765     0    stevel 	 * Initialize throttles.
    766     0    stevel 	 */
    767     0    stevel 	esp_set_throttles(esp, 0, N_SLOTS, CLEAR_THROTTLE);
    768     0    stevel 
    769     0    stevel 	/*
    770     0    stevel 	 * initialize transport structure
    771     0    stevel 	 */
    772     0    stevel 	esp->e_tran			= tran;
    773     0    stevel 	esp->e_dev			= dip;
    774     0    stevel 
    775     0    stevel 	tran->tran_hba_private		= esp;
    776     0    stevel 	tran->tran_tgt_private		= NULL;
    777     0    stevel 
    778     0    stevel 	tran->tran_tgt_init		= esp_scsi_tgt_init;
    779     0    stevel 	tran->tran_tgt_probe		= esp_scsi_tgt_probe;
    780     0    stevel 	tran->tran_tgt_free		= NULL;
    781     0    stevel 
    782     0    stevel 	tran->tran_start		= esp_start;
    783     0    stevel 	tran->tran_abort		= esp_abort;
    784     0    stevel 	tran->tran_reset		= esp_reset;
    785     0    stevel 	tran->tran_getcap		= esp_getcap;
    786     0    stevel 	tran->tran_setcap		= esp_setcap;
    787     0    stevel 	tran->tran_init_pkt		= esp_scsi_init_pkt;
    788     0    stevel 	tran->tran_destroy_pkt		= esp_scsi_destroy_pkt;
    789     0    stevel 	tran->tran_dmafree		= esp_scsi_dmafree;
    790     0    stevel 	tran->tran_sync_pkt		= esp_scsi_sync_pkt;
    791     0    stevel 	tran->tran_reset_notify		= esp_scsi_reset_notify;
    792     0    stevel 	tran->tran_get_bus_addr		= NULL;
    793     0    stevel 	tran->tran_get_name		= NULL;
    794     0    stevel 	tran->tran_add_eventcall	= NULL;
    795     0    stevel 	tran->tran_get_eventcookie	= NULL;
    796     0    stevel 	tran->tran_post_event		= NULL;
    797     0    stevel 	tran->tran_remove_eventcall	= NULL;
    798     0    stevel 
    799     0    stevel 	/* XXX need tran_quiesce and tran_unquiesce for hotplugging */
    800     0    stevel 	tran->tran_bus_reset		= NULL;
    801     0    stevel 	tran->tran_quiesce		= NULL;
    802     0    stevel 	tran->tran_unquiesce		= NULL;
    803     0    stevel 
    804     0    stevel 	esp->e_espconf = DEFAULT_HOSTID;
    805     0    stevel 	i = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, "initiator-id", -1);
    806     0    stevel 	if (i == -1) {
    807     0    stevel 		i = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0,
    808     0    stevel 		    "scsi-initiator-id", -1);
    809     0    stevel 	}
    810     0    stevel 	if (i != DEFAULT_HOSTID && i >= 0 && i < NTARGETS) {
    811     0    stevel 		esplog(esp, CE_NOTE, "initiator SCSI ID now %d\n", i);
    812     0    stevel 		esp->e_espconf = (uchar_t)i;
    813     0    stevel 	}
    814     0    stevel 
    815     0    stevel 	for (i = 0; i < NTARGETS; i++) {
    816     0    stevel 		esp->e_qfull_retries[i] = QFULL_RETRIES;
    817     0    stevel 		esp->e_qfull_retry_interval[i] =
    818  7656    Sherry 		    drv_usectohz(QFULL_RETRY_INTERVAL * 1000);
    819     0    stevel 	}
    820     0    stevel 
    821     0    stevel 	esp->e_reg = ep;
    822     0    stevel 	esp->e_dma = dmar;
    823     0    stevel 	esp->e_last_slot = esp->e_cur_slot = UNDEFINED;
    824     0    stevel 
    825     0    stevel 	IPRINTF1("DMA Rev: 0x%x\n", ESP_DMAGA_REV(esp));
    826     0    stevel 
    827     0    stevel 	esp->e_dma_attr = esp_dma_attr;
    828     0    stevel 	IPRINTF1("esp_dma_attr burstsize=%x\n",
    829     0    stevel 	    esp_dma_attr->dma_attr_burstsizes);
    830     0    stevel 
    831     0    stevel 	/*
    832     0    stevel 	 * Attach this instance of the hba
    833     0    stevel 	 */
    834     0    stevel 	if (scsi_hba_attach_setup(dip, esp->e_dma_attr, tran, 0) !=
    835     0    stevel 	    DDI_SUCCESS) {
    836     0    stevel 		cmn_err(CE_WARN, "esp: scsi_hba_attach failed\n");
    837     0    stevel 		goto fail;
    838     0    stevel 	}
    839     0    stevel 
    840     0    stevel 	/*
    841     0    stevel 	 * if scsi-options property exists, use it;
    842     0    stevel 	 * otherwise use the global variable
    843     0    stevel 	 */
    844     0    stevel 	esp->e_scsi_options = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0,
    845     0    stevel 	    "scsi-options", SCSI_OPTIONS_DR);
    846     0    stevel 
    847     0    stevel 	/* we don't support wide */
    848     0    stevel 	if (esp->e_scsi_options & SCSI_OPTIONS_WIDE) {
    849     0    stevel 		esp->e_scsi_options &= ~SCSI_OPTIONS_WIDE;
    850     0    stevel 		(void) ddi_prop_update_int(DDI_MAJOR_T_UNKNOWN, dip,
    851     0    stevel 		    "scsi-options", esp->e_scsi_options);
    852     0    stevel 	}
    853     0    stevel 
    854     0    stevel 	if ((esp->e_scsi_options & SCSI_OPTIONS_SYNC) == 0) {
    855     0    stevel 		esp->e_weak = 0xff;
    856     0    stevel 	}
    857     0    stevel 
    858     0    stevel 	/*
    859     0    stevel 	 * if scsi-selection-timeout property exists, use it
    860     0    stevel 	 */
    861     0    stevel 	esp_selection_timeout = ddi_prop_get_int(DDI_DEV_T_ANY,
    862     0    stevel 	    dip, 0, "scsi-selection-timeout", SCSI_DEFAULT_SELECTION_TIMEOUT);
    863     0    stevel 
    864     0    stevel #ifdef ESPDEBUG
    865     0    stevel 	if ((esp->e_scsi_options & SCSI_DEBUG_HA) && (espdebug == 0)) {
    866     0    stevel 		espdebug = 1;
    867     0    stevel 	}
    868     0    stevel #endif
    869     0    stevel 
    870     0    stevel 	/*
    871     0    stevel 	 * if target<n>-scsi-options property exists, use it;
    872     0    stevel 	 * otherwise use the e_scsi_options
    873     0    stevel 	 */
    874     0    stevel 	for (i = 0; i < NTARGETS; i++) {
    875     0    stevel 		(void) sprintf(prop_str, prop_template, i);
    876     0    stevel 		esp->e_target_scsi_options[i] = ddi_prop_get_int(
    877  7656    Sherry 		    DDI_DEV_T_ANY, dip, 0, prop_str, -1);
    878     0    stevel 		if (esp->e_target_scsi_options[i] != -1) {
    879     0    stevel 			esplog(esp, CE_NOTE,
    880  7656    Sherry 			    "?target%d_scsi_options=0x%x\n",
    881  7656    Sherry 			    i, esp->e_target_scsi_options[i]);
    882     0    stevel 			esp->e_target_scsi_options_defined |= 1 << i;
    883     0    stevel 		} else {
    884     0    stevel 			esp->e_target_scsi_options[i] = esp->e_scsi_options;
    885     0    stevel 		}
    886     0    stevel 
    887     0    stevel 		if (((esp->e_target_scsi_options[i] & SCSI_OPTIONS_DR) == 0) &&
    888     0    stevel 		    (esp->e_target_scsi_options[i] & SCSI_OPTIONS_TAG)) {
    889     0    stevel 			esp->e_target_scsi_options[i] &= ~SCSI_OPTIONS_TAG;
    890     0    stevel 			esplog(esp, CE_WARN,
    891     0    stevel 			    "Disabled TQ since disconnects are disabled\n");
    892     0    stevel 		}
    893     0    stevel 	}
    894     0    stevel 
    895     0    stevel 	esp->e_scsi_tag_age_limit =
    896     0    stevel 	    ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, "scsi-tag-age-limit",
    897     0    stevel 	    scsi_tag_age_limit);
    898     0    stevel 	IPRINTF2("esp tag age limit=%d, global=%d\n",
    899     0    stevel 	    esp->e_scsi_tag_age_limit, scsi_tag_age_limit);
    900     0    stevel 	if (esp->e_scsi_tag_age_limit != scsi_tag_age_limit) {
    901     0    stevel 		esplog(esp, CE_NOTE, "scsi-tag-age-limit=%d\n",
    902     0    stevel 		    esp->e_scsi_tag_age_limit);
    903     0    stevel 	}
    904     0    stevel 
    905     0    stevel 	esp->e_scsi_reset_delay = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0,
    906     0    stevel 	    "scsi-reset-delay", scsi_reset_delay);
    907     0    stevel 	IPRINTF2("esp scsi_reset_delay=%x, global=%x\n",
    908     0    stevel 	    esp->e_scsi_reset_delay, scsi_reset_delay);
    909     0    stevel 	if (esp->e_scsi_reset_delay == 0) {
    910     0    stevel 		esplog(esp, CE_NOTE,
    911  7656    Sherry 		    "scsi_reset_delay of 0 is not recommended,"
    912  7656    Sherry 		    " resetting to SCSI_DEFAULT_RESET_DELAY\n");
    913     0    stevel 		esp->e_scsi_reset_delay = SCSI_DEFAULT_RESET_DELAY;
    914     0    stevel 	}
    915     0    stevel 	if (esp->e_scsi_reset_delay != scsi_reset_delay) {
    916     0    stevel 		esplog(esp, CE_NOTE, "scsi-reset-delay=%d\n",
    917     0    stevel 		    esp->e_scsi_reset_delay);
    918     0    stevel 	}
    919     0    stevel 
    920     0    stevel 	esp->e_force_async = 0;
    921     0    stevel 	/*
    922     0    stevel 	 * disable tagged queuing for all targets
    923     0    stevel 	 * (will be enabled by target driver if necessary)
    924     0    stevel 	 */
    925     0    stevel 	esp->e_notag = 0xff;
    926     0    stevel 
    927     0    stevel 	/*
    928     0    stevel 	 * get iblock cookie and initialize mutexes
    929     0    stevel 	 */
    930     0    stevel 	if (ddi_get_iblock_cookie(dip, (uint_t)0, &esp->e_iblock)
    931     0    stevel 	    != DDI_SUCCESS) {
    932     0    stevel 		cmn_err(CE_WARN, "esp_attach: cannot get iblock cookie");
    933     0    stevel 		goto fail;
    934     0    stevel 	}
    935     0    stevel 
    936     0    stevel 	mutex_init(ESP_MUTEX, NULL, MUTEX_DRIVER, esp->e_iblock);
    937     0    stevel 
    938     0    stevel 	/*
    939     0    stevel 	 * initialize mutex for startQ
    940     0    stevel 	 */
    941     0    stevel 	mutex_init(&esp->e_startQ_mutex, NULL, MUTEX_DRIVER, esp->e_iblock);
    942     0    stevel 
    943     0    stevel 	/*
    944     0    stevel 	 * add this esp to the linked list of esp's
    945     0    stevel 	 */
    946     0    stevel 	rw_enter(&esp_global_rwlock, RW_WRITER);
    947     0    stevel 	if (esp_softc == (struct esp *)NULL) {
    948     0    stevel 		esp_softc = esp;
    949     0    stevel 	} else {
    950     0    stevel 		esp_tail->e_next = esp;
    951     0    stevel 	}
    952     0    stevel 	esp_tail = esp;		/* point to last esp in list */
    953     0    stevel 	rw_exit(&esp_global_rwlock);
    954     0    stevel 	mutex_initialized++;
    955     0    stevel 
    956     0    stevel 	/*
    957     0    stevel 	 * kstat_intr support
    958     0    stevel 	 */
    959     0    stevel 	(void) sprintf(buf, "esp%d", instance);
    960     0    stevel 	esp->e_intr_kstat = kstat_create("esp", instance, buf, "controller", \
    961  7656    Sherry 	    KSTAT_TYPE_INTR, 1, KSTAT_FLAG_PERSISTENT);
    962     0    stevel 	if (esp->e_intr_kstat)
    963     0    stevel 		kstat_install(esp->e_intr_kstat);
    964     0    stevel 
    965     0    stevel 	if (ddi_add_intr(dip, (uint_t)0, &esp->e_iblock, NULL, esp_intr,
    966  7656    Sherry 	    (caddr_t)esp)) {
    967     0    stevel 		cmn_err(CE_WARN, "esp: cannot add intr");
    968     0    stevel 		goto fail;
    969     0    stevel 	}
    970     0    stevel 	add_intr_done++;
    971     0    stevel 
    972     0    stevel 	/*
    973     0    stevel 	 * finally, find out what kind of ESP/FAS chip we have here
    974     0    stevel 	 * now we are ready to take the reset interrupt
    975     0    stevel 	 */
    976     0    stevel 	esp_determine_chip_type(esp);
    977     0    stevel 
    978     0    stevel 	/*
    979     0    stevel 	 * start off one watchdog for all esp's now we are fully initialized
    980     0    stevel 	 */
    981     0    stevel 	if (esp_softc == esp) {
    982     0    stevel 		esp_scsi_watchdog_tick =
    983     0    stevel 		    ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0,
    984  7656    Sherry 		    "scsi-watchdog-tick", scsi_watchdog_tick);
    985     0    stevel 		if (esp_scsi_watchdog_tick != scsi_watchdog_tick) {
    986     0    stevel 			esplog(esp, CE_NOTE, "scsi-watchdog-tick=%d\n",
    987     0    stevel 			    esp_scsi_watchdog_tick);
    988     0    stevel 		}
    989     0    stevel 		esp_tick = drv_usectohz((clock_t)
    990     0    stevel 		    esp_scsi_watchdog_tick * 1000000);
    991     0    stevel 		IPRINTF2("esp scsi watchdog tick=%x, esp_tick=%lx\n",
    992     0    stevel 		    esp_scsi_watchdog_tick, esp_tick);
    993     0    stevel 		mutex_enter(&esp_global_mutex);
    994     0    stevel 		if (esp_timeout_id == 0) {
    995     0    stevel 			esp_timeout_id = timeout(esp_watch, NULL, esp_tick);
    996     0    stevel 			esp_timeout_initted = 1;
    997     0    stevel 		}
    998     0    stevel 		mutex_exit(&esp_global_mutex);
    999     0    stevel 	}
   1000     0    stevel 
   1001     0    stevel 	/*
   1002     0    stevel 	 * Initialize power management bookkeeping; components are
   1003     0    stevel 	 * created idle
   1004     0    stevel 	 */
   1005     0    stevel 
   1006     0    stevel 	/*
   1007     0    stevel 	 * Since as of now, there is no power management done in
   1008     0    stevel 	 * scsi-HBA drivers, there is no need to create a pm_component.
   1009     0    stevel 	 * BUT esp is a special case with GYPSY. In gypsy, the
   1010     0    stevel 	 * PM_SUSPEND/PM_RESUME is used. So, the following few lines
   1011     0    stevel 	 * of code will be there until Gypsy machines are supported.
   1012     0    stevel 	 */
   1013     0    stevel 
   1014     0    stevel 	if (pm_create_components(dip, 1) == DDI_SUCCESS) {
   1015     0    stevel 		pm_set_normal_power(dip, 0, 1);
   1016     0    stevel 	} else {
   1017     0    stevel 		goto fail;
   1018     0    stevel 	}
   1019     0    stevel 
   1020     0    stevel #ifdef ESP_KSTATS
   1021     0    stevel 	/*
   1022     0    stevel 	 * kstats to measure scsi bus busy time
   1023     0    stevel 	 */
   1024     0    stevel 	if (esp_do_bus_kstats) {
   1025     0    stevel 		if ((esp->e_scsi_bus_stats = kstat_create("esp-scsi-bus",
   1026     0    stevel 		    instance, NULL, "disk", KSTAT_TYPE_IO, 1,
   1027     0    stevel 		    KSTAT_FLAG_PERSISTENT)) != NULL) {
   1028     0    stevel 			esp->e_scsi_bus_stats->ks_lock = ESP_MUTEX;
   1029     0    stevel 			kstat_install(esp->e_scsi_bus_stats);
   1030     0    stevel 		}
   1031     0    stevel 	}
   1032     0    stevel #endif /* ESP_KSTATS */
   1033     0    stevel 
   1034     0    stevel 	/*
   1035     0    stevel 	 * create a possibly shared callback thread which will empty the
   1036     0    stevel 	 * callback queue
   1037     0    stevel 	 */
   1038     0    stevel 	mutex_enter(&esp_global_mutex);
   1039     0    stevel 	esp_create_callback_thread(esp);
   1040     0    stevel 	mutex_exit(&esp_global_mutex);
   1041     0    stevel 
   1042     0    stevel 	/*
   1043     0    stevel 	 * create kmem cache for packets
   1044     0    stevel 	 */
   1045     0    stevel 	(void) sprintf(buf, "esp%d_cache", instance);
   1046     0    stevel 	esp->e_kmem_cache = kmem_cache_create(buf,
   1047  7656    Sherry 	    ESP_CMD_SIZE, 8,
   1048  7656    Sherry 	    esp_kmem_cache_constructor, esp_kmem_cache_destructor,
   1049  7656    Sherry 	    NULL, (void *)esp, NULL, 0);
   1050     0    stevel 	if (esp->e_kmem_cache == NULL) {
   1051     0    stevel 		cmn_err(CE_WARN, "esp: cannot create kmem_cache");
   1052     0    stevel 		goto fail;
   1053     0    stevel 	}
   1054     0    stevel 
   1055     0    stevel 	ddi_report_dev(dip);
   1056     0    stevel 
   1057     0    stevel 	return (DDI_SUCCESS);
   1058     0    stevel 
   1059     0    stevel fail:
   1060     0    stevel 	cmn_err(CE_WARN, "esp%d: cannot attach", instance);
   1061     0    stevel 	if (esp) {
   1062     0    stevel 		struct esp *next, *prev;
   1063     0    stevel 
   1064     0    stevel 		/* remove this esp from the linked list */
   1065     0    stevel 		rw_enter(&esp_global_rwlock, RW_WRITER);
   1066     0    stevel 		for (prev = NULL,  next = esp_softc; next != NULL;
   1067     0    stevel 		    prev = next, next = next->e_next) {
   1068     0    stevel 			if (next == esp) {
   1069     0    stevel 				if (next == esp_softc) {
   1070     0    stevel 					esp_softc = esp->e_next;
   1071     0    stevel 				} else {
   1072     0    stevel 					prev->e_next = esp->e_next;
   1073     0    stevel 				}
   1074     0    stevel 				if (esp_tail == esp) {
   1075     0    stevel 					esp_tail = prev;
   1076     0    stevel 				}
   1077     0    stevel 				break;
   1078     0    stevel 			}
   1079     0    stevel 		}
   1080     0    stevel 		rw_exit(&esp_global_rwlock);
   1081     0    stevel 
   1082     0    stevel 		if (mutex_initialized) {
   1083     0    stevel 			mutex_destroy(&esp->e_startQ_mutex);
   1084     0    stevel 			mutex_destroy(ESP_MUTEX);
   1085     0    stevel 		}
   1086     0    stevel 		if (esp->e_intr_kstat) {
   1087     0    stevel 			kstat_delete(esp->e_intr_kstat);
   1088     0    stevel 		}
   1089     0    stevel 		if (add_intr_done) {
   1090     0    stevel 			ddi_remove_intr(dip, (uint_t)0, esp->e_iblock);
   1091     0    stevel 		}
   1092     0    stevel 		if (tran) {
   1093     0    stevel 			scsi_hba_tran_free(tran);
   1094     0    stevel 		}
   1095     0    stevel 		if (esp->e_kmem_cache) {
   1096     0    stevel 			kmem_cache_destroy(esp->e_kmem_cache);
   1097     0    stevel 		}
   1098     0    stevel 		if (esp->e_cmdarea) {
   1099     0    stevel 			if (bound_handle) {
   1100     0    stevel 				(void) ddi_dma_unbind_handle(esp->e_dmahandle);
   1101     0    stevel 			}
   1102     0    stevel 			ddi_dma_mem_free(&esp->e_cmdarea_acc_handle);
   1103     0    stevel 		}
   1104     0    stevel 		if (esp->e_dmahandle) {
   1105     0    stevel 			ddi_dma_free_handle(&esp->e_dmahandle);
   1106     0    stevel 		}
   1107     0    stevel 	}
   1108     0    stevel 
   1109     0    stevel 	if (dmar)
   1110     0    stevel 		dma_free((struct dmaga *)dmar);
   1111     0    stevel unmap:
   1112     0    stevel 	if (esp->e_regs_acc_handle)
   1113     0    stevel 		ddi_regs_map_free(&esp->e_regs_acc_handle);
   1114     0    stevel 
   1115     0    stevel exit:
   1116     0    stevel 	if (esp) {
   1117     0    stevel 		ddi_soft_state_free(esp_state, instance);
   1118     0    stevel 	}
   1119     0    stevel 
   1120     0    stevel 	return (DDI_FAILURE);
   1121     0    stevel }
   1122     0    stevel 
   1123     0    stevel /*ARGSUSED*/
   1124     0    stevel static int
   1125     0    stevel esp_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
   1126     0    stevel {
   1127     0    stevel 	struct esp	*esp, *nesp;
   1128     0    stevel 	scsi_hba_tran_t		*tran;
   1129     0    stevel 
   1130     0    stevel 	switch (cmd) {
   1131     0    stevel 	case DDI_DETACH:
   1132     0    stevel 		return (esp_dr_detach(dip));
   1133     0    stevel 
   1134     0    stevel 	case DDI_SUSPEND:
   1135     0    stevel 	case DDI_PM_SUSPEND:
   1136     0    stevel 		if ((tran = ddi_get_driver_private(dip)) == NULL)
   1137     0    stevel 			return (DDI_FAILURE);
   1138     0    stevel 
   1139     0    stevel 		esp = TRAN2ESP(tran);
   1140     0    stevel 		if (!esp) {
   1141     0    stevel 			return (DDI_FAILURE);
   1142     0    stevel 		}
   1143     0    stevel 		mutex_enter(ESP_MUTEX);
   1144     0    stevel 
   1145     0    stevel 		esp->e_suspended = 1;
   1146     0    stevel 		esp_watchdog_running = 0;
   1147     0    stevel 
   1148     0    stevel 		if (esp->e_ncmds) {
   1149     0    stevel 			(void) esp_reset_bus(esp);
   1150     0    stevel 			(void) esp_dopoll(esp, SHORT_POLL_TIMEOUT);
   1151     0    stevel 		}
   1152     0    stevel 		/*
   1153     0    stevel 		 * In the current implementation of esp power management, the
   1154     0    stevel 		 * SCSI active terminators are turned off and so the bus
   1155     0    stevel 		 * signals can wander everywhere - including generating false
   1156     0    stevel 		 * interrupts, so they need to be disabled.  This should also
   1157     0    stevel 		 * be done for a full SUSPEND in theory, but since CPR writes
   1158     0    stevel 		 * out the state file....
   1159     0    stevel 		 */
   1160     0    stevel 		if (cmd == DDI_PM_SUSPEND) {
   1161     0    stevel 			esp->e_dmaga_csr &= ~DMAGA_INTEN;
   1162     0    stevel 			esp->e_dma->dmaga_csr = esp->e_dmaga_csr;
   1163     0    stevel 		}
   1164     0    stevel 		mutex_exit(ESP_MUTEX);
   1165     0    stevel 
   1166     0    stevel 		if (esp->e_restart_cmd_timeid) {
   1167     0    stevel 			(void) untimeout(esp->e_restart_cmd_timeid);
   1168     0    stevel 			esp->e_restart_cmd_timeid = 0;
   1169     0    stevel 		}
   1170     0    stevel 
   1171     0    stevel 		/* Last esp? */
   1172     0    stevel 		rw_enter(&esp_global_rwlock, RW_WRITER);
   1173     0    stevel 		for (nesp = esp_softc; nesp; nesp = nesp->e_next) {
   1174     0    stevel 			if (!nesp->e_suspended) {
   1175     0    stevel 				rw_exit(&esp_global_rwlock);
   1176     0    stevel 				return (DDI_SUCCESS);
   1177     0    stevel 			}
   1178     0    stevel 		}
   1179     0    stevel 		rw_exit(&esp_global_rwlock);
   1180     0    stevel 
   1181     0    stevel 		mutex_enter(&esp_global_mutex);
   1182     0    stevel 		if (esp_timeout_initted) {
   1183     0    stevel 			timeout_id_t tid = esp_timeout_id;
   1184     0    stevel 			esp_timeout_initted = 0;
   1185     0    stevel 			esp_timeout_id = 0;		/* don't resched */
   1186     0    stevel 			mutex_exit(&esp_global_mutex);
   1187     0    stevel 			(void) untimeout(tid);
   1188     0    stevel 			mutex_enter(&esp_global_mutex);
   1189     0    stevel 		}
   1190     0    stevel 
   1191     0    stevel 		if (esp_reset_watch) {
   1192     0    stevel 			mutex_exit(&esp_global_mutex);
   1193     0    stevel 			(void) untimeout(esp_reset_watch);
   1194     0    stevel 			mutex_enter(&esp_global_mutex);
   1195     0    stevel 			esp_reset_watch = 0;
   1196     0    stevel 		}
   1197     0    stevel 		mutex_exit(&esp_global_mutex);
   1198     0    stevel 
   1199     0    stevel 		return (DDI_SUCCESS);
   1200     0    stevel 
   1201     0    stevel 	default:
   1202     0    stevel 		return (DDI_FAILURE);
   1203     0    stevel 	}
   1204     0    stevel 	_NOTE(NOT_REACHED)
   1205     0    stevel 	/* NOTREACHED */
   1206     0    stevel }
   1207     0    stevel 
   1208     0    stevel static int
   1209     0    stevel esp_dr_detach(dev_info_t *dev)
   1210     0    stevel {
   1211     0    stevel 	struct esp	*esp, *e;
   1212     0    stevel 	scsi_hba_tran_t		*tran;
   1213     0    stevel 	int			i, j;
   1214     0    stevel 
   1215     0    stevel 	if ((tran = ddi_get_driver_private(dev)) == NULL)
   1216     0    stevel 		return (DDI_FAILURE);
   1217     0    stevel 
   1218     0    stevel 	esp = TRAN2ESP(tran);
   1219     0    stevel 	if (!esp) {
   1220     0    stevel 		return (DDI_FAILURE);
   1221     0    stevel 	}
   1222     0    stevel 
   1223     0    stevel 	/*
   1224     0    stevel 	 * Force interrupts OFF
   1225     0    stevel 	 */
   1226     0    stevel 	esp->e_dmaga_csr &= ~DMAGA_INTEN;
   1227     0    stevel 	esp->e_dma->dmaga_csr = esp->e_dmaga_csr;
   1228     0    stevel 	ddi_remove_intr(dev, (uint_t)0, esp->e_iblock);
   1229     0    stevel 
   1230     0    stevel #ifdef ESP_KSTATS
   1231     0    stevel 	/*
   1232     0    stevel 	 * Remove kstats if any i.e., if pointer non-NULL.
   1233     0    stevel 	 * Note: pointer NOT explicitly NULL'ed. But buffer zalloc'd
   1234     0    stevel 	 */
   1235     0    stevel 	if (esp->e_scsi_bus_stats != (struct kstat *)NULL) {
   1236     0    stevel 		kmutex_t *lp = esp->e_scsi_bus_stats->ks_lock;
   1237     0    stevel 		if ((lp != (kmutex_t *)NULL) && !MUTEX_HELD(lp))
   1238     0    stevel 			kstat_delete(esp->e_scsi_bus_stats);
   1239     0    stevel 	}
   1240     0    stevel #endif /* ESP_KSTATS */
   1241     0    stevel 
   1242     0    stevel 	/*
   1243     0    stevel 	 * deallocate reset notify callback list
   1244     0    stevel 	 */
   1245     0    stevel 	scsi_hba_reset_notify_tear_down(esp->e_reset_notify_listf);
   1246     0    stevel 
   1247     0    stevel 	/*
   1248     0    stevel 	 * Remove device instance from the global linked list
   1249     0    stevel 	 */
   1250     0    stevel 	rw_enter(&esp_global_rwlock, RW_WRITER);
   1251     0    stevel 
   1252     0    stevel 	if (esp_softc == esp) {
   1253     0    stevel 		e = esp_softc = esp->e_next;
   1254     0    stevel 	} else {
   1255     0    stevel 		for (e = esp_softc; e != (struct esp *)NULL; e = e->e_next) {
   1256     0    stevel 			if (e->e_next == esp) {
   1257     0    stevel 				e->e_next = esp->e_next;
   1258     0    stevel 				break;
   1259     0    stevel 			}
   1260     0    stevel 		}
   1261     0    stevel 		if (e == (struct esp *)NULL) {
   1262     0    stevel 			/*
   1263     0    stevel 			 * Instance not in softc list. Since the
   1264     0    stevel 			 * instance is not there in softc list, don't
   1265     0    stevel 			 * enable interrupts, the instance is effectively
   1266     0    stevel 			 * unusable.
   1267     0    stevel 			 */
   1268     0    stevel 			cmn_err(CE_WARN, "esp_dr_detach: esp instance not"
   1269  7656    Sherry 			    " in softc list!");
   1270     0    stevel 			rw_exit(&esp_global_rwlock);
   1271     0    stevel 			return (DDI_FAILURE);
   1272     0    stevel 		}
   1273     0    stevel 	}
   1274     0    stevel 
   1275     0    stevel 	if (esp_tail == esp)
   1276     0    stevel 		esp_tail = e;
   1277     0    stevel 
   1278     0    stevel 	rw_exit(&esp_global_rwlock);
   1279     0    stevel 
   1280     0    stevel 	if (esp->e_intr_kstat)
   1281     0    stevel 		kstat_delete(esp->e_intr_kstat);
   1282     0    stevel 
   1283     0    stevel 	/*
   1284     0    stevel 	 * disallow timeout thread rescheduling
   1285     0    stevel 	 */
   1286     0    stevel 	mutex_enter(&esp_global_mutex);
   1287     0    stevel 	esp->e_flags |= ESP_FLG_NOTIMEOUTS;
   1288     0    stevel 	mutex_exit(&esp_global_mutex);
   1289     0    stevel 
   1290     0    stevel 	/*
   1291     0    stevel 	 * last esp? ... if active, CANCEL watch threads.
   1292     0    stevel 	 */
   1293     0    stevel 	if (esp_softc == (struct esp *)NULL) {
   1294     0    stevel 		mutex_enter(&esp_global_mutex);
   1295     0    stevel 		if (esp_timeout_initted) {
   1296     0    stevel 			timeout_id_t tid = esp_timeout_id;
   1297     0    stevel 			esp_timeout_initted = 0;
   1298     0    stevel 			esp_timeout_id = 0;		/* don't resched */
   1299     0    stevel 			mutex_exit(&esp_global_mutex);
   1300     0    stevel 			(void) untimeout(tid);
   1301     0    stevel 			mutex_enter(&esp_global_mutex);
   1302     0    stevel 		}
   1303     0    stevel 
   1304     0    stevel 		if (esp_reset_watch) {
   1305     0    stevel 			mutex_exit(&esp_global_mutex);
   1306     0    stevel 			(void) untimeout(esp_reset_watch);
   1307     0    stevel 			mutex_enter(&esp_global_mutex);
   1308     0    stevel 			esp_reset_watch = 0;
   1309     0    stevel 		}
   1310     0    stevel 		mutex_exit(&esp_global_mutex);
   1311     0    stevel 	}
   1312     0    stevel 
   1313     0    stevel 	if (esp->e_restart_cmd_timeid) {
   1314     0    stevel 		(void) untimeout(esp->e_restart_cmd_timeid);
   1315     0    stevel 		esp->e_restart_cmd_timeid = 0;
   1316     0    stevel 	}
   1317     0    stevel 
   1318     0    stevel 	/*
   1319     0    stevel 	 * destroy outstanding ARQ pkts
   1320     0    stevel 	 */
   1321     0    stevel 	for (i = 0; i < NTARGETS; i++) {
   1322     0    stevel 		for (j = 0; j < NLUNS_PER_TARGET; j++) {
   1323     0    stevel 			int slot = i * NLUNS_PER_TARGET | j;
   1324     0    stevel 			if (esp->e_arq_pkt[slot]) {
   1325     0    stevel 				struct scsi_address	sa;
   1326     0    stevel 				sa.a_hba_tran = NULL;	/* not used */
   1327     0    stevel 				sa.a_target = (ushort_t)i;
   1328     0    stevel 				sa.a_lun = (uchar_t)j;
   1329     0    stevel 				(void) esp_create_arq_pkt(esp, &sa, 0);
   1330     0    stevel 			}
   1331     0    stevel 		}
   1332     0    stevel 	}
   1333     0    stevel 
   1334     0    stevel 	/*
   1335     0    stevel 	 * destroy any outstanding tagged command info
   1336     0    stevel 	 */
   1337     0    stevel 	for (i = 0; i < N_SLOTS; i++) {
   1338     0    stevel 		struct t_slots *active = esp->e_tagQ[i];
   1339     0    stevel 		if (active) {
   1340     0    stevel 			for (j = 0; j < NTAGS; j++) {
   1341     0    stevel 				struct esp_cmd *sp = active->t_slot[j];
   1342     0    stevel 				if (sp) {
   1343     0    stevel 					struct scsi_pkt *pkt = &sp->cmd_pkt;
   1344     0    stevel 					if (pkt) {
   1345     0    stevel 						esp_scsi_destroy_pkt(
   1346     0    stevel 						    &pkt->pkt_address, pkt);
   1347     0    stevel 					}
   1348     0    stevel 					/* sp freed in esp_scsi_destroy_pkt */
   1349     0    stevel 					active->t_slot[j] = NULL;
   1350     0    stevel 				}
   1351     0    stevel 			}
   1352     0    stevel 			kmem_free(active, sizeof (struct t_slots));
   1353     0    stevel 			esp->e_tagQ[i] = NULL;
   1354     0    stevel 		}
   1355     0    stevel 		ASSERT(esp->e_tcmds[i] == 0);
   1356     0    stevel 	}
   1357     0    stevel 
   1358     0    stevel 	/*
   1359     0    stevel 	 * Remove device MT locks
   1360     0    stevel 	 */
   1361     0    stevel 	mutex_destroy(&esp->e_startQ_mutex);
   1362     0    stevel 	mutex_destroy(ESP_MUTEX);
   1363     0    stevel 
   1364     0    stevel 	/*
   1365     0    stevel 	 * Release miscellaneous device resources
   1366     0    stevel 	 */
   1367     0    stevel 	if (esp->e_kmem_cache) {
   1368     0    stevel 		kmem_cache_destroy(esp->e_kmem_cache);
   1369     0    stevel 	}
   1370     0    stevel 
   1371     0    stevel 	if (esp->e_cmdarea != (uchar_t *)NULL) {
   1372     0    stevel 		(void) ddi_dma_unbind_handle(esp->e_dmahandle);
   1373     0    stevel 		ddi_dma_mem_free(&esp->e_cmdarea_acc_handle);
   1374     0    stevel 	}
   1375     0    stevel 
   1376     0    stevel 	if (esp->e_dmahandle != NULL)
   1377     0    stevel 		ddi_dma_free_handle(&esp->e_dmahandle);
   1378     0    stevel 
   1379     0    stevel 	if (esp->e_dma != (struct dmaga *)NULL)
   1380     0    stevel 		dma_free((struct dmaga *)esp->e_dma);
   1381     0    stevel 
   1382     0    stevel 	ddi_regs_map_free(&esp->e_regs_acc_handle);
   1383     0    stevel 
   1384     0    stevel 	esp_destroy_callback_thread(esp);
   1385     0    stevel 
   1386     0    stevel 	/*
   1387     0    stevel 	 * Process shared callback resources, as required.
   1388     0    stevel 	 * Update callback_thread bookkeeping.
   1389     0    stevel 	 */
   1390     0    stevel 	ddi_soft_state_free(esp_state, ddi_get_instance(dev));
   1391     0    stevel 
   1392     0    stevel 	/*
   1393     0    stevel 	 * Remove properties created during attach()
   1394     0    stevel 	 */
   1395     0    stevel 	ddi_prop_remove_all(dev);
   1396     0    stevel 
   1397     0    stevel 	/*
   1398     0    stevel 	 * Delete the DMA limits, transport vectors and remove the device
   1399     0    stevel 	 * links to the scsi_transport layer.
   1400     0    stevel 	 *	-- ddi_set_driver_private(dip, NULL)
   1401     0    stevel 	 */
   1402     0    stevel 	(void) scsi_hba_detach(dev);
   1403     0    stevel 
   1404     0    stevel 	/*
   1405     0    stevel 	 * Free the scsi_transport structure for this device.
   1406     0    stevel 	 */
   1407     0    stevel 	scsi_hba_tran_free(tran);
   1408     0    stevel 
   1409     0    stevel 	return (DDI_SUCCESS);
   1410     0    stevel }
   1411     0    stevel 
   1412     0    stevel /*
   1413     0    stevel  * Hardware and Software internal reset routines
   1414     0    stevel  */
   1415     0    stevel static void
   1416     0    stevel esp_determine_chip_type(struct esp *esp)
   1417     0    stevel {
   1418     0    stevel 	int i;
   1419     0    stevel 	uchar_t clock_conv;
   1420     0    stevel 	clock_t ticks;
   1421     0    stevel 	volatile struct espreg *ep = esp->e_reg;
   1422     0    stevel 
   1423     0    stevel 	if (esp->e_scsi_options & SCSI_OPTIONS_PARITY)
   1424     0    stevel 		esp->e_espconf |= ESP_CONF_PAREN;
   1425     0    stevel 
   1426     0    stevel 	/*
   1427     0    stevel 	 * Determine clock frequency of attached ESP chip.
   1428     0    stevel 	 */
   1429     0    stevel 	i = ddi_prop_get_int(DDI_DEV_T_ANY, esp->e_dev, 0, prop_cfreq, -1);
   1430     0    stevel 
   1431     0    stevel 	/*
   1432     0    stevel 	 * Valid clock freqs. are between 10 and 40 MHz.  Otherwise
   1433     0    stevel 	 * presume 20 MHz. and complain.  (Notice, that we wrap to
   1434     0    stevel 	 * zero at 40 MHz.  Ick!)  This test should NEVER fail!
   1435     0    stevel 	 *
   1436     0    stevel 	 *	freq (MHz)	clock conversion factor
   1437     0    stevel 	 *	10		2
   1438     0    stevel 	 *	10.01-15	3
   1439     0    stevel 	 *	15.01-20	4
   1440     0    stevel 	 *	20.01-25	5
   1441     0    stevel 	 *	25.01-30	6
   1442     0    stevel 	 *	30.01-35	7
   1443     0    stevel 	 *	35.01-40	8 (0)
   1444     0    stevel 	 */
   1445     0    stevel 	if (i > FIVE_MEG) {
   1446     0    stevel 		clock_conv = (i + FIVE_MEG - 1)/ FIVE_MEG;
   1447     0    stevel 	} else {
   1448     0    stevel 		clock_conv = 0;
   1449     0    stevel 	}
   1450     0    stevel 	if (clock_conv < CLOCK_10MHZ || clock_conv > CLOCK_40MHZ) {
   1451     0    stevel 		esplog(esp, CE_WARN,
   1452     0    stevel 		    "Bad clock frequency- setting 20mhz, asynchronous mode");
   1453     0    stevel 		esp->e_weak = 0xff;
   1454     0    stevel 		clock_conv = CLOCK_20MHZ;
   1455     0    stevel 		i = TWENTY_MEG;
   1456     0    stevel 	}
   1457     0    stevel 
   1458     0    stevel 	esp->e_clock_conv = clock_conv;
   1459     0    stevel 	esp->e_clock_cycle = CLOCK_PERIOD(i);
   1460     0    stevel 	ticks = ESP_CLOCK_TICK(esp);
   1461     0    stevel 	esp->e_stval = ESP_CLOCK_TIMEOUT(ticks, esp_selection_timeout);
   1462     0    stevel 
   1463     0    stevel 	IPRINTF5("%d mhz, clock_conv %d, clock_cycle %d, ticks %ld, stval %d\n",
   1464  7656    Sherry 	    i, esp->e_clock_conv, esp->e_clock_cycle,
   1465  7656    Sherry 	    ticks, esp->e_stval);
   1466     0    stevel 
   1467     0    stevel 	ep->esp_conf2 = 0;
   1468     0    stevel 	ep->esp_conf2 = 0xa;
   1469     0    stevel 	if ((ep->esp_conf2 & 0xf) == 0xa) {
   1470     0    stevel 		esp->e_espconf2 = (uchar_t)ESP_CONF2_SCSI2;
   1471     0    stevel 		ep->esp_conf3 = 0;
   1472     0    stevel 		ep->esp_conf3 = 5;
   1473     0    stevel 		if (ep->esp_conf3 == 0x5) {
   1474     0    stevel 			for (i = 0; i < NTARGETS; i++) {
   1475     0    stevel 				esp->e_espconf3[i] = 0;
   1476     0    stevel 			}
   1477     0    stevel 			if (clock_conv > CLOCK_25MHZ) {
   1478     0    stevel 				/*
   1479     0    stevel 				 * do not enable FENABLE when using
   1480     0    stevel 				 * stacked cmds
   1481     0    stevel 				 * esp->e_espconf2 |= ESP_CONF2_FENABLE;
   1482     0    stevel 				 */
   1483     0    stevel 				ep->esp_conf2 = esp->e_espconf2;
   1484     0    stevel 				esp->e_type = FAST;
   1485     0    stevel 				IPRINTF("found FAST\n");
   1486     0    stevel 			} else {
   1487     0    stevel 				ep->esp_conf2 = esp->e_espconf2;
   1488     0    stevel 				esp->e_type = ESP236;
   1489     0    stevel 			}
   1490     0    stevel 			ep->esp_conf3 = 0;
   1491     0    stevel 		} else {
   1492     0    stevel 			ep->esp_conf2 = esp->e_espconf2;
   1493     0    stevel 			esp->e_type = ESP100A;
   1494     0    stevel 		}
   1495     0    stevel 	} else {
   1496     0    stevel 		esp->e_type = ESP100;
   1497     0    stevel 	}
   1498     0    stevel 
   1499     0    stevel 	for (i = 0; i < NTARGETS; i++) {
   1500     0    stevel 		if (esp->e_target_scsi_options[i] & SCSI_OPTIONS_FAST) {
   1501     0    stevel 			esp->e_default_period[i] = (uchar_t)
   1502     0    stevel 			    MIN_SYNC_PERIOD(esp);
   1503     0    stevel 		} else {
   1504     0    stevel 			esp->e_default_period[i] =
   1505     0    stevel 			    (uchar_t)CONVERT_PERIOD(DEFAULT_SYNC_PERIOD);
   1506     0    stevel 		}
   1507     0    stevel 	}
   1508     0    stevel 
   1509     0    stevel 	New_state(esp, ACTS_RESET);
   1510     0    stevel 
   1511     0    stevel 	/*
   1512     0    stevel 	 * Avoid resetting the scsi bus since this causes a few seconds
   1513     0    stevel 	 * delay per esp in boot and also causes busy conditions in some
   1514     0    stevel 	 * tape devices.
   1515     0    stevel 	 * we assume that with FAS devices, we probably have OBP 2.0 or
   1516     0    stevel 	 * higher which resets the bus before booting.
   1517     0    stevel 	 * worst case, we hang during the first probe and reset then
   1518     0    stevel 	 */
   1519     0    stevel 	if ((esp->e_type == FAST) && (esp->e_weak == 0)) {
   1520     0    stevel 		esp_internal_reset(esp,
   1521  7656    Sherry 		    ESP_RESET_SOFTC|ESP_RESET_ESP|ESP_RESET_DMA);
   1522     0    stevel 	} else {
   1523     0    stevel 		esp_internal_reset(esp, ESP_RESET_ALL);
   1524     0    stevel 	}
   1525     0    stevel }
   1526     0    stevel 
   1527     0    stevel static void
   1528     0    stevel esp_flush_fifo(struct esp *esp)
   1529     0    stevel {
   1530     0    stevel 	Esp_cmd(esp, CMD_FLUSH);
   1531     0    stevel 
   1532     0    stevel 	if (esp->e_options & ESP_OPT_SLOW_FIFO_FLUSH) {
   1533     0    stevel 		int i;
   1534     0    stevel 		for (i = 0; i < 1000; i++) {
   1535     0    stevel 			if (FIFO_CNT(esp->e_reg) == 0) {
   1536     0    stevel 				break;
   1537     0    stevel 			}
   1538     0    stevel 			drv_usecwait(1);
   1539     0    stevel 		}
   1540     0    stevel 		if (i >= 1000) {
   1541     0    stevel 			esplog(esp, CE_WARN, "fifo didn't flush\n");
   1542     0    stevel 		}
   1543     0    stevel 	}
   1544     0    stevel }
   1545     0    stevel 
   1546     0    stevel 
   1547     0    stevel static void
   1548     0    stevel esp_internal_reset(struct esp *esp, int reset_action)
   1549     0    stevel {
   1550     0    stevel 	if (reset_action & ESP_RESET_HW) {
   1551     0    stevel 		esp_hw_reset(esp, reset_action);
   1552     0    stevel 	}
   1553     0    stevel 
   1554     0    stevel 	if (reset_action & ESP_RESET_SOFTC) {
   1555     0    stevel 		esp->e_last_slot = esp->e_cur_slot;
   1556     0    stevel 		esp->e_cur_slot = UNDEFINED;
   1557     0    stevel 		bzero(esp->e_slots, (sizeof (struct esp_cmd *)) * N_SLOTS);
   1558     0    stevel 		bzero(esp->e_offset, NTARGETS * (sizeof (uchar_t)));
   1559     0    stevel 		bzero(esp->e_period, NTARGETS * (sizeof (uchar_t)));
   1560     0    stevel 		esp->e_sync_known = esp->e_omsglen = 0;
   1561     0    stevel 		esp->e_cur_msgout[0] = esp->e_last_msgout =
   1562     0    stevel 		    esp->e_last_msgin = INVALID_MSG;
   1563     0    stevel 		esp->e_espconf3_last = esp->e_offset_last =
   1564     0    stevel 		    esp->e_period_last = (uchar_t)-1;
   1565     0    stevel 
   1566     0    stevel 		/*
   1567     0    stevel 		 * esp->e_weak && esp->e_nodisc && ncmds && ndiscs  are
   1568     0    stevel 		 * preserved across softc resets.
   1569     0    stevel 		 */
   1570     0    stevel 		New_state(esp, STATE_FREE);
   1571     0    stevel 	}
   1572     0    stevel 	LOG_STATE(esp, ACTS_RESET, esp->e_stat, -1, reset_action);
   1573     0    stevel }
   1574     0    stevel 
   1575     0    stevel static void
   1576     0    stevel esp_hw_reset(struct esp *esp, int action)
   1577     0    stevel {
   1578     0    stevel 	volatile struct espreg *ep = esp->e_reg;
   1579     0    stevel 	volatile struct dmaga *dmar = esp->e_dma;
   1580     0    stevel 	uchar_t junk, i;
   1581     0    stevel 	int sbus_reruns;
   1582     0    stevel 
   1583     0    stevel 	/*
   1584     0    stevel 	 * never reset the dmaga while a request pending; this
   1585     0    stevel 	 * may cause a hang in xbox if there was a rerun pending
   1586     0    stevel 	 */
   1587     0    stevel 	if (action & ESP_RESET_SCSIBUS) {
   1588     0    stevel 		Esp_cmd(esp, CMD_RESET_SCSI);
   1589     0    stevel 		if (esp_watchdog_running && !panicstr) {
   1590     0    stevel 			int i;
   1591     0    stevel 
   1592     0    stevel 			esp_set_throttles(esp, 0, N_SLOTS, HOLD_THROTTLE);
   1593     0    stevel 			for (i = 0; i < NTARGETS; i++) {
   1594     0    stevel 				esp->e_reset_delay[i] =
   1595     0    stevel 				    esp->e_scsi_reset_delay;
   1596     0    stevel 			}
   1597     0    stevel 			esp_start_watch_reset_delay(esp);
   1598     0    stevel 		} else {
   1599     0    stevel 			drv_usecwait(esp->e_scsi_reset_delay * 1000);
   1600     0    stevel 		}
   1601     0    stevel 		ESP_FLUSH_DMA(esp);
   1602     0    stevel 	}
   1603     0    stevel 
   1604     0    stevel 	if (action & ESP_RESET_DMA) {
   1605     0    stevel 		int burstsizes = esp->e_dma_attr->dma_attr_burstsizes;
   1606     0    stevel 		burstsizes &= (ddi_dma_burstsizes(esp->e_dmahandle) &
   1607  7656    Sherry 		    esp_burst_sizes_limit);
   1608     0    stevel 
   1609     0    stevel 		ESP_FLUSH_DMA(esp);
   1610     0    stevel 		dmar->dmaga_csr = DMAGA_RESET;
   1611     0    stevel 		dmar->dmaga_csr &= ~DMAGA_RESET; /* clear it */
   1612     0    stevel 
   1613     0    stevel 		switch (ESP_DMAGA_REV(esp)) {
   1614     0    stevel 		case ESC1_REV1:
   1615     0    stevel 			sbus_reruns =
   1616     0    stevel 			    ddi_prop_exists(DDI_DEV_T_ANY, esp->e_dev, 0,
   1617     0    stevel 			    "reruns");
   1618     0    stevel 			if (sbus_reruns) {
   1619     0    stevel 				esp->e_options |= ESP_OPT_SBUS_RERUNS;
   1620     0    stevel 			}
   1621     0    stevel 			IPRINTF2("DMA Rev: 0x%x with %s\n", ESP_DMAGA_REV(esp),
   1622     0    stevel 			    sbus_reruns ? "SBus Reruns" : "No SBus Reruns");
   1623     0    stevel 
   1624     0    stevel 			if (!(burstsizes & BURST32)) {
   1625     0    stevel 				IPRINTF("16 byte burstsize\n");
   1626     0    stevel 				DMAESC_SETBURST16(dmar);
   1627     0    stevel 			}
   1628     0    stevel 			dmar->dmaga_csr |= DMAESC_EN_ADD;
   1629     0    stevel 			break;
   1630     0    stevel 
   1631     0    stevel 		case DMA_REV2:
   1632     0    stevel 			if (esp->e_type != ESP100)
   1633     0    stevel 				dmar->dmaga_csr |= DMAGA_TURBO;
   1634     0    stevel 			break;
   1635     0    stevel 
   1636     0    stevel 		case DMA_REV3:
   1637     0    stevel 			dmar->dmaga_csr &= ~DMAGA_TURBO;
   1638     0    stevel 			dmar->dmaga_csr |= DMAGA_TWO_CYCLE;
   1639     0    stevel 
   1640     0    stevel 			if (burstsizes & BURST32) {
   1641     0    stevel 				IPRINTF("32 byte burstsize\n");
   1642     0    stevel 				DMA2_SETBURST32(dmar);
   1643     0    stevel 			}
   1644     0    stevel 			break;
   1645     0    stevel 
   1646     0    stevel 		default:
   1647     0    stevel 			break;
   1648     0    stevel 		}
   1649     0    stevel 	}
   1650     0    stevel 
   1651     0    stevel 	dmar->dmaga_csr = esp->e_dmaga_csr = dmar->dmaga_csr | DMAGA_INTEN;
   1652     0    stevel 
   1653     0    stevel 	if (action & ESP_RESET_ESP) {
   1654     0    stevel 		/*
   1655     0    stevel 		 * according to Emulex, 2 NOPs with DMA are required here
   1656     0    stevel 		 * (essential for FAS101; id_code is unreliable if we don't
   1657     0    stevel 		 * do this)
   1658     0    stevel 		 */
   1659     0    stevel 		ESP_FLUSH_DMA(esp);
   1660     0    stevel 		Esp_cmd(esp, CMD_RESET_ESP);	/* hard-reset ESP chip */
   1661     0    stevel 		Esp_cmd(esp, CMD_NOP | CMD_DMA);
   1662     0    stevel 		Esp_cmd(esp, CMD_NOP | CMD_DMA);
   1663     0    stevel 
   1664     0    stevel 		/*
   1665     0    stevel 		 * Re-load chip configurations
   1666     0    stevel 		 */
   1667     0    stevel 		ep->esp_clock_conv = esp->e_clock_conv & CLOCK_MASK;
   1668     0    stevel 		ep->esp_timeout = esp->e_stval;
   1669     0    stevel 		ep->esp_sync_period = 0;
   1670     0    stevel 		ep->esp_sync_offset = 0;
   1671     0    stevel 
   1672     0    stevel 		/*
   1673     0    stevel 		 * enable default configurations
   1674     0    stevel 		 */
   1675     0    stevel 		if (esp->e_type == FAST) {
   1676     0    stevel 			uchar_t fcode;
   1677     0    stevel 
   1678     0    stevel 			esp->e_idcode = ep->esp_id_code;
   1679     0    stevel 			fcode =
   1680     0    stevel 			    (uchar_t)(ep->esp_id_code & ESP_FCODE_MASK)>>
   1681     0    stevel 			    (uchar_t)3;
   1682     0    stevel 			if (fcode == ESP_FAS236) {
   1683     0    stevel 				esp->e_type = FAS236;
   1684     0    stevel 			} else {
   1685     0    stevel 				esp->e_type = FAS100A;
   1686     0    stevel 			}
   1687     0    stevel 			IPRINTF2("Family code %d, revision %d\n",
   1688     0    stevel 			    fcode, (esp->e_idcode & ESP_REV_MASK));
   1689     0    stevel 		}
   1690     0    stevel 
   1691     0    stevel 		ep->esp_conf = esp->e_espconf;
   1692     0    stevel 		switch (esp->e_type) {
   1693     0    stevel 		case FAS236:
   1694     0    stevel 			/*
   1695     0    stevel 			 * used on DSBE, FSBE, galaxies
   1696     0    stevel 			 */
   1697     0    stevel 			IPRINTF("type is FAS236\n");
   1698     0    stevel 			for (i = 0; i < NTARGETS; i++) {
   1699     0    stevel 				esp->e_espconf3[i] |= ESP_CONF3_236_FASTCLK;
   1700     0    stevel 			}
   1701     0    stevel 			ep->esp_conf3 = esp->e_espconf3[0];
   1702     0    stevel 			esp->e_espconf3_fastscsi = ESP_CONF3_236_FASTSCSI;
   1703     0    stevel 			ep->esp_conf2 = esp->e_espconf2;
   1704     0    stevel 
   1705     0    stevel 			/*
   1706     0    stevel 			 * check if differential scsi bus; if so then no
   1707     0    stevel 			 * req/ack delay desired
   1708     0    stevel 			 */
   1709     0    stevel 			if (ddi_prop_get_int(DDI_DEV_T_ANY, esp->e_dev,
   1710     0    stevel 			    DDI_PROP_DONTPASS, "differential", 0)) {
   1711     0    stevel 				IPRINTF("differential scsibus\n");
   1712     0    stevel 				esp->e_req_ack_delay = 0;
   1713     0    stevel 				esp->e_options |= ESP_OPT_DIFFERENTIAL;
   1714     0    stevel 			} else {
   1715     0    stevel 				esp->e_req_ack_delay =
   1716     0    stevel 				    DEFAULT_REQ_ACK_DELAY_236;
   1717     0    stevel 			}
   1718     0    stevel 			if ((uchar_t)(ep->esp_id_code & ESP_REV_MASK)
   1719     0    stevel 			    > (uchar_t)2) {
   1720     0    stevel 				IPRINTF1("FAS236 rev=%x Stack_cmds DISABLED\n",
   1721     0    stevel 				    (uchar_t)(ep->esp_id_code & ESP_REV_MASK));
   1722     0    stevel 				esp->e_options |= ESP_OPT_DMA_OUT_TAG
   1723     0    stevel 				    | ESP_OPT_FAS;
   1724     0    stevel 			} else {
   1725     0    stevel 				IPRINTF1("FAS236 rev=%x Stack_cmds ENABLED\n",
   1726     0    stevel 				    (uchar_t)(ep->esp_id_code & ESP_REV_MASK));
   1727     0    stevel 				esp->e_options |= ESP_OPT_DMA_OUT_TAG
   1728     0    stevel 				    | ESP_OPT_FAS | ESP_OPT_STACKED_CMDS;
   1729     0    stevel 			}
   1730     0    stevel 			break;
   1731     0    stevel 
   1732     0    stevel 		case FAS100A:
   1733     0    stevel 			/*
   1734     0    stevel 			 * used on all desktop sun4m machines (macio)
   1735     0    stevel 			 */
   1736     0    stevel 			IPRINTF("type is FAS100A or 101A\n");
   1737     0    stevel 			for (i = 0; i < NTARGETS; i++) {
   1738     0    stevel 				esp->e_espconf3[i] |= ESP_CONF3_100A_FASTCLK;
   1739     0    stevel 			}
   1740     0    stevel 			ep->esp_conf3 = esp->e_espconf3[0];
   1741     0    stevel 			esp->e_espconf3_fastscsi = ESP_CONF3_100A_FASTSCSI;
   1742     0    stevel 			ep->esp_conf2 = esp->e_espconf2;
   1743     0    stevel 			esp->e_req_ack_delay = DEFAULT_REQ_ACK_DELAY_101;
   1744     0    stevel 			esp->e_options |= ESP_OPT_DMA_OUT_TAG | ESP_OPT_FAS |
   1745  7656    Sherry 			    ESP_OPT_ACCEPT_STEP567;
   1746     0    stevel 			break;
   1747     0    stevel 
   1748     0    stevel 		case ESP236:
   1749     0    stevel 			/*
   1750     0    stevel 			 * used on galaxies, SBE
   1751     0    stevel 			 */
   1752     0    stevel 			IPRINTF("type is ESP236\n");
   1753     0    stevel 			ep->esp_conf2 = esp->e_espconf2;
   1754     0    stevel 			ep->esp_conf3 = esp->e_espconf3[0];
   1755     0    stevel 			esp->e_options |= ESP_OPT_DMA_OUT_TAG |
   1756  7656    Sherry 			    ESP_OPT_SLOW_FIFO_FLUSH;
   1757     0    stevel 			break;
   1758     0    stevel 
   1759     0    stevel 		case ESP100A:
   1760     0    stevel 			/*
   1761     0    stevel 			 * used on SS2, IPX, sport8
   1762     0    stevel 			 */
   1763     0    stevel 			IPRINTF("type is ESP100A\n");
   1764     0    stevel 			ep->esp_conf2 = esp->e_espconf2;
   1765     0    stevel 			esp->e_options |= ESP_OPT_DMA_OUT_TAG |
   1766     0    stevel 			    ESP_OPT_MASK_OFF_STAT |
   1767     0    stevel 			    ESP_OPT_ACCEPT_STEP567;
   1768     0    stevel 			break;
   1769     0    stevel 
   1770     0    stevel 		case ESP100:
   1771     0    stevel 			/*
   1772     0    stevel 			 * used on SS1, SS1+, IPC
   1773     0    stevel 			 */
   1774     0    stevel 			IPRINTF("type is ESP100\n");
   1775     0    stevel 			IPRINTF("disable sync mode\n");
   1776     0    stevel 			esp->e_weak = 0xff;
   1777     0    stevel 			esp->e_options |= ESP_OPT_MASK_OFF_STAT;
   1778     0    stevel 			break;
   1779     0    stevel 
   1780     0    stevel 		default:
   1781     0    stevel 			IPRINTF("type is ???\n");
   1782     0    stevel 			break;
   1783     0    stevel 		}
   1784     0    stevel 
   1785     0    stevel 		/*
   1786     0    stevel 		 * look up esp-options property
   1787     0    stevel 		 */
   1788     0    stevel 		esp->e_options = ddi_prop_get_int(DDI_DEV_T_ANY,
   1789  7656    Sherry 		    esp->e_dev, 0, "esp-options", esp->e_options);
   1790     0    stevel 
   1791     0    stevel 		esplog(esp, CE_NOTE, "?esp-options=0x%x\n", esp->e_options);
   1792     0    stevel 
   1793     0    stevel 		/*
   1794     0    stevel 		 * Just in case...
   1795     0    stevel 		 * clear interrupt
   1796     0    stevel 		 */
   1797     0    stevel 		junk = ep->esp_intr;
   1798     0    stevel 
   1799     0    stevel 		IPRINTF1("clock conversion = %x\n", esp->e_clock_conv);
   1800     0    stevel 		IPRINTF2("conf = %x (%x)\n", esp->e_espconf, ep->esp_conf);
   1801     0    stevel 		if (esp->e_type > ESP100) {
   1802     0    stevel 			IPRINTF2("conf2 = %x (%x)\n",
   1803     0    stevel 			    esp->e_espconf2, ep->esp_conf2);
   1804     0    stevel 		}
   1805     0    stevel 		if (esp->e_type > ESP100A) {
   1806     0    stevel 			EPRINTF1("conf3=%x (read back)\n", ep->esp_conf3);
   1807     0    stevel 			EPRINTF4("conf3 (for target 0 - 3) = %x %x %x %x\n",
   1808     0    stevel 			    esp->e_espconf3[0], esp->e_espconf3[1],
   1809     0    stevel 			    esp->e_espconf3[2], esp->e_espconf3[3]);
   1810     0    stevel 			EPRINTF3("conf3 (for target 4 - 6) = %x %x %x\n",
   1811     0    stevel 			    esp->e_espconf3[4],
   1812     0    stevel 			    esp->e_espconf3[5], esp->e_espconf3[6]);
   1813     0    stevel 			EPRINTF2("req_ack_delay (0x%p) = %x\n",
   1814     0    stevel 			    (void *)&esp->e_req_ack_delay,
   1815     0    stevel 			    esp->e_req_ack_delay);
   1816     0    stevel 
   1817     0    stevel 		}
   1818     0    stevel 	}
   1819     0    stevel 
   1820     0    stevel #ifdef	lint
   1821     0    stevel 	junk = junk;
   1822     0    stevel #endif	/* lint */
   1823     0    stevel }
   1824     0    stevel 
   1825     0    stevel /*
   1826     0    stevel  * create a thread that performs the callbacks and init associated cv and mutex
   1827     0    stevel  *
   1828     0    stevel  * callback tunables:
   1829     0    stevel  */
   1830     0    stevel static int esp_n_esps_per_callback_thread = 4;
   1831     0    stevel static uchar_t esp_max_spawn = 2;	/* max of 2 extra threads for 4 esps */
   1832     0    stevel static uchar_t esp_cb_now_qlen = 5;
   1833     0    stevel static int esp_hi_cb_load = 50;		/* high watermark */
   1834     0    stevel static int esp_lo_cb_load = 2;		/* low watermark */
   1835     0    stevel static int esp_cb_load_count = 25;
   1836     0    stevel 
   1837     0    stevel static int esp_n_callback_threads = 0;
   1838     0    stevel static struct callback_info  *last_esp_callback_info;
   1839     0    stevel 
   1840     0    stevel static void
   1841     0    stevel esp_create_callback_thread(struct esp *esp)
   1842     0    stevel {
   1843     0    stevel 	ASSERT(mutex_owned(&esp_global_mutex));
   1844     0    stevel 	ASSERT(esp->e_callback_info == NULL);
   1845     0    stevel 
   1846     0    stevel 	if ((esp_n_esps++ % esp_n_esps_per_callback_thread) == 0) {
   1847     0    stevel 		kthread_t *t;
   1848     0    stevel 		struct callback_info  *cb_info;
   1849     0    stevel 
   1850     0    stevel 		/*
   1851     0    stevel 		 * create another thread
   1852     0    stevel 		 */
   1853     0    stevel 		IPRINTF1("create callback thread %d\n", esp_n_callback_threads);
   1854     0    stevel 
   1855     0    stevel 		cb_info = kmem_zalloc(sizeof (struct callback_info), KM_SLEEP);
   1856     0    stevel 
   1857     0    stevel 		cv_init(&cb_info->c_cv, NULL, CV_DRIVER, NULL);
   1858     0    stevel 		cv_init(&cb_info->c_cvd, NULL, CV_DRIVER, NULL);
   1859     0    stevel 
   1860     0    stevel 		mutex_init(&cb_info->c_mutex, NULL, MUTEX_DRIVER,
   1861     0    stevel 		    esp->e_iblock);
   1862     0    stevel 
   1863     0    stevel 		cb_info->c_id = esp_n_callback_threads++;
   1864     0    stevel 		if (last_esp_callback_info) {
   1865     0    stevel 			last_esp_callback_info->c_next = cb_info;
   1866     0    stevel 		}
   1867     0    stevel 		last_esp_callback_info = esp->e_callback_info = cb_info;
   1868     0    stevel 
   1869     0    stevel 		t = thread_create(NULL, 0, esp_callback, esp, 0, &p0,
   1870     0    stevel 		    TS_RUN, v.v_maxsyspri - 2);
   1871     0    stevel 
   1872     0    stevel 		cb_info->c_thread = t;
   1873     0    stevel 		cb_info->c_spawned = esp_max_spawn;
   1874     0    stevel 		cb_info->c_cb_now_qlen = esp_cb_now_qlen;
   1875     0    stevel 	} else {
   1876     0    stevel 		ASSERT(last_esp_callback_info != NULL);
   1877     0    stevel 		IPRINTF1("sharing callback thread %d\n",
   1878     0    stevel 		    last_esp_callback_info->c_id);
   1879     0    stevel 		esp->e_callback_info = last_esp_callback_info;
   1880     0    stevel 	}
   1881     0    stevel }
   1882     0    stevel 
   1883     0    stevel static void
   1884     0    stevel esp_destroy_callback_thread(struct esp *esp)
   1885     0    stevel {
   1886     0    stevel 	struct esp	*e;
   1887     0    stevel 
   1888     0    stevel 	ASSERT(esp->e_callback_info != NULL);
   1889     0    stevel 
   1890     0    stevel 	/*
   1891     0    stevel 	 * Remove callback
   1892     0    stevel 	 *
   1893     0    stevel 	 * We have to see if we are the last one using this cb thread
   1894     0    stevel 	 * before deleting it.
   1895     0    stevel 	 * Check the list for others referencing this cb.  We are off
   1896     0    stevel 	 * the list, so finding one other reference indicates shared.
   1897     0    stevel 	 */
   1898     0    stevel 	rw_enter(&esp_global_rwlock, RW_READER);
   1899     0    stevel 	for (e = esp_softc; e != (struct esp *)NULL; e = e->e_next) {
   1900     0    stevel 		if (e->e_callback_info == esp->e_callback_info) {
   1901     0    stevel 			break;
   1902     0    stevel 		}
   1903     0    stevel 	}
   1904     0    stevel 	rw_exit(&esp_global_rwlock);
   1905     0    stevel 
   1906     0    stevel 	/*
   1907     0    stevel 	 * we couldn't find another esp sharing this cb
   1908     0    stevel 	 */
   1909     0    stevel 	if (!e) {
   1910     0    stevel 		struct callback_info	*ci = esp->e_callback_info;
   1911     0    stevel 		struct callback_info	*tci, **pci;
   1912     0    stevel 
   1913     0    stevel 	IPRINTF2("esp_destroy_callback_thread: "
   1914  7656    Sherry 	    "killing callback 0x%p thread %d\n",
   1915  7656    Sherry 	    (void *)esp->e_callback_info, ci->c_id);
   1916     0    stevel 		mutex_enter(&ci->c_mutex);
   1917     0    stevel 		ci->c_exit = 1;			/* die */
   1918     0    stevel 
   1919     0    stevel 		IPRINTF2("esp_destroy_callback_thread: spawned %d max %d\n",
   1920     0    stevel 		    ci->c_spawned, esp_max_spawn);
   1921     0    stevel 		while (ci->c_spawned <= (uchar_t)esp_max_spawn) {
   1922     0    stevel 			IPRINTF1("esp_destroy_callback_thread:%p wakeup\n",
   1923     0    stevel 			    (void *)ci);
   1924     0    stevel 			cv_broadcast(&ci->c_cv);	/* might be snoozing */
   1925     0    stevel 			cv_wait(&ci->c_cvd, &ci->c_mutex);
   1926     0    stevel 		}
   1927     0    stevel 
   1928     0    stevel 		mutex_exit(&ci->c_mutex);
   1929     0    stevel 		IPRINTF("esp_destroy_callback_thread: all threads killed\n");
   1930     0    stevel 
   1931     0    stevel 		mutex_enter(&esp_global_mutex);
   1932     0    stevel 		for (pci = &last_esp_callback_info;
   1933     0    stevel 		    (tci = *pci) != NULL; pci = &tci->c_next) {
   1934     0    stevel 			if (tci == ci) {
   1935     0    stevel 				/* take it out of list */
   1936     0    stevel 				*pci = tci->c_next;
   1937     0    stevel 				/* destroy it */
   1938     0    stevel 				cv_destroy(&ci->c_cv);
   1939     0    stevel 				cv_destroy(&ci->c_cvd);
   1940     0    stevel 				mutex_destroy(&ci->c_mutex);
   1941     0    stevel 				kmem_free(ci, sizeof (struct callback_info));
   1942  7656    Sherry 				IPRINTF1("esp_destroy_callback_thread:%p"
   1943  7656    Sherry 				    " freed\n", (void *)ci);
   1944     0    stevel 				esp->e_callback_info = NULL;
   1945     0    stevel 				break;
   1946     0    stevel 			}
   1947     0    stevel 		}
   1948     0    stevel 	} else {
   1949     0    stevel 		mutex_enter(&esp_global_mutex);
   1950     0    stevel 		IPRINTF1("esp_destroy_callback_thread: callback 0x%p shared\n",
   1951     0    stevel 		    (void *)esp->e_callback_info);
   1952     0    stevel 	}
   1953     0    stevel 
   1954     0    stevel 	esp_n_esps--;
   1955     0    stevel 	mutex_exit(&esp_global_mutex);
   1956     0    stevel }
   1957     0    stevel 
   1958     0    stevel /*
   1959     0    stevel  * this is the function executed by the callback thread; it
   1960     0    stevel  * empties the callback queue by calling the completion function of each
   1961     0    stevel  * packet; note the release of the mutex before
   1962     0    stevel  * calling the completion function
   1963     0    stevel  * the cv_wait is at the end of the loop because by the time this thread
   1964     0    stevel  * comes alive, there is already work to do.
   1965     0    stevel  */
   1966     0    stevel void
   1967     0    stevel esp_wakeup_callback_thread(struct callback_info *cb_info)
   1968     0    stevel {
   1969     0    stevel 	struct esp_cmd *sp;
   1970     0    stevel 
   1971     0    stevel 	mutex_enter(&cb_info->c_mutex);
   1972     0    stevel 	if (cb_info->c_qlen) {
   1973     0    stevel 		/*
   1974     0    stevel 		 * callback now?
   1975     0    stevel 		 */
   1976     0    stevel 		if ((cb_info->c_qlen < cb_info->c_cb_now_qlen) || panicstr) {
   1977     0    stevel 			while (cb_info->c_qf) {
   1978     0    stevel 				sp = cb_info->c_qf;
   1979     0    stevel 				cb_info->c_qf = sp->cmd_forw;
   1980     0    stevel 				if (cb_info->c_qb == sp) {
   1981     0    stevel 					cb_info->c_qb = NULL;
   1982     0    stevel 				}
   1983     0    stevel 				cb_info->c_qlen--;
   1984     0    stevel 				mutex_exit(&cb_info->c_mutex);
   1985  6640       cth 				(*sp->cmd_pkt.pkt_comp)(&sp->cmd_pkt);
   1986     0    stevel 				mutex_enter(&cb_info->c_mutex);
   1987     0    stevel 			}
   1988     0    stevel 		/*
   1989     0    stevel 		 * if the queue is too long then do
   1990     0    stevel 		 * a wakeup for *all* callback threads
   1991     0    stevel 		 */
   1992     0    stevel 		} else if (cb_info->c_signal_needed) {
   1993     0    stevel 			cv_broadcast(&cb_info->c_cv);
   1994     0    stevel 		}
   1995     0    stevel 	}
   1996     0    stevel 	cb_info->c_signal_needed = 0;
   1997     0    stevel 	mutex_exit(&cb_info->c_mutex);
   1998     0    stevel }
   1999     0    stevel 
   2000     0    stevel /*
   2001     0    stevel  * Warlock has a problem when we use different locks
   2002     0    stevel  * on the same type of structure in different contexts.
   2003     0    stevel  * We use callb_cpr_t in both scsi_watch and esp_callback threads.
   2004     0    stevel  * we use different mutex's in different threads. And
   2005     0    stevel  * this is not acceptable to warlock. To avoid this
   2006     0    stevel  * problem we use the same name for the mutex in
   2007     0    stevel  * both scsi_watch & esp_callback. when __lock_lint is not defined
   2008     0    stevel  * esp_callback uses the mutex on the stack and in scsi_watch
   2009     0    stevel  * a static variable. But when __lock_lint is defined
   2010     0    stevel  * we make a mutex which is global in esp_callback and
   2011     0    stevel  * a external mutex for scsi_watch.
   2012     0    stevel  */
   2013     0    stevel #ifdef __lock_lint
   2014     0    stevel kmutex_t cpr_mutex;
   2015     0    stevel #endif
   2016     0    stevel 
   2017     0    stevel static void
   2018     0    stevel esp_callback(struct esp *esp)
   2019     0    stevel {
   2020     0    stevel 	struct esp_cmd *sp;
   2021     0    stevel 	struct callback_info *cb_info = esp->e_callback_info;
   2022     0    stevel 	int serviced = 0;
   2023     0    stevel 	int wakeups = 0;
   2024     0    stevel 	int id, load;
   2025     0    stevel 	int hiload = 0;
   2026     0    stevel 	int loload = 0;
   2027     0    stevel 	callb_cpr_t cpr_info;
   2028     0    stevel #ifndef	__lock_lint
   2029     0    stevel 	kmutex_t cpr_mutex;
   2030     0    stevel #endif
   2031     0    stevel 	int n = 0;
   2032     0    stevel 
   2033     0    stevel 	_NOTE(MUTEX_PROTECTS_DATA(cpr_mutex, cpr_info))
   2034     0    stevel 	_NOTE(NO_COMPETING_THREADS_NOW);
   2035     0    stevel 	mutex_init(&cpr_mutex, NULL, MUTEX_DRIVER, esp->e_iblock);
   2036     0    stevel 	CALLB_CPR_INIT(&cpr_info,
   2037  7656    Sherry 	    &cpr_mutex, callb_generic_cpr, "esp_callback");
   2038  2840  carlsonj #ifndef lint
   2039     0    stevel 	_NOTE(COMPETING_THREADS_NOW);
   2040  2840  carlsonj #endif
   2041     0    stevel 
   2042     0    stevel 	mutex_enter(&cb_info->c_mutex);
   2043     0    stevel 
   2044     0    stevel 	id = cb_info->c_count++;
   2045     0    stevel #ifdef ESP_PERF
   2046     0    stevel 	cmn_err(CE_CONT,
   2047     0    stevel 	    "esp cb%d.%d thread starting\n", cb_info->c_id, id);
   2048     0    stevel #endif
   2049     0    stevel 
   2050     0    stevel 	for (;;) {
   2051     0    stevel 		TRACE_0(TR_FAC_SCSI, TR_ESP_CALLBACK_START,
   2052  7656    Sherry 		    "esp_callback_start");
   2053     0    stevel 		while (cb_info->c_qf) {
   2054     0    stevel 			sp = cb_info->c_qf;
   2055     0    stevel 			cb_info->c_qf = sp->cmd_forw;
   2056     0    stevel 			if (cb_info->c_qb == sp) {
   2057     0    stevel 				cb_info->c_qb = NULL;
   2058     0    stevel 			}
   2059     0    stevel 			cb_info->c_qlen--;
   2060     0    stevel 			ASSERT(sp->cmd_pkt.pkt_comp != 0);
   2061     0    stevel 			serviced++;
   2062     0    stevel 			mutex_exit(&cb_info->c_mutex);
   2063  6640       cth 			(*sp->cmd_pkt.pkt_comp)(&sp->cmd_pkt);
   2064     0    stevel 			mutex_enter(&cb_info->c_mutex);
   2065     0    stevel 			n++;
   2066     0    stevel 		}
   2067     0    stevel 
   2068     0    stevel 		/*
   2069     0    stevel 		 * check load
   2070     0    stevel 		 * if the load is consistently too high, create another
   2071     0    stevel 		 * thread to help out
   2072     0    stevel 		 * if the load is consistently too low, exit thread
   2073     0    stevel 		 * If the load is so high that we never exit the
   2074     0    stevel 		 * above while loop then esp_n_esps_per_callback_thread is
   2075     0    stevel 		 * too high; we are not going to deal with that condition
   2076     0    stevel 		 * here
   2077     0    stevel 		 */
   2078     0    stevel 		if (wakeups) {
   2079     0    stevel 			load  = (serviced + wakeups - 1)/wakeups;
   2080     0    stevel 		} else {
   2081     0    stevel 			load = 0;
   2082     0    stevel 		}
   2083     0    stevel 
   2084     0    stevel 		if (cb_info->c_exit) {
   2085     0    stevel 			EPRINTF2("esp_callback: thread %d 0x%p exit set\n",
   2086     0    stevel 			    cb_info->c_id, (void *)cb_info);
   2087     0    stevel 			cb_info->c_spawned++;
   2088     0    stevel 			cv_broadcast(&cb_info->c_cvd);
   2089     0    stevel 			mutex_exit(&cb_info->c_mutex);
   2090     0    stevel 			break;
   2091     0    stevel 		} else if (load > esp_hi_cb_load) {
   2092     0    stevel 			/*
   2093     0    stevel 			 * load is too high
   2094     0    stevel 			 */
   2095     0    stevel 			if ((hiload++ > esp_cb_load_count) &&
   2096     0    stevel 			    (cb_info->c_spawned > 0)) {
   2097     0    stevel 				/*
   2098     0    stevel 				 * create another thread
   2099     0    stevel 				 */
   2100     0    stevel 				(void) thread_create(NULL, 0, esp_callback, esp,
   2101     0    stevel 				    0, &p0, TS_RUN, v.v_maxsyspri - 2);
   2102     0    stevel 				serviced = wakeups = 0;
   2103     0    stevel 				cb_info->c_spawned--;
   2104     0    stevel 				/*
   2105     0    stevel 				 * from now on do not allow immediate
   2106     0    stevel 				 * callback
   2107     0    stevel 				 */
   2108     0    stevel 				cb_info->c_cb_now_qlen = 0;
   2109     0    stevel 				hiload = loload = 0;
   2110     0    stevel 			}
   2111     0    stevel 		} else if (load < esp_lo_cb_load) {
   2112     0    stevel 			/*
   2113     0    stevel 			 * load is too low
   2114     0    stevel 			 */
   2115     0    stevel 			if (loload++ > esp_cb_load_count) {
   2116     0    stevel 				/*
   2117     0    stevel 				 * if this is not the first thread, exit
   2118     0    stevel 				 */
   2119     0    stevel 				if (id != 0) {
   2120     0    stevel 					cb_info->c_spawned++;
   2121     0    stevel 					mutex_exit(&cb_info->c_mutex);
   2122     0    stevel 					/*
   2123     0    stevel 					 * exit while loop and esp_callback
   2124     0    stevel 					 * function which destroys the
   2125     0    stevel 					 * thread
   2126     0    stevel 					 */
   2127     0    stevel 					break;
   2128     0    stevel 				} else {
   2129     0    stevel 					/*
   2130     0    stevel 					 * if only 1 thread left then set
   2131     0    stevel 					 * back cb_now_qlen
   2132     0    stevel 					 */
   2133     0    stevel 					if (cb_info->c_spawned ==
   2134     0    stevel 					    esp_max_spawn) {
   2135     0    stevel 						cb_info->c_cb_now_qlen =
   2136     0    stevel 						    esp_cb_now_qlen;
   2137     0    stevel 					}
   2138     0    stevel 				}
   2139     0    stevel 				hiload = loload = 0;
   2140     0    stevel 			}
   2141     0    stevel 		} else {
   2142     0    stevel 			/*
   2143     0    stevel 			 * always use deferred callback from now on
   2144     0    stevel 			 */
   2145     0    stevel 			cb_info->c_cb_now_qlen = 0;
   2146     0    stevel 			hiload = loload = 0;
   2147     0    stevel 		}
   2148     0    stevel 
   2149     0    stevel 		TRACE_1(TR_FAC_SCSI, TR_ESP_CALLBACK_END,
   2150  7656    Sherry 		    "esp_callback_end: (%d)", serviced);
   2151     0    stevel 
   2152     0    stevel 		/*
   2153     0    stevel 		 * reset serviced and wakeups; if these numbers get too high
   2154     0    stevel 		 * then we don't adjust to bursts very well
   2155     0    stevel 		 */
   2156     0    stevel 		if (serviced >= 20000) {
   2157     0    stevel #ifdef ESP_PERF
   2158     0    stevel 			cmn_err(CE_CONT,
   2159     0    stevel 	    "esp cb%d.%d: svced=%d, wkup=%d, ld=%d, spwn=%d, now_qlen=%d\n",
   2160     0    stevel 			    cb_info->c_id, id, serviced, wakeups,
   2161     0    stevel 			    load, cb_info->c_spawned,
   2162     0    stevel 			    cb_info->c_cb_now_qlen);
   2163     0    stevel #endif
   2164     0    stevel 			serviced = 0;
   2165     0    stevel 			wakeups = 0;
   2166     0    stevel 		}
   2167     0    stevel 
   2168     0    stevel 		mutex_enter(&cpr_mutex);
   2169     0    stevel 		CALLB_CPR_SAFE_BEGIN(&cpr_info);
   2170     0    stevel 		mutex_exit(&cpr_mutex);
   2171     0    stevel 
   2172     0    stevel 		cv_wait(&cb_info->c_cv, &cb_info->c_mutex);
   2173     0    stevel 
   2174     0    stevel 		mutex_exit(&cb_info->c_mutex);
   2175     0    stevel 		mutex_enter(&cpr_mutex);
   2176     0    stevel 		CALLB_CPR_SAFE_END(&cpr_info, &cpr_mutex);
   2177     0    stevel 		mutex_exit(&cpr_mutex);
   2178     0    stevel 		mutex_enter(&cb_info->c_mutex);
   2179     0    stevel 
   2180     0    stevel 		cb_info->c_signal_needed = 0;
   2181     0    stevel 		wakeups++;
   2182     0    stevel 	}
   2183     0    stevel 
   2184     0    stevel #ifdef ESP_PERF
   2185     0    stevel 	cmn_err(CE_CONT, "esp cb%d.%d exits\n", cb_info->c_id, id);
   2186     0    stevel #endif
   2187     0    stevel 	TRACE_1(TR_FAC_SCSI, TR_ESP_CALLBACK_END,
   2188  7656    Sherry 	    "esp_callback_end:  (%d)", n);
   2189     0    stevel #ifndef __lock_lint
   2190     0    stevel 	mutex_enter(&cpr_mutex);
   2191     0    stevel 	CALLB_CPR_EXIT(&cpr_info);
   2192     0    stevel #endif
   2193     0    stevel 	mutex_destroy(&cpr_mutex);
   2194     0    stevel 	thread_exit();
   2195     0    stevel }
   2196     0    stevel 
   2197     0    stevel /*
   2198     0    stevel  * Interface functions
   2199     0    stevel  *
   2200     0    stevel  * Visible to the external world via the transport structure.
   2201     0    stevel  *
   2202     0    stevel  * These functions have been grouped together to reduce cache misses.
   2203     0    stevel  *
   2204     0    stevel  */
   2205     0    stevel /*ARGSUSED*/
   2206     0    stevel static void
   2207     0    stevel esp_scsi_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt)
   2208     0    stevel {
   2209  6640       cth 	struct esp_cmd *cmd = (struct esp_cmd *)pkt->pkt_ha_private;
   2210     0    stevel 
   2211     0    stevel 	TRACE_0(TR_FAC_SCSI, TR_ESP_SCSI_IMPL_DMAFREE_START,
   2212     0    stevel 	    "esp_scsi_dmafree_start");
   2213     0    stevel 
   2214     0    stevel 	if (cmd->cmd_flags & CFLAG_DMAVALID) {
   2215     0    stevel 		/*
   2216     0    stevel 		 * Free the mapping.
   2217     0    stevel 		 */
   2218     0    stevel 		(void) ddi_dma_unbind_handle(cmd->cmd_dmahandle);
   2219     0    stevel 		cmd->cmd_flags ^= CFLAG_DMAVALID;
   2220     0    stevel 	}
   2221     0    stevel 	TRACE_0(TR_FAC_SCSI, TR_ESP_SCSI_IMPL_DMAFREE_END,
   2222     0    stevel 	    "esp_scsi_dmafree_end");
   2223     0    stevel }
   2224     0    stevel 
   2225     0    stevel 
   2226     0    stevel /*ARGSUSED*/
   2227     0    stevel static void
   2228     0    stevel esp_scsi_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt)
   2229     0    stevel {
   2230     0    stevel 	int i;
   2231  6640       cth 	struct esp_cmd *sp = (struct esp_cmd *)pkt->pkt_ha_private;
   2232     0    stevel 
   2233     0    stevel 	if (sp->cmd_flags & CFLAG_DMAVALID) {
   2234     0    stevel 		i = ddi_dma_sync(sp->cmd_dmahandle, 0, 0,
   2235  7656    Sherry 		    (sp->cmd_flags & CFLAG_DMASEND) ?
   2236  7656    Sherry 		    DDI_DMA_SYNC_FORDEV : DDI_DMA_SYNC_FORCPU);
   2237     0    stevel 		if (i != DDI_SUCCESS) {
   2238     0    stevel 			cmn_err(CE_WARN, "esp: sync pkt failed");
   2239     0    stevel 		}
   2240     0    stevel 	}
   2241     0    stevel }
   2242     0    stevel 
   2243     0    stevel 
   2244     0    stevel static struct scsi_pkt *
   2245     0    stevel esp_scsi_init_pkt(struct scsi_address *ap, struct scsi_pkt *pkt,
   2246     0    stevel 	struct buf *bp, int cmdlen, int statuslen, int tgtlen,
   2247     0    stevel 	int flags, int (*callback)(), caddr_t arg)
   2248     0    stevel {
   2249     0    stevel 	int kf;
   2250     0    stevel 	int failure = 0;
   2251     0    stevel 	struct esp_cmd *cmd, *new_cmd;
   2252     0    stevel 	struct esp *esp = ADDR2ESP(ap);
   2253     0    stevel 	int rval;
   2254     0    stevel 
   2255     0    stevel /* #define	ESP_TEST_EXTRN_ALLOC */
   2256     0    stevel #ifdef ESP_TEST_EXTRN_ALLOC
   2257     0    stevel 	cmdlen *= 4; statuslen *= 4; tgtlen *= 4;
   2258     0    stevel #endif
   2259     0    stevel 	/*
   2260     0    stevel 	 * If we've already allocated a pkt once,
   2261     0    stevel 	 * this request is for dma allocation only.
   2262     0    stevel 	 */
   2263     0    stevel 	if (pkt == NULL) {
   2264     0    stevel 		/*
   2265     0    stevel 		 * First step of esp_scsi_init_pkt:  pkt allocation
   2266     0    stevel 		 */
   2267     0    stevel 		TRACE_0(TR_FAC_SCSI, TR_ESP_SCSI_IMPL_PKTALLOC_START,
   2268     0    stevel 		    "esp_scsi_pktalloc_start");
   2269     0    stevel 
   2270     0    stevel 		failure = 0;
   2271     0    stevel 		kf = (callback == SLEEP_FUNC)? KM_SLEEP: KM_NOSLEEP;
   2272     0    stevel 
   2273     0    stevel 		cmd = kmem_cache_alloc(esp->e_kmem_cache, kf);
   2274     0    stevel 
   2275     0    stevel 		if (cmd) {
   2276     0    stevel 			ddi_dma_handle_t save_dma_handle;
   2277     0    stevel 
   2278     0    stevel 			save_dma_handle = cmd->cmd_dmahandle;
   2279  6640       cth 			bzero(cmd, ESP_CMD_SIZE);
   2280     0    stevel 			cmd->cmd_dmahandle = save_dma_handle;
   2281     0    stevel 
   2282     0    stevel 			cmd->cmd_pkt.pkt_scbp = (opaque_t)cmd->cmd_scb;
   2283     0    stevel 			cmd->cmd_cdblen_alloc = cmd->cmd_cdblen =
   2284  7656    Sherry 			    (uchar_t)cmdlen;
   2285     0    stevel 			cmd->cmd_scblen		= statuslen;
   2286     0    stevel 			cmd->cmd_privlen	= tgtlen;
   2287     0    stevel 			cmd->cmd_pkt.pkt_address = *ap;
   2288     0    stevel 
   2289     0    stevel 			cmd->cmd_pkt.pkt_cdbp = (opaque_t)&cmd->cmd_cdb;
   2290     0    stevel 			cmd->cmd_pkt.pkt_private = cmd->cmd_pkt_private;
   2291  6640       cth 			cmd->cmd_pkt.pkt_ha_private = (opaque_t)cmd;
   2292     0    stevel 		} else {
   2293     0    stevel 			failure++;
   2294     0    stevel 		}
   2295     0    stevel 
   2296     0    stevel 		if (failure || (cmdlen > sizeof (cmd->cmd_cdb)) ||
   2297     0    stevel 		    (tgtlen > PKT_PRIV_LEN) ||
   2298     0    stevel 		    (statuslen > EXTCMDS_STATUS_SIZE)) {
   2299     0    stevel 			if (failure == 0) {
   2300     0    stevel 				failure = esp_pkt_alloc_extern(esp, cmd,
   2301     0    stevel 				    cmdlen, tgtlen, statuslen, kf);
   2302     0    stevel 			}
   2303     0    stevel 			if (failure) {
   2304     0    stevel 				TRACE_0(TR_FAC_SCSI,
   2305  7656    Sherry 				    TR_ESP_SCSI_IMPL_PKTALLOC_END,
   2306  7656    Sherry 				    "esp_scsi_pktalloc_end");
   2307     0    stevel 				return (NULL);
   2308     0    stevel 			}
   2309     0    stevel 		}
   2310     0    stevel 
   2311     0    stevel 		new_cmd = cmd;
   2312     0    stevel 
   2313     0    stevel 		TRACE_0(TR_FAC_SCSI, TR_ESP_SCSI_IMPL_PKTALLOC_END,
   2314  7656    Sherry 		    "esp_scsi_pktalloc_end");
   2315     0    stevel 	} else {
   2316  6640       cth 		cmd = (struct esp_cmd *)pkt->pkt_ha_private;
   2317     0    stevel 		new_cmd = NULL;
   2318     0    stevel 	}
   2319     0    stevel 
   2320     0    stevel 
   2321     0    stevel 	/*
   2322     0    stevel 	 * Second step of esp_scsi_init_pkt:  dma allocation
   2323     0    stevel 	 * Set up dma info
   2324     0    stevel 	 */
   2325     0    stevel 	if (bp && bp->b_bcount) {
   2326     0    stevel 		uint_t cmd_flags, dma_flags;
   2327     0    stevel 		uint_t dmacookie_count;
   2328     0    stevel 
   2329     0    stevel 		TRACE_0(TR_FAC_SCSI, TR_SCSI_IMPL_DMAGET_START,
   2330     0    stevel 		    "esp_scsi_dmaget_start");
   2331     0    stevel 
   2332     0    stevel 		cmd_flags = cmd->cmd_flags;
   2333     0    stevel 
   2334     0    stevel 		if (bp->b_flags & B_READ) {
   2335     0    stevel 			cmd_flags &= ~CFLAG_DMASEND;
   2336     0    stevel 			dma_flags = DDI_DMA_READ | DDI_DMA_PARTIAL;
   2337     0    stevel 		} else {
   2338     0    stevel 			cmd_flags |= CFLAG_DMASEND;
   2339     0    stevel 			dma_flags = DDI_DMA_WRITE | DDI_DMA_PARTIAL;
   2340     0    stevel 		}
   2341     0    stevel 		if (flags & PKT_CONSISTENT) {
   2342     0    stevel 			cmd_flags |= CFLAG_CMDIOPB;
   2343     0    stevel 			dma_flags |= DDI_DMA_CONSISTENT;
   2344     0    stevel 		}
   2345     0    stevel 
   2346     0    stevel 		ASSERT(cmd->cmd_dmahandle != NULL);
   2347     0    stevel 
   2348     0    stevel 		rval = ddi_dma_buf_bind_handle(cmd->cmd_dmahandle, bp,
   2349  7656    Sherry 		    dma_flags, callback, arg, &cmd->cmd_dmacookie,
   2350  7656    Sherry 		    &dmacookie_count);
   2351     0    stevel dma_failure:
   2352     0    stevel 		if (rval && rval != DDI_DMA_PARTIAL_MAP) {
   2353     0    stevel 			switch (rval) {
   2354     0    stevel 			case DDI_DMA_NORESOURCES:
   2355     0    stevel 				bioerror(bp, 0);
   2356     0    stevel 				break;
   2357     0    stevel 			case DDI_DMA_BADATTR:
   2358     0    stevel 			case DDI_DMA_NOMAPPING:
   2359     0    stevel 				bioerror(bp, EFAULT);
   2360     0    stevel 				break;
   2361     0    stevel 			case DDI_DMA_TOOBIG:
   2362     0    stevel 			default:
   2363     0    stevel 				bioerror(bp, EINVAL);
   2364     0    stevel 				break;
   2365     0    stevel 			}
   2366     0    stevel 			cmd->cmd_flags = cmd_flags & ~CFLAG_DMAVALID;
   2367     0    stevel 			if (new_cmd) {
   2368  6640       cth 				esp_scsi_destroy_pkt(ap, &new_cmd->cmd_pkt);
   2369     0    stevel 			}
   2370     0    stevel 			TRACE_0(TR_FAC_SCSI, TR_SCSI_IMPL_DMAGET_END,
   2371  7656    Sherry 			    "esp_scsi_dmaget_end");
   2372     0    stevel 			return ((struct scsi_pkt *)NULL);
   2373     0    stevel 		}
   2374     0    stevel 		ASSERT(dmacookie_count == 1);
   2375     0    stevel 		cmd->cmd_dmacount = bp->b_bcount;
   2376     0    stevel 		cmd->cmd_flags = cmd_flags | CFLAG_DMAVALID;
   2377     0    stevel 
   2378     0    stevel 		ASSERT(cmd->cmd_dmahandle != NULL);
   2379     0    stevel 		TRACE_0(TR_FAC_SCSI, TR_SCSI_IMPL_DMAGET_END,
   2380     0    stevel 		    "esp_scsi_dmaget_end");
   2381     0    stevel 	}
   2382     0    stevel 
   2383  6640       cth 	return (&cmd->cmd_pkt);
   2384     0    stevel }
   2385     0    stevel 
   2386     0    stevel /*
   2387     0    stevel  * allocate and deallocate external space (ie. not part of esp_cmd) for
   2388     0    stevel  * non-standard length cdb, pkt_private, status areas
   2389     0    stevel  */
   2390     0    stevel /* ARGSUSED */
   2391     0    stevel static int
   2392     0    stevel esp_pkt_alloc_extern(struct esp *esp, struct esp_cmd *sp,
   2393     0    stevel     int cmdlen, int tgtlen, int statuslen, int kf)
   2394     0    stevel {
   2395     0    stevel 	caddr_t cdbp, scbp, tgt;
   2396     0    stevel 	int failure = 0;
   2397     0    stevel 
   2398     0    stevel 	tgt = cdbp = scbp = NULL;
   2399     0    stevel 	if (cmdlen > sizeof (sp->cmd_cdb)) {
   2400     0    stevel 		if ((cdbp = kmem_zalloc((size_t)cmdlen, kf)) == NULL) {
   2401     0    stevel 			failure++;
   2402     0    stevel 		} else {
   2403     0    stevel 			sp->cmd_pkt.pkt_cdbp = (opaque_t)cdbp;
   2404     0    stevel 			sp->cmd_flags |= CFLAG_CDBEXTERN;
   2405     0    stevel 		}
   2406     0    stevel 	}
   2407     0    stevel 	if (tgtlen > PKT_PRIV_LEN) {
   2408     0    stevel 		if ((tgt = kmem_zalloc(tgtlen, kf)) == NULL) {
   2409     0    stevel 			failure++;
   2410     0    stevel 		} else {
   2411     0    stevel 			sp->cmd_flags |= CFLAG_PRIVEXTERN;
   2412     0    stevel 			sp->cmd_pkt.pkt_private = tgt;
   2413     0    stevel 		}
   2414     0    stevel 	}
   2415     0    stevel 	if (statuslen > EXTCMDS_STATUS_SIZE) {
   2416     0    stevel 		if ((scbp = kmem_zalloc((size_t)statuslen, kf)) == NULL) {
   2417     0    stevel 			failure++;
   2418     0    stevel 		} else {
   2419     0    stevel 			sp->cmd_flags |= CFLAG_SCBEXTERN;
   2420     0    stevel 			sp->cmd_pkt.pkt_scbp = (opaque_t)scbp;
   2421     0    stevel 		}
   2422     0    stevel 	}
   2423     0    stevel 	if (failure) {
   2424     0    stevel 		esp_pkt_destroy_extern(esp, sp);
   2425     0    stevel 	}
   2426     0    stevel 	return (failure);
   2427     0    stevel }
   2428     0    stevel 
   2429     0    stevel /* ARGSUSED */
   2430     0    stevel static void
   2431     0    stevel esp_scsi_destroy_pkt(struct scsi_address *ap, struct scsi_pkt *pkt)
   2432     0    stevel {
   2433  6640       cth 	struct esp_cmd *sp = (struct esp_cmd *)pkt->pkt_ha_private;
   2434     0    stevel 	struct esp *esp = ADDR2ESP(ap);
   2435     0    stevel 
   2436     0    stevel 	/*
   2437     0    stevel 	 * esp_scsi_dmafree inline to speed things up
   2438     0    stevel 	 */
   2439     0    stevel 	TRACE_0(TR_FAC_SCSI, TR_ESP_SCSI_IMPL_DMAFREE_START,
   2440     0    stevel 	    "esp_scsi_dmafree_start");
   2441     0    stevel 
   2442     0    stevel 	if (sp->cmd_flags & CFLAG_DMAVALID) {
   2443     0    stevel 		/*
   2444     0    stevel 		 * Free the mapping.
   2445     0    stevel 		 */
   2446     0    stevel 		(void) ddi_dma_unbind_handle(sp->cmd_dmahandle);
   2447     0    stevel 		sp->cmd_flags ^= CFLAG_DMAVALID;
   2448     0    stevel 	}
   2449     0    stevel 	TRACE_0(TR_FAC_SCSI, TR_ESP_SCSI_IMPL_DMAFREE_END,
   2450     0    stevel 	    "esp_scsi_dmafree_end");
   2451     0    stevel 
   2452     0    stevel 	TRACE_0(TR_FAC_SCSI, TR_ESP_SCSI_IMPL_PKTFREE_START,
   2453     0    stevel 	    "esp_scsi_pktfree_start");
   2454     0    stevel 
   2455     0    stevel 	/*
   2456     0    stevel 	 * first test the most common case
   2457     0    stevel 	 */
   2458     0    stevel 	if ((sp->cmd_flags &
   2459     0    stevel 	    (CFLAG_FREE | CFLAG_CDBEXTERN | CFLAG_PRIVEXTERN |
   2460     0    stevel 	    CFLAG_SCBEXTERN)) == 0) {
   2461     0    stevel 		sp->cmd_flags = CFLAG_FREE;
   2462     0    stevel 		kmem_cache_free(esp->e_kmem_cache, (void *)sp);
   2463     0    stevel 	} else {
   2464     0    stevel 		esp_pkt_destroy_extern(esp, sp);
   2465     0    stevel 	}
   2466     0    stevel 
   2467     0    stevel 	TRACE_0(TR_FAC_SCSI, TR_ESP_SCSI_IMPL_PKTFREE_END,
   2468     0    stevel 	    "esp_scsi_pktfree_end");
   2469     0    stevel }
   2470     0    stevel 
   2471     0    stevel /* ARGSUSED */
   2472     0    stevel static void
   2473     0    stevel esp_pkt_destroy_extern(struct esp *esp, struct esp_cmd *sp)
   2474     0    stevel {
   2475     0    stevel 	if (sp->cmd_flags & CFLAG_FREE) {
   2476     0    stevel 		panic("esp_pkt_destroy(_extern): freeing free packet");
   2477     0    stevel 		_NOTE(NOT_REACHED)
   2478     0    stevel 		/*NOTREACHED*/
   2479     0    stevel 	}
   2480     0    stevel 	if (sp->cmd_flags & CFLAG_CDBEXTERN) {
   2481     0    stevel 		kmem_free((caddr_t)sp->cmd_pkt.pkt_cdbp,
   2482     0    stevel 		    (size_t)sp->cmd_cdblen_alloc);
   2483     0    stevel 	}
   2484     0    stevel 	if (sp->cmd_flags & CFLAG_SCBEXTERN) {
   2485     0    stevel 		kmem_free((caddr_t)sp->cmd_pkt.pkt_scbp,
   2486     0    stevel 		    (size_t)sp->cmd_scblen);
   2487     0    stevel 	}
   2488     0    stevel 	if (sp->cmd_flags & CFLAG_PRIVEXTERN) {
   2489     0    stevel 		kmem_free((caddr_t)sp->cmd_pkt.pkt_private,
   2490     0    stevel 		    (size_t)sp->cmd_privlen);
   2491     0    stevel 	}
   2492     0    stevel 	sp->cmd_flags = CFLAG_FREE;
   2493     0    stevel 	kmem_cache_free(esp->e_kmem_cache, (void *)sp);
   2494     0    stevel }
   2495     0    stevel 
   2496     0    stevel /*
   2497     0    stevel  * kmem cache constructor and destructor.
   2498     0    stevel  * When constructing, we bzero the cmd and allocate a handle
   2499     0    stevel  * When destructing, just free the dma handle
   2500     0    stevel  */
   2501     0    stevel static int
   2502     0    stevel esp_kmem_cache_constructor(void *buf, void *cdrarg, int kmflags)
   2503     0    stevel {
   2504     0    stevel 	struct esp_cmd *cmd = buf;
   2505     0    stevel 	struct esp *esp = cdrarg;
   2506     0    stevel 	int  (*callback)(caddr_t) = (kmflags == KM_SLEEP) ? DDI_DMA_SLEEP:
   2507  7656    Sherry 	    DDI_DMA_DONTWAIT;
   2508     0    stevel 
   2509  6640       cth 	bzero(cmd, ESP_CMD_SIZE);
   2510     0    stevel 
   2511     0    stevel 	if (ddi_dma_alloc_handle(esp->e_dev,
   2512     0    stevel 	    esp->e_dma_attr, callback, NULL,
   2513     0    stevel 	    &cmd->cmd_dmahandle) != 0) {
   2514     0    stevel 		return (-1);
   2515     0    stevel 	}
   2516     0    stevel 	return (0);
   2517     0    stevel }
   2518     0    stevel 
   2519     0    stevel /* ARGSUSED */
   2520     0    stevel static void
   2521     0    stevel esp_kmem_cache_destructor(void *buf, void *cdrarg)
   2522     0    stevel {
   2523     0    stevel 	struct esp_cmd *cmd = buf;
   2524     0    stevel 	if (cmd->cmd_dmahandle) {
   2525     0    stevel 		ddi_dma_free_handle(&cmd->cmd_dmahandle);
   2526     0    stevel 	}
   2527     0    stevel }
   2528     0    stevel 
   2529     0    stevel /*
   2530     0    stevel  * esp_prepare_pkt():
   2531     0    stevel  * initialize the packet and do some sanity checks
   2532     0    stevel  * before taking the lock
   2533     0    stevel  */
   2534     0    stevel static int
   2535     0    stevel esp_prepare_pkt(struct esp *esp, struct esp_cmd *sp)
   2536     0    stevel {
   2537     0    stevel 	int size, cmdlen;
   2538     0    stevel 
   2539     0    stevel #ifdef ESPDEBUG
   2540     0    stevel 	if (sp->cmd_flags & CFLAG_DMAVALID) {
   2541     0    stevel 		uint32_t maxdma;
   2542     0    stevel 		switch (ESP_DMAGA_REV(esp)) {
   2543     0    stevel 		default:
   2544     0    stevel 		case DMA_REV1:
   2545     0    stevel 		case DMA_REV2:
   2546     0    stevel 		case ESC1_REV1:
   2547     0    stevel 			maxdma = 1 << 24;
   2548     0    stevel 			break;
   2549     0    stevel 		case DMA_REV3:
   2550     0    stevel 			maxdma = 1 << 30; /* be reasonable - 2gb is enuff */
   2551     0    stevel 			break;
   2552     0    stevel 		}
   2553     0    stevel 		if (sp->cmd_dmacount >= maxdma) {
   2554     0    stevel 			IPRINTF("prepare pkt: dma count too high\n");
   2555     0    stevel 			return (TRAN_BADPKT);
   2556     0    stevel 		}
   2557     0    stevel 	}
   2558     0    stevel 	ASSERT((sp->cmd_flags & CFLAG_IN_TRANSPORT) == 0);
   2559     0    stevel #endif
   2560     0    stevel 
   2561     0    stevel 	/*
   2562     0    stevel 	 * Reinitialize some fields that need it; the packet may
   2563     0    stevel 	 * have been resubmitted
   2564     0    stevel 	 */
   2565     0    stevel 	sp->cmd_pkt.pkt_reason = CMD_CMPLT;
   2566     0    stevel 	sp->cmd_pkt.pkt_state = 0;
   2567     0    stevel 	sp->cmd_pkt.pkt_statistics = 0;
   2568     0    stevel 	sp->cmd_pkt.pkt_resid = 0;
   2569     0    stevel 	sp->cmd_age = 0;
   2570     0    stevel 
   2571     0    stevel 	/*
   2572     0    stevel 	 * Copy the cdb and scb pointers to the esp_cmd area as we
   2573     0    stevel 	 * modify these parameters.
   2574     0    stevel 	 */
   2575     0    stevel 	sp->cmd_cdbp = sp->cmd_pkt.pkt_cdbp;
   2576     0    stevel 	sp->cmd_scbp = sp->cmd_pkt.pkt_scbp;
   2577     0    stevel 	*(sp->cmd_scbp) = 0;
   2578     0    stevel 	sp->cmd_flags &= ~CFLAG_TRANFLAG;
   2579     0    stevel 	sp->cmd_flags |= CFLAG_IN_TRANSPORT;
   2580     0    stevel 
   2581     0    stevel 	if (sp->cmd_pkt.pkt_time != 0) {
   2582     0    stevel 		sp->cmd_flags |= CFLAG_WATCH;
   2583     0    stevel 	}
   2584     0    stevel 	sp->cmd_timeout = sp->cmd_pkt.pkt_time; /* Set timeout */
   2585     0    stevel 
   2586     0    stevel 	if (sp->cmd_flags & CFLAG_DMAVALID) {
   2587     0    stevel 		sp->cmd_pkt.pkt_resid = sp->cmd_dmacount;
   2588     0    stevel 
   2589     0    stevel 		/*
   2590     0    stevel 		 * if the pkt was resubmitted then the
   2591     0    stevel 		 * window may be at the wrong number
   2592     0    stevel 		 */
   2593     0    stevel 		if (sp->cmd_cur_win) {
   2594     0    stevel 			sp->cmd_cur_win = 0;
   2595     0    stevel 			if (esp_set_new_window(esp, sp)) {
   2596     0    stevel 				IPRINTF("cannot reset window\n");
   2597     0    stevel 				return (TRAN_BADPKT);
   2598     0    stevel 			}
   2599     0    stevel 		}
   2600     0    stevel 		sp->cmd_saved_cur_addr =
   2601     0    stevel 		    sp->cmd_cur_addr = sp->cmd_dmacookie.dmac_address;
   2602     0    stevel 
   2603     0    stevel 		/*
   2604     0    stevel 		 * the common case is just one window, we worry
   2605     0    stevel 		 * about multiple windows when we run out of the
   2606     0    stevel 		 * current window
   2607     0    stevel 		 */
   2608     0    stevel 		sp->cmd_nwin = sp->cmd_saved_win = 0;
   2609     0    stevel 		sp->cmd_data_count = sp->cmd_saved_data_count = 0;
   2610     0    stevel 
   2611     0    stevel 		if ((sp->cmd_flags & (CFLAG_CMDIOPB | CFLAG_DMASEND)) ==
   2612  7656    Sherry 		    (CFLAG_CMDIOPB | CFLAG_DMASEND)) {
   2613     0    stevel 			(void) ddi_dma_sync(sp->cmd_dmahandle, 0, (uint_t)-1,
   2614     0    stevel 			    DDI_DMA_SYNC_FORDEV);
   2615     0    stevel 		}
   2616     0    stevel 	}
   2617     0    stevel 
   2618     0    stevel 	/*
   2619     0    stevel 	 * The ESP chip only will automatically send 6, 10 or 12 byte
   2620     0    stevel 	 * cdb's.  Setting cmd_cdblen to a non-zero value signals this.
   2621     0    stevel 	 * Otherwise, we have to do it manually and send them out one at
   2622     0    stevel 	 * a time.  Setting cmd_cdblen to zero signals this condition.
   2623     0    stevel 	 * For non-group{0,1,2,5} cmds we use the cmdlen specified by
   2624     0    stevel 	 * the target driver if it is 6, 10, or 12.
   2625     0    stevel 	 */
   2626     0    stevel 	size = scsi_cdb_size[CDB_GROUPID(sp->cmd_cdbp[0])];
   2627     0    stevel 	cmdlen = sp->cmd_cdblen;
   2628     0    stevel 	if (size == 0 && (cmdlen != CDB_GROUP0 &&
   2629     0    stevel 	    cmdlen != CDB_GROUP1 && cmdlen != CDB_GROUP5)) {
   2630     0    stevel 		sp->cmd_cdblen = 0;
   2631     0    stevel 		IPRINTF("cdblen = 0\n");
   2632     0    stevel 	} else if (size != 0) {
   2633     0    stevel 		sp->cmd_cdblen = (uchar_t)size;
   2634     0    stevel 	}
   2635     0    stevel 
   2636     0    stevel 
   2637     0    stevel #ifdef ESP_TEST_UNTAGGED
   2638     0    stevel #ifndef __lock_lint
   2639     0    stevel 	if (esp_test_untagged > 0) {
   2640     0    stevel 		if (TAGGED(Tgt(sp))) {
   2641     0    stevel 			int slot = Tgt(sp) * NLUNS_PER_TARGET | Lun(sp);
   2642     0    stevel 			sp->cmd_pkt.pkt_flags &= ~FLAG_TAGMASK;
   2643     0    stevel 			sp->cmd_pkt.pkt_flags &= ~FLAG_NODISCON;
   2644     0    stevel 			sp->cmd_pkt.pkt_flags |= 0x80000000;
   2645     0    stevel 			esplog(esp, CE_NOTE,
   2646  7656    Sherry 			    "starting untagged cmd, target=%d,"
   2647  7656    Sherry 			    " tcmds=%d, sp=0x%p, throttle=%d\n",
   2648  7656    Sherry 			    Tgt(sp), esp->e_tcmds[slot], (void *)sp,
   2649  7656    Sherry 			    esp->e_throttle[slot]);
   2650     0    stevel 			esp_test_untagged = -10;
   2651     0    stevel 		}
   2652     0    stevel 	}
   2653     0    stevel #endif
   2654     0    stevel #endif
   2655     0    stevel 
   2656     0    stevel 
   2657     0    stevel #ifdef ESPDEBUG
   2658     0    stevel 	if (NOTAG(Tgt(sp)) && (sp->cmd_pkt.pkt_flags & FLAG_TAGMASK)) {
   2659     0    stevel 		IPRINTF2("tagged packet for non-tagged target %d.%d\n",
   2660     0    stevel 		    Tgt(sp), Lun(sp));
   2661     0    stevel 		sp->cmd_pkt.pkt_flags &= ~FLAG_TAGMASK;
   2662     0    stevel 	}
   2663     0    stevel 
   2664     0    stevel 	/*
   2665     0    stevel 	 * the scsa spec states that it is an error to have no
   2666     0    stevel 	 * completion function when FLAG_NOINTR is not set
   2667     0    stevel 	 */
   2668     0    stevel 	if ((sp->cmd_pkt.pkt_comp == NULL) &&
   2669     0    stevel 	    ((sp->cmd_pkt.pkt_flags & FLAG_NOINTR) == 0)) {
   2670     0    stevel 		IPRINTF("intr packet with pkt_comp == 0\n");
   2671     0    stevel 		sp->cmd_flags &= ~CFLAG_IN_TRANSPORT;
   2672     0    stevel 		TRACE_0(TR_FAC_SCSI, TR_ESP_PREPARE_PKT_TRAN_BADPKT_END,
   2673     0    stevel 		    "esp_prepare_pkt_end (tran_badpkt)");
   2674     0    stevel 		return (TRAN_BADPKT);
   2675     0    stevel 	}
   2676     0    stevel #endif /* ESPDEBUG */
   2677     0    stevel 
   2678     0    stevel 	if (((esp->e_target_scsi_options[Tgt(sp)] & SCSI_OPTIONS_DR) == 0) ||
   2679     0    stevel 	    (esp->e_nodisc & (Tgt(sp) << 1)))  {
   2680     0    stevel 		/*
   2681     0    stevel 		 * no need to reset tag bits since tag queuing will
   2682     0    stevel 		 * not be enabled if disconnects are disabled
   2683     0    stevel 		 */
   2684     0    stevel 		sp->cmd_pkt.pkt_flags |= FLAG_NODISCON;
   2685     0    stevel 	}
   2686     0    stevel 
   2687     0    stevel 	sp->cmd_flags |= CFLAG_PREPARED;
   2688     0    stevel 
   2689     0    stevel 	ASSERT(sp->cmd_flags & CFLAG_IN_TRANSPORT);
   2690     0    stevel 
   2691     0    stevel 	TRACE_0(TR_FAC_SCSI, TR_ESP_PREPARE_PKT_TRAN_ACCEPT_END,
   2692     0    stevel 	    "esp_prepare_pkt_end (tran_accept)");
   2693     0    stevel 	return (TRAN_ACCEPT);
   2694     0    stevel }
   2695     0    stevel 
   2696     0    stevel /*
   2697     0    stevel  * when the startQ is emptied, we cannot tolerate TRAN_BUSY.
   2698     0    stevel  * if the queue is not empty when the next request comes in esp_start
   2699     0    stevel  * the order of requests is not preserved
   2700     0    stevel  * if a transport busy condition occurs, we queue up startQ pkts in the ready
   2701     0    stevel  * queue; the disadvantage is that the target driver has initially
   2702     0    stevel  * the wrong value (too high) for the target queue but eventually
   2703     0    stevel  * it should get it right; there is not really a big performance hit here
   2704     0    stevel  */
   2705     0    stevel static void
   2706     0    stevel esp_empty_startQ(struct esp *esp)
   2707     0    stevel {
   2708     0    stevel 	struct esp_cmd *sp;
   2709     0    stevel 	int rval;
   2710     0    stevel 
   2711     0    stevel 	ASSERT(mutex_owned(&esp->e_startQ_mutex));
   2712     0    stevel 
   2713     0    stevel 	TRACE_0(TR_FAC_SCSI, TR_ESP_EMPTY_STARTQ_START,
   2714     0    stevel 	    "esp_empty_startQ_start");
   2715     0    stevel 	while (esp->e_startf) {
   2716     0    stevel 		sp = esp->e_startf;
   2717     0    stevel 		esp->e_startf = sp->cmd_forw;
   2718     0    stevel 		if (esp->e_startb == sp) {
   2719     0    stevel 			esp->e_startb = NULL;
   2720     0    stevel 		}
   2721     0    stevel 		mutex_exit(&esp->e_startQ_mutex);
   2722     0    stevel 		rval = _esp_start(esp, sp, NO_TRAN_BUSY);
   2723     0    stevel 
   2724     0    stevel 		/*
   2725     0    stevel 		 * the request should have been accepted but if not,
   2726     0    stevel 		 * put it back on the head of startQ
   2727     0    stevel 		 * If the  packet was rejected for other reasons then
   2728     0    stevel 		 * complete it here
   2729     0    stevel 		 */
   2730     0    stevel 		if (rval != TRAN_ACCEPT) {
   2731     0    stevel 			if (rval != TRAN_BUSY) {
   2732     0    stevel 				if (sp->cmd_pkt.pkt_reason == CMD_CMPLT) {
   2733     0    stevel 					sp->cmd_pkt.pkt_reason = CMD_TRAN_ERR;
   2734     0    stevel 				}
   2735     0    stevel 				if (sp->cmd_pkt.pkt_comp) {
   2736     0    stevel 					mutex_exit(ESP_MUTEX);
   2737  6640       cth 					(*sp->cmd_pkt.pkt_comp)(&sp->cmd_pkt);
   2738     0    stevel 					mutex_enter(ESP_MUTEX);
   2739     0    stevel 				}
   2740     0    stevel 				mutex_enter(&esp->e_startQ_mutex);
   2741     0    stevel 				continue;
   2742     0    stevel 			}
   2743     0    stevel 			mutex_enter(&esp->e_startQ_mutex);
   2744     0    stevel 			if (esp->e_startf == NULL) {
   2745     0    stevel 				esp->e_startb = esp->e_startf = sp;
   2746     0    stevel 				sp->cmd_forw = NULL;
   2747     0    stevel 			} else {
   2748     0    stevel 				sp->cmd_forw = esp->e_startf;
   2749     0    stevel 				esp->e_startf = sp;
   2750     0    stevel 			}
   2751     0    stevel 			break;
   2752     0    stevel 		}
   2753     0    stevel 		mutex_enter(&esp->e_startQ_mutex);
   2754     0    stevel 	}
   2755     0    stevel 	TRACE_0(TR_FAC_SCSI, TR_ESP_EMPTY_STARTQ_END,
   2756     0    stevel 	    "esp_empty_startQ_end");
   2757     0    stevel }
   2758     0    stevel 
   2759     0    stevel /*
   2760     0    stevel  * emptying the startQ just before releasing ESP_MUTEX is
   2761     0    stevel  * tricky; there is a small window where we checked the
   2762     0    stevel  * startQ and emptied it but possibly due to a
   2763     0    stevel  * a kernel preemption, we don't release the ESP_MUTEX soon enough and
   2764     0    stevel  * esp_start() will not be able to get the ESP_MUTEX and exit
   2765     0    stevel  * The next cmd coming in or the next interrupt or esp_watch() would eventually
   2766     0    stevel  * empty the startQ, though
   2767     0    stevel  * Therefore, by releasing the ESP_MUTEX before releasing the startQ mutex,
   2768     0    stevel  * we prevent that esp_start() fills the startQ and then cannot get the
   2769     0    stevel  * ESP_MUTEX for emptying the startQ
   2770     0    stevel  *
   2771     0    stevel  * esp_start() - accept a esp_cmd
   2772     0    stevel  */
   2773     0    stevel static int
   2774     0    stevel esp_start(struct scsi_address *ap, struct scsi_pkt *pkt)
   2775     0    stevel {
   2776  6640       cth 	struct esp_cmd *sp = (struct esp_cmd *)pkt->pkt_ha_private;
   2777     0    stevel 	struct esp *esp = ADDR2ESP(ap);
   2778     0    stevel 	int rval;
   2779     0    stevel 
   2780     0    stevel 	TRACE_0(TR_FAC_SCSI, TR_ESP_START_START, "esp_start_start");
   2781     0    stevel 
   2782     0    stevel #ifdef ESP_PERF
   2783     0    stevel 	esp_ncmds_per_esp[CNUM]++;
   2784     0    stevel #endif
   2785     0    stevel #ifdef ESP_CHECK
   2786     0    stevel 	mutex_enter(ESP_MUTEX);
   2787     0    stevel 	esp_check_in_transport(esp, sp);
   2788     0    stevel 	mutex_exit(ESP_MUTEX);
   2789     0    stevel #endif
   2790     0    stevel 
   2791     0    stevel 	/*
   2792     0    stevel 	 * prepare packet before taking the mutex
   2793     0    stevel 	 */
   2794     0    stevel 	rval = esp_prepare_pkt(esp, sp);
   2795     0    stevel 	if (rval != TRAN_ACCEPT) {
   2796     0    stevel 		TRACE_0(TR_FAC_SCSI, TR_ESP_START_PREPARE_PKT_END,
   2797     0    stevel 		    "esp_start_end (prepare_pkt)");
   2798     0    stevel 		return (rval);
   2799     0    stevel 	}
   2800     0    stevel 
   2801     0    stevel 	/*
   2802     0    stevel 	 * esp mutex can be held for a long time; therefore, if mutex is
   2803     0    stevel 	 * held, we queue the packet in a startQ; we now need to check
   2804     0    stevel 	 * the startQ on every mutex_exit(ESP_MUTEX);
   2805     0    stevel 	 * Don't put NOINTR cmds in startQ! Proxy cmds go directly
   2806     0    stevel 	 * to _esp_start
   2807     0    stevel 	 */
   2808     0    stevel 	if (sp->cmd_pkt.pkt_flags & FLAG_NOINTR) {
   2809     0    stevel 		mutex_enter(ESP_MUTEX);
   2810     0    stevel 	} else {
   2811     0    stevel 		mutex_enter(&esp->e_startQ_mutex);
   2812     0    stevel 		if (esp->e_startf || (mutex_tryenter(ESP_MUTEX) == 0)) {
   2813     0    stevel 			if (esp->e_startf == NULL) {
   2814     0    stevel 				esp->e_startb = esp->e_startf = sp;
   2815     0    stevel 				sp->cmd_forw = NULL;
   2816     0    stevel 			} else {
   2817     0    stevel 				struct esp_cmd *dp = esp->e_startb;
   2818     0    stevel 				dp->cmd_forw = esp->e_startb = sp;
   2819     0    stevel 				sp->cmd_forw = NULL;
   2820     0    stevel 			}
   2821     0    stevel 			/*
   2822     0    stevel 			 * check again the ESP_MUTEX
   2823     0    stevel 			 */
   2824     0    stevel 			if (mutex_tryenter(ESP_MUTEX)) {
   2825     0    stevel 				esp_empty_startQ(esp);
   2826     0    stevel 				mutex_exit(ESP_MUTEX);
   2827     0    stevel 			}
   2828     0    stevel 			mutex_exit(&esp->e_startQ_mutex);
   2829     0    stevel 			goto done;
   2830     0    stevel 		}
   2831     0    stevel 		mutex_exit(&esp->e_startQ_mutex);
   2832     0    stevel 	}
   2833     0    stevel 
   2834     0    stevel 	rval = _esp_start(esp, sp, TRAN_BUSY_OK);
   2835     0    stevel 	ESP_CHECK_STARTQ_AND_ESP_MUTEX_EXIT(esp);
   2836     0    stevel 	ESP_WAKEUP_CALLBACK_THREAD(esp);
   2837     0    stevel done:
   2838     0    stevel 	TRACE_1(TR_FAC_SCSI, TR_ESP_START_END, "esp_start_end: esp 0x%p",
   2839     0    stevel 	    (void *)esp);
   2840     0    stevel 	return (rval);
   2841     0    stevel }
   2842     0    stevel 
   2843     0    stevel /*
   2844     0    stevel  * _esp_start()
   2845     0    stevel  * the flag argument is to force _esp_start to accept the pkt; pkts that were
   2846     0    stevel  * on startQ cannot be bounced back with TRAN_BUSY
   2847     0    stevel  */
   2848     0    stevel static int
   2849     0    stevel _esp_start(struct esp *esp, struct esp_cmd *sp, int flag)
   2850     0    stevel {
   2851     0    stevel 	short slot;
   2852     0    stevel 	int target = Tgt(sp);
   2853     0    stevel 	int lun = Lun(sp);
   2854     0    stevel 	int rval = TRAN_ACCEPT;
   2855     0    stevel 
   2856     0    stevel 	TRACE_0(TR_FAC_SCSI, TR__ESP_START_START, "_esp_start_start");
   2857     0    stevel 	slot =	(target * NLUNS_PER_TARGET) | lun;
   2858     0    stevel 	ASSERT(mutex_owned(ESP_MUTEX));
   2859     0    stevel 	ASSERT(esp->e_ncmds >= esp->e_ndisc);
   2860     0    stevel 	ASSERT(esp->e_ncmds >= 0 && esp->e_ndisc >= 0);
   2861     0    stevel 
   2862     0    stevel 	if (lun) {
   2863     0    stevel 		EPRINTF("_esp_start: switching target and lun slot scan\n");
   2864     0    stevel 		esp->e_dslot = 1;
   2865     0    stevel 	}
   2866     0    stevel 
   2867     0    stevel 	esp_check_in_transport(esp, sp);
   2868     0    stevel 
   2869     0    stevel 	/*
   2870     0    stevel 	 * prepare (init) packet if this hasn't been done yet and do some checks
   2871     0    stevel 	 */
   2872     0    stevel 	if ((sp->cmd_flags & CFLAG_PREPARED) == 0) {
   2873     0    stevel 		rval = esp_prepare_pkt(esp, sp);
   2874     0    stevel 		if (rval != TRAN_ACCEPT) {
   2875     0    stevel 			IPRINTF1("prepare pkt failed, slot=%x\n", slot);
   2876     0    stevel #ifdef ESPDEBUG
   2877     0    stevel 			sp->cmd_flags &= ~CFLAG_IN_TRANSPORT;
   2878     0    stevel #endif
   2879     0    stevel 			goto done;
   2880     0    stevel 		}
   2881     0    stevel 	}
   2882     0    stevel 
   2883     0    stevel 	/*
   2884     0    stevel 	 * At this point we are not going to reject the packet.
   2885     0    stevel 	 * we let proxy packets go thru because these packets don't call a
   2886     0    stevel 	 * target driver completion routine
   2887     0    stevel 	 */
   2888     0    stevel 
   2889     0    stevel #ifdef ESP_KSTATS
   2890     0    stevel 	/*
   2891     0    stevel 	 * create kstats if not done already
   2892     0    stevel 	 */
   2893     0    stevel 	if (esp_do_kstats) {
   2894     0    stevel 		int slot = (Tgt(sp) * NLUNS_PER_TARGET) | Lun(sp);
   2895     0    stevel 
   2896     0    stevel 		/*
   2897     0    stevel 		 * don't create e_slot_stats if this is an NOINTR cmd; this
   2898     0    stevel 		 * may be just a probing
   2899     0    stevel 		 */
   2900     0    stevel 		if ((esp->e_slot_stats[slot] == NULL) &&
   2901     0    stevel 		    ((sp->cmd_pkt.pkt_flags & FLAG_NOINTR) == 0)) {
   2902     0    stevel 			char buf[32];
   2903     0    stevel 
   2904     0    stevel 			(void) sprintf(buf, "esp%dt%dd", CNUM, target);
   2905     0    stevel 			if ((esp->e_slot_stats[slot] = kstat_create(
   2906     0    stevel 			    buf, lun, NULL, "disk",
   2907     0    stevel 			    KSTAT_TYPE_IO, 1,
   2908     0    stevel 			    KSTAT_FLAG_PERSISTENT)) != NULL) {
   2909     0    stevel 				esp->e_slot_stats[slot]->ks_lock = ESP_MUTEX;
   2910     0    stevel 				kstat_install(esp->e_slot_stats[slot]);
   2911     0    stevel 			}
   2912     0    stevel 		}
   2913     0    stevel 		if (esp->e_slot_stats[slot]) {
   2914     0    stevel 			kstat_waitq_enter(IOSP(slot));
   2915     0    stevel 		}
   2916     0    stevel 	}
   2917     0    stevel #endif /* ESP_KSTATS */
   2918     0    stevel 
   2919     0    stevel #ifdef ESP_PERF
   2920     0    stevel 	esp_request_count++;
   2921     0    stevel #endif
   2922     0    stevel 
   2923     0    stevel 	/*
   2924     0    stevel 	 * we accepted the command; increment the count
   2925     0    stevel 	 * (we may reject later if TRAN_BUSY!; we test this later because
   2926     0    stevel 	 * we don't want to incur the extra overhead here)
   2927     0    stevel 	 */
   2928     0    stevel 	esp->e_ncmds++;
   2929     0    stevel 
   2930     0    stevel 	/*
   2931     0    stevel 	 * if it is a nointr packet, start it now
   2932     0    stevel 	 * (NO_INTR pkts are not queued in the startQ)
   2933     0    stevel 	 */
   2934     0    stevel 	if (sp->cmd_pkt.pkt_flags & FLAG_NOINTR) {
   2935     0    stevel 		EPRINTF("starting a nointr cmd\n");
   2936     0    stevel 		esp_runpoll(esp, slot, sp);
   2937     0    stevel #ifdef ESPDEBUG
   2938     0    stevel 		sp->cmd_flags &= ~CFLAG_IN_TRANSPORT;
   2939     0    stevel #endif
   2940     0    stevel 		goto done;
   2941     0    stevel 	}
   2942     0    stevel 
   2943     0    stevel 	/*
   2944     0    stevel 	 * accept the command:
   2945     0    stevel 	 * If no ready que and free slot, run cmd immediately.
   2946     0    stevel 	 * If FLAG_HEAD mode set, run cmd as soon as free slot
   2947     0    stevel 	 * available. if first cmd in ready Q is request sense then insert
   2948     0    stevel 	 * after this cmd (there shouldn't be more than one request sense).
   2949     0    stevel 	 * Queue up the command in the ready queue if this queue is non-empty
   2950     0    stevel 	 * or if we had a queue full condition
   2951     0    stevel 	 */
   2952     0    stevel 	if (esp->e_readyf[slot]) {
   2953     0    stevel 		if (sp->cmd_pkt.pkt_flags & FLAG_HEAD) {
   2954     0    stevel 			struct esp_cmd *ssp = esp->e_readyf[slot];
   2955     0    stevel 			EPRINTF("que head\n");
   2956     0    stevel 			if (*(ssp->cmd_pkt.pkt_cdbp) != SCMD_REQUEST_SENSE) {
   2957     0    stevel 				sp->cmd_forw = ssp;
   2958     0    stevel 				esp->e_readyf[slot] = sp;
   2959     0    stevel 			} else {
   2960     0    stevel 				struct esp_cmd *dp = ssp->cmd_forw;
   2961     0    stevel 				ssp->cmd_forw = sp;
   2962     0    stevel 				sp->cmd_forw = dp;
   2963     0    stevel 				if (esp->e_readyb[slot] == ssp) {
   2964     0    stevel 					esp->e_readyb[slot] = sp;
   2965     0    stevel 				}
   2966     0    stevel 			}
   2967     0    stevel 		} else if ((esp->e_tcmds[slot] >= esp->e_throttle[slot]) &&
   2968  7656    Sherry 		    (esp->e_throttle[slot] > HOLD_THROTTLE) &&
   2969  7656    Sherry 		    (flag == TRAN_BUSY_OK)) {
   2970  7656    Sherry 			IPRINTF2(
   2971  7656    Sherry 			    "transport busy, slot=%x, ncmds=%x\n",
   2972  7656    Sherry 			    slot, esp->e_ncmds);
   2973  7656    Sherry 			rval = TRAN_BUSY;
   2974  7656    Sherry 			esp->e_ncmds--;
   2975  7656    Sherry 			sp->cmd_flags &= ~CFLAG_PREPARED;
   2976  7656    Sherry #ifdef ESPDEBUG
   2977  7656    Sherry 			sp->cmd_flags &= ~CFLAG_IN_TRANSPORT;
   2978     0    stevel #endif
   2979     0    stevel #ifdef ESP_PERF
   2980  7656    Sherry 			esp_request_count--;
   2981  7656    Sherry #endif
   2982  7656    Sherry 			goto done;
   2983     0    stevel 		} else {
   2984     0    stevel 			struct esp_cmd *dp = esp->e_readyb[slot];
   2985     0    stevel 
   2986     0    stevel 			EPRINTF("que tail\n");
   2987     0    stevel 			ASSERT(dp != 0);
   2988     0    stevel 			esp->e_readyb[slot] = sp;
   2989     0    stevel 			sp->cmd_forw = NULL;
   2990     0    stevel 			dp->cmd_forw = sp;
   2991     0    stevel 		}
   2992     0    stevel 
   2993     0    stevel 		if ((esp->e_throttle[slot] == DRAIN_THROTTLE) &&
   2994     0    stevel 		    (esp->e_tcmds[slot] == 0)) {
   2995     0    stevel 			esp->e_throttle[slot] = CLEAR_THROTTLE;
   2996     0    stevel 		}
   2997     0    stevel 
   2998     0    stevel 		/*
   2999     0    stevel 		 * just in case that the bus is free and we haven't
   3000     0    stevel 		 * been able to restart for some reason
   3001     0    stevel 		 * XXX this shouldn't really be necessary
   3002     0    stevel 		 */
   3003     0    stevel 		if (esp->e_state == STATE_FREE) {
   3004     0    stevel 			(void) esp_ustart(esp, slot, NEW_CMD);
   3005     0    stevel 		}
   3006     0    stevel 	} else {
   3007     0    stevel 		/*
   3008     0    stevel 		 * for tagged targets with no cmds outstanding and currently
   3009     0    stevel 		 * draining, reset throttle now
   3010     0    stevel 		 * for non-tagged targets and currently draining, always reset
   3011     0    stevel 		 * throttle now (t_cmds is always zero for non-tagged)
   3012     0    stevel 		 */
   3013     0    stevel 		if ((esp->e_tcmds[slot] == 0) && (esp->e_throttle[slot] ==
   3014  7656    Sherry 		    DRAIN_THROTTLE)) {
   3015     0    stevel 			IPRINTF("reset throttle\n");
   3016     0    stevel 			esp->e_throttle[slot] = CLEAR_THROTTLE;
   3017     0    stevel 		}
   3018     0    stevel 		if ((esp->e_state == STATE_FREE) &&
   3019     0    stevel 		    (esp->e_slots[slot] == NULL) &&
   3020     0    stevel 		    (esp->e_tcmds[slot] < esp->e_throttle[slot])) {
   3021     0    stevel 			EPRINTF("start cmd (maybe)\n");
   3022     0    stevel 			esp->e_cur_slot = slot;
   3023     0    stevel 			esp->e_slots[slot] = sp;
   3024     0    stevel 			(void) esp_startcmd(esp, sp);
   3025     0    stevel 		} else {
   3026     0    stevel 			EPRINTF2(
   3027     0    stevel 			    "cmd not started: e_slot=0x%p, throttle=%x\n",
   3028     0    stevel 			    (void *)esp->e_slots[slot], esp->e_throttle[slot]);
   3029     0    stevel 			esp->e_readyf[slot] = esp->e_readyb[slot] = sp;
   3030     0    stevel 			sp->cmd_forw = NULL;
   3031     0    stevel 		}
   3032     0    stevel 	}
   3033     0    stevel done:
   3034     0    stevel 	ASSERT(mutex_owned(ESP_MUTEX));
   3035     0    stevel 	TRACE_0(TR_FAC_SCSI, TR__ESP_START_END, "_esp_start_end");
   3036     0    stevel 	return (rval);
   3037     0    stevel }
   3038     0    stevel 
   3039     0    stevel static char esp_tag_lookup[] =
   3040     0    stevel 	{0, MSG_HEAD_QTAG, MSG_ORDERED_QTAG, 0, MSG_SIMPLE_QTAG};
   3041     0    stevel 
   3042     0    stevel static int
   3043     0    stevel esp_alloc_tag(struct esp *esp, struct esp_cmd *sp)
   3044     0    stevel {
   3045     0    stevel 	struct t_slots *tag_slots;
   3046     0    stevel 	uchar_t tag;
   3047     0    stevel 	int rval = 0;
   3048     0    stevel 	int target = Tgt(sp);
   3049     0    stevel 	int lun = Lun(sp);
   3050     0    stevel 	short slot = (target * NLUNS_PER_TARGET) | lun;
   3051     0    stevel 
   3052     0    stevel 	TRACE_0(TR_FAC_SCSI, TR_ESP_ALLOC_TAG_START,
   3053     0    stevel 	    "esp_alloc_tag_start");
   3054     0    stevel 	ASSERT(mutex_owned(ESP_MUTEX));
   3055     0    stevel 
   3056     0    stevel alloc:
   3057     0    stevel 	/*
   3058     0    stevel 	 * allocate tag
   3059     0    stevel 	 * Optimize for the common case, ie. success
   3060     0    stevel 	 */
   3061     0    stevel 	tag_slots = esp->e_tagQ[slot];
   3062     0    stevel 	if (tag_slots != NULL) {
   3063     0    stevel 		tag = (esp->e_tagQ[slot]->e_tags)++;
   3064     0    stevel 		EPRINTF1("tagged cmd, tag = %d\n", tag);
   3065     0    stevel 
   3066     0    stevel 		/* Validate tag, should never fail. */
   3067     0    stevel 		if (tag_slots->t_slot[tag] == 0) {
   3068     0    stevel 			/*
   3069     0    stevel 			 * Store assigned tag and tag queue type.
   3070     0    stevel 			 * Note, in case
   3071     0    stevel 			 * of multiple choice, default to simple queue.
   3072     0    stevel 			 */
   3073     0    stevel 			sp->cmd_tag[1] = tag;
   3074     0    stevel 			sp->cmd_tag[0] = esp_tag_lookup[
   3075     0    stevel 			    ((sp->cmd_pkt.pkt_flags & FLAG_TAGMASK) >> 12)];
   3076     0    stevel 			EPRINTF1("tag= %d\n", tag);
   3077     0    stevel 			tag_slots->t_slot[tag] =  sp;
   3078     0    stevel 			(esp->e_tcmds[slot])++;
   3079     0    stevel done:
   3080     0    stevel 			ASSERT(mutex_owned(ESP_MUTEX));
   3081     0    stevel 			TRACE_0(TR_FAC_SCSI, TR_ESP_ALLOC_TAG_END,
   3082     0    stevel 			    "esp_alloc_tag_end");
   3083     0    stevel 			return (rval);
   3084     0    stevel 		} else {
   3085