1/*- 2 * Copyright (c) 2004 Scott Long 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 */ 27 |
28/* $NetBSD: ncr53c9x.c,v 1.114 2005/02/27 00:27:02 perry Exp $ */ |
29 30/*- 31 * Copyright (c) 1998, 2002 The NetBSD Foundation, Inc. 32 * All rights reserved. 33 * 34 * This code is derived from software contributed to The NetBSD Foundation 35 * by Charles M. Hannum. 36 * --- 62 unchanged lines hidden (view full) --- 99 * Based on aic6360 by Jarle Greipsland 100 * 101 * Acknowledgements: Many of the algorithms used in this driver are 102 * inspired by the work of Julian Elischer (julian@FreeBSD.org) and 103 * Charles Hannum (mycroft@duality.gnu.ai.mit.edu). Thanks a million! 104 */ 105 106#include <sys/cdefs.h> |
107__FBSDID("$FreeBSD: head/sys/dev/esp/ncr53c9x.c 146392 2005-05-19 14:51:10Z marius $"); |
108 109#include <sys/param.h> 110#include <sys/systm.h> 111#include <sys/bus.h> 112#include <sys/kernel.h> 113#include <sys/malloc.h> 114#include <sys/resource.h> 115#include <sys/lock.h> --- 79 unchanged lines hidden (view full) --- 195 "NCR53C94", 196 "NCR53C96", 197 "ESP406", 198 "FAS408", 199 "FAS216", 200 "AM53C974", 201 "FAS366/HME", 202 "NCR53C90 (86C01)", |
203 "FAS100A", 204 "FAS236", |
205}; 206 207/* 208 * Search linked list for LUN info by LUN id. 209 */ 210static struct ncr53c9x_linfo * 211ncr53c9x_lunsearch(struct ncr53c9x_tinfo *ti, int64_t lun) 212{ --- 9 unchanged lines hidden (view full) --- 222 */ 223int 224ncr53c9x_attach(struct ncr53c9x_softc *sc) 225{ 226 struct cam_devq *devq; 227 struct cam_sim *sim; 228 struct cam_path *path; 229 struct ncr53c9x_ecb *ecb; |
230 int error, i; |
231 232 mtx_init(&sc->sc_lock, "ncr", "ncr53c9x lock", MTX_DEF); 233 234 /* 235 * Note, the front-end has set us up to print the chip variation. 236 */ 237 if (sc->sc_rev >= NCR_VARIANT_MAX) { 238 device_printf(sc->sc_dev, "unknown variant %d, devices not " --- 7 unchanged lines hidden (view full) --- 246 sc->sc_ntarg = (sc->sc_rev == NCR_VARIANT_FAS366) ? 16 : 8; 247 248 /* 249 * Allocate SCSI message buffers. 250 * Front-ends can override allocation to avoid alignment 251 * handling in the DMA engines. Note that that ncr53c9x_msgout() 252 * can request a 1 byte DMA transfer. 253 */ |
254 if (sc->sc_omess == NULL) { 255 sc->sc_omess_self = 1; |
256 sc->sc_omess = malloc(NCR_MAX_MSG_LEN, M_DEVBUF, M_NOWAIT); |
257 if (sc->sc_omess == NULL) { 258 device_printf(sc->sc_dev, 259 "cannot allocate MSGOUT buffer\n"); 260 return (ENOMEM); 261 } 262 } else 263 sc->sc_omess_self = 0; |
264 |
265 if (sc->sc_imess == NULL) { 266 sc->sc_imess_self = 1; |
267 sc->sc_imess = malloc(NCR_MAX_MSG_LEN + 1, M_DEVBUF, M_NOWAIT); |
268 if (sc->sc_imess == NULL) { 269 device_printf(sc->sc_dev, 270 "cannot allocate MSGIN buffer\n"); 271 error = ENOMEM; 272 goto fail_omess; 273 } 274 } else 275 sc->sc_imess_self = 0; |
276 277 sc->sc_tinfo = malloc(sc->sc_ntarg * sizeof(sc->sc_tinfo[0]), 278 M_DEVBUF, M_NOWAIT | M_ZERO); |
279 if (sc->sc_tinfo == NULL) { 280 device_printf(sc->sc_dev, 281 "cannot allocate target info buffer\n"); 282 error = ENOMEM; 283 goto fail_imess; |
284 } 285 286 callout_init(&sc->sc_watchdog, 0); 287 288 /* 289 * Treat NCR53C90 with the 86C01 DMA chip exactly as ESP100 290 * from now on. 291 */ --- 21 unchanged lines hidden (view full) --- 313 314 /* CCF register only has 3 bits; 0 is actually 8 */ 315 sc->sc_ccf &= 7; 316 317 /* 318 * Register with CAM 319 */ 320 devq = cam_simq_alloc(sc->sc_ntarg); |
321 if (devq == NULL) { 322 device_printf(sc->sc_dev, "cannot allocate device queue\n"); 323 error = ENOMEM; 324 goto fail_tinfo; 325 } |
326 327 sim = cam_sim_alloc(ncr53c9x_action, ncr53c9x_poll, "esp", sc, 328 device_get_unit(sc->sc_dev), 1, 329 NCR_TAG_DEPTH, devq); 330 if (sim == NULL) { |
331 device_printf(sc->sc_dev, "cannot allocate SIM entry\n"); 332 error = ENOMEM; 333 goto fail_devq; |
334 } 335 if (xpt_bus_register(sim, 0) != CAM_SUCCESS) { |
336 device_printf(sc->sc_dev, "cannot register bus\n"); 337 error = EIO; 338 goto fail_sim; |
339 } 340 341 if (xpt_create_path(&path, NULL, cam_sim_path(sim), 342 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) 343 != CAM_REQ_CMP) { |
344 device_printf(sc->sc_dev, "cannot create path\n"); 345 error = EIO; 346 goto fail_bus; |
347 } 348 349 sc->sc_sim = sim; 350 sc->sc_path = path; 351 352 /* Reset state & bus */ 353#if 0 354 sc->sc_cfflags = sc->sc_dev.dv_cfdata->cf_flags; 355#endif 356 sc->sc_state = 0; 357 ncr53c9x_init(sc, 1); 358 359 TAILQ_INIT(&sc->free_list); 360 if ((sc->ecb_array = malloc(sizeof(struct ncr53c9x_ecb) * NCR_TAG_DEPTH, 361 M_DEVBUF, M_NOWAIT|M_ZERO)) == NULL) { 362 device_printf(sc->sc_dev, "cannot allocate ECB array\n"); |
363 error = ENOMEM; 364 goto fail_path; |
365 } 366 for (i = 0; i < NCR_TAG_DEPTH; i++) { 367 ecb = &sc->ecb_array[i]; 368 ecb->sc = sc; 369 ecb->tag_id = i; 370 TAILQ_INSERT_HEAD(&sc->free_list, ecb, free_links); 371 } 372 373 callout_reset(&sc->sc_watchdog, 60*hz, ncr53c9x_watch, sc); 374 375 return (0); |
376 377fail_path: 378 xpt_free_path(path); 379fail_bus: 380 xpt_bus_deregister(cam_sim_path(sim)); 381fail_sim: 382 cam_sim_free(sim, TRUE); 383fail_devq: 384 cam_simq_free(devq); 385fail_tinfo: 386 free(sc->sc_tinfo, M_DEVBUF); 387fail_imess: 388 if (sc->sc_imess_self) 389 free(sc->sc_imess, M_DEVBUF); 390fail_omess: 391 if (sc->sc_omess_self) 392 free(sc->sc_omess, M_DEVBUF); 393 return (error); |
394} 395 396int |
397ncr53c9x_detach(struct ncr53c9x_softc *sc) |
398{ 399 |
400 callout_drain(&sc->sc_watchdog); 401 mtx_lock(&sc->sc_lock); 402 ncr53c9x_init(sc, 1); 403 mtx_unlock(&sc->sc_lock); 404 xpt_free_path(sc->sc_path); 405 xpt_bus_deregister(cam_sim_path(sc->sc_sim)); 406 cam_sim_free(sc->sc_sim, TRUE); 407 free(sc->ecb_array, M_DEVBUF); 408 free(sc->sc_tinfo, M_DEVBUF); 409 if (sc->sc_imess_self) 410 free(sc->sc_imess, M_DEVBUF); 411 if (sc->sc_omess_self) 412 free(sc->sc_omess, M_DEVBUF); 413 mtx_destroy(&sc->sc_lock); |
414 |
415 return (0); |
416} 417 418/* 419 * This is the generic ncr53c9x reset function. It does not reset the SCSI bus, 420 * only this controller, but kills any on-going commands, and also stops 421 * and resets the DMA. 422 * 423 * After reset, registers are loaded with the defaults from the attach --- 13 unchanged lines hidden (view full) --- 437 438 /* do these backwards, and fall through */ 439 switch (sc->sc_rev) { 440 case NCR_VARIANT_ESP406: 441 case NCR_VARIANT_FAS408: 442 NCR_WRITE_REG(sc, NCR_CFG5, sc->sc_cfg5 | NCRCFG5_SINT); 443 NCR_WRITE_REG(sc, NCR_CFG4, sc->sc_cfg4); 444 case NCR_VARIANT_AM53C974: |
445 case NCR_VARIANT_FAS100A: |
446 case NCR_VARIANT_FAS216: |
447 case NCR_VARIANT_FAS236: |
448 case NCR_VARIANT_NCR53C94: 449 case NCR_VARIANT_NCR53C96: 450 case NCR_VARIANT_ESP200: 451 sc->sc_features |= NCR_F_HASCFG3; 452 NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3); 453 case NCR_VARIANT_ESP100A: 454 sc->sc_features |= NCR_F_SELATN3; 455 NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2); --- 110 unchanged lines hidden (view full) --- 566 } 567 } 568 569 /* 570 * reset the chip to a known state 571 */ 572 ncr53c9x_reset(sc); 573 |
574 sc->sc_flags = 0; 575 sc->sc_msgpriq = sc->sc_msgout = sc->sc_msgoutq = 0; |
576 sc->sc_phase = sc->sc_prevphase = INVALID_PHASE; |
577 |
578 for (r = 0; r < sc->sc_ntarg; r++) { 579 struct ncr53c9x_tinfo *ti = &sc->sc_tinfo[r]; 580/* XXX - config flags per target: low bits: no reselect; high bits: no synch */ 581 582 ti->flags = ((sc->sc_minsync && !(sc->sc_cfflags & (1<<((r&7)+8)))) 583 ? 0 : T_SYNCHOFF) | 584 ((sc->sc_cfflags & (1<<(r&7))) ? T_RSELECTOFF : 0); 585#ifdef DEBUG --- 1261 unchanged lines hidden (view full) --- 1847 int p; 1848 1849 p = ncr53c9x_stp2cpb(sc, ti->period); 1850 ti->period = ncr53c9x_cpb2stp(sc, p); 1851 if ((sc->sc_flags&NCR_SYNCHNEGO) == 0) { 1852 /* 1853 * target initiated negotiation 1854 */ |
1855 if (ti->period < sc->sc_minsync) |
1856 ti->period = 1857 sc->sc_minsync; 1858 if (ti->offset > 15) 1859 ti->offset = 15; 1860 ti->flags &= ~T_SYNCMODE; 1861 ncr53c9x_sched_msgout( 1862 SEND_SDTR); 1863 } else { --- 683 unchanged lines hidden (view full) --- 2547 } 2548 2549#define NCRINTR_DONE (NCRINTR_FC|NCRINTR_BS) 2550 if ((sc->sc_espintr & NCRINTR_DONE) == NCRINTR_DONE) { 2551 /* 2552 * Arbitration won; examine the `step' register 2553 * to determine how far the selection could progress. 2554 */ |
2555 if (ecb == NULL) { 2556 /* 2557 * When doing path inquiry during boot 2558 * FAS100A trigger a stray interrupt which 2559 * we just ignore instead of panicing. 2560 */ 2561 if (sc->sc_state == NCR_IDLE && 2562 sc->sc_espstep == 0) 2563 goto out; |
2564 panic("ncr53c9x: no nexus"); |
2565 } |
2566 2567 ti = &sc->sc_tinfo[ecb->ccb->ccb_h.target_id]; 2568 2569 switch (sc->sc_espstep) { 2570 case 0: 2571 /* 2572 * The target did not respond with a 2573 * message out phase - probably an old --- 100 unchanged lines hidden (view full) --- 2674 "select: [intr %x, stat %x, step %x]\n", 2675 sc->sc_espintr, sc->sc_espstat, sc->sc_espstep); 2676 NCRCMD(sc, NCRCMD_FLUSH); 2677 DELAY(1); 2678 goto reset; 2679 } 2680 if (sc->sc_state == NCR_IDLE) { 2681 device_printf(sc->sc_dev, "stray interrupt\n"); |
2682 goto out; |
2683 } 2684 break; 2685 2686 case NCR_CONNECTED: 2687 if ((sc->sc_flags & NCR_ICCS) != 0) { 2688 /* "Initiate Command Complete Steps" in progress */ 2689 u_char msg; 2690 --- 334 unchanged lines hidden --- |