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