Deleted Added
full compact
isp_freebsd.c (64176) isp_freebsd.c (65140)
1/* $FreeBSD: head/sys/dev/isp/isp_freebsd.c 64176 2000-08-03 03:05:50Z mjacob $ */
1/* $FreeBSD: head/sys/dev/isp/isp_freebsd.c 65140 2000-08-27 23:38:44Z mjacob $ */
2/*
3 * Platform (FreeBSD) dependent common attachment code for Qlogic adapters.
4 *
2/*
3 * Platform (FreeBSD) dependent common attachment code for Qlogic adapters.
4 *
5 *---------------------------------------
6 * Copyright (c) 1997, 1998, 1999 by Matthew Jacob
7 * NASA/Ames Research Center
8 * All rights reserved.
9 *---------------------------------------
5 * Copyright (c) 1997, 1998, 1999, 2000 by Matthew Jacob
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice immediately at the beginning of the file, without modification,
16 * this list of conditions, and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice immediately at the beginning of the file, without modification,
12 * this list of conditions, and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
20 * 3. The name of the author may not be used to endorse or promote products
21 * derived from this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
27 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)

--- 129 unchanged lines hidden (view full) ---

159 }
160}
161
162static void
163isp_intr_enable(void *arg)
164{
165 struct ispsoftc *isp = arg;
166 ENABLE_INTS(isp);
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)

--- 129 unchanged lines hidden (view full) ---

153 }
154}
155
156static void
157isp_intr_enable(void *arg)
158{
159 struct ispsoftc *isp = arg;
160 ENABLE_INTS(isp);
161#ifdef SERVICING_INTERRUPT
167 isp->isp_osinfo.intsok = 1;
162 isp->isp_osinfo.intsok = 1;
163#endif
168 /* Release our hook so that the boot can continue. */
169 config_intrhook_disestablish(&isp->isp_osinfo.ehook);
170}
171
172/*
173 * Put the target mode functions here, because some are inlines
174 */
175

--- 218 unchanged lines hidden (view full) ---

394
395static void
396isp_en_lun(struct ispsoftc *isp, union ccb *ccb)
397{
398 const char *lfmt = "Lun now %sabled for target mode\n";
399 struct ccb_en_lun *cel = &ccb->cel;
400 tstate_t *tptr;
401 u_int16_t rstat;
164 /* Release our hook so that the boot can continue. */
165 config_intrhook_disestablish(&isp->isp_osinfo.ehook);
166}
167
168/*
169 * Put the target mode functions here, because some are inlines
170 */
171

--- 218 unchanged lines hidden (view full) ---

390
391static void
392isp_en_lun(struct ispsoftc *isp, union ccb *ccb)
393{
394 const char *lfmt = "Lun now %sabled for target mode\n";
395 struct ccb_en_lun *cel = &ccb->cel;
396 tstate_t *tptr;
397 u_int16_t rstat;
402 int bus;
398 int bus, frozen = 0;
403 lun_id_t lun;
404 target_id_t tgt;
405
406
407 bus = XS_CHANNEL(ccb);
408 tgt = ccb->ccb_h.target_id;
409 lun = ccb->ccb_h.target_lun;
410
411 /*
399 lun_id_t lun;
400 target_id_t tgt;
401
402
403 bus = XS_CHANNEL(ccb);
404 tgt = ccb->ccb_h.target_id;
405 lun = ccb->ccb_h.target_lun;
406
407 /*
412 * First, check to see if we're enabling on fibre channel
413 * and don't yet have a notion of who the heck we are (no
408 * Do some sanity checking first.
409 */
410
411 if (lun < 0 || lun >= (lun_id_t) isp->isp_maxluns) {
412 ccb->ccb_h.status = CAM_LUN_INVALID;
413 return;
414 }
415 if (IS_SCSI(isp)) {
416 if (tgt != CAM_TARGET_WILDCARD &&
417 tgt != ((sdparam *) isp->isp_param)->isp_initiator_id) {
418 ccb->ccb_h.status = CAM_TID_INVALID;
419 return;
420 }
421 } else {
422 if (tgt != CAM_TARGET_WILDCARD &&
423 tgt != ((fcparam *) isp->isp_param)->isp_loopid) {
424 ccb->ccb_h.status = CAM_TID_INVALID;
425 return;
426 }
427 }
428
429 /*
430 * If Fibre Channel, stop and drain all activity to this bus.
431 */
432 if (IS_FC(isp)) {
433 ISP_LOCK(isp);
434 frozen = 1;
435 xpt_freeze_simq(isp->isp_sim, 1);
436 isp->isp_osinfo.drain = 1;
437 /* ISP_UNLOCK(isp); XXX NEED CV_WAIT HERE XXX */
438 while (isp->isp_osinfo.drain) {
439 tsleep(&isp->isp_osinfo.drain, PRIBIO, "ispdrain", 0);
440 }
441 ISP_UNLOCK(isp);
442 }
443
444 /*
445 * Check to see if we're enabling on fibre channel and
446 * don't yet have a notion of who the heck we are (no
414 * loop yet).
415 */
416 if (IS_FC(isp) && cel->enable &&
417 (isp->isp_osinfo.tmflags & TM_TMODE_ENABLED) == 0) {
418 int rv= 2 * 1000000;
419 fcparam *fcp = isp->isp_param;
420
421 ISP_LOCK(isp);
422 rv = isp_control(isp, ISPCTL_FCLINK_TEST, &rv);
423 ISP_UNLOCK(isp);
424 if (rv || fcp->isp_fwstate != FW_READY) {
425 xpt_print_path(ccb->ccb_h.path);
426 printf("link status not good yet\n");
427 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
447 * loop yet).
448 */
449 if (IS_FC(isp) && cel->enable &&
450 (isp->isp_osinfo.tmflags & TM_TMODE_ENABLED) == 0) {
451 int rv= 2 * 1000000;
452 fcparam *fcp = isp->isp_param;
453
454 ISP_LOCK(isp);
455 rv = isp_control(isp, ISPCTL_FCLINK_TEST, &rv);
456 ISP_UNLOCK(isp);
457 if (rv || fcp->isp_fwstate != FW_READY) {
458 xpt_print_path(ccb->ccb_h.path);
459 printf("link status not good yet\n");
460 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
461 if (frozen)
462 xpt_release_simq(isp->isp_sim, 1);
428 return;
429 }
430 ISP_LOCK(isp);
431 rv = isp_control(isp, ISPCTL_PDB_SYNC, NULL);
432 ISP_UNLOCK(isp);
433 if (rv || fcp->isp_fwstate != FW_READY) {
434 xpt_print_path(ccb->ccb_h.path);
435 printf("could not get a good port database read\n");
436 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
463 return;
464 }
465 ISP_LOCK(isp);
466 rv = isp_control(isp, ISPCTL_PDB_SYNC, NULL);
467 ISP_UNLOCK(isp);
468 if (rv || fcp->isp_fwstate != FW_READY) {
469 xpt_print_path(ccb->ccb_h.path);
470 printf("could not get a good port database read\n");
471 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
472 if (frozen)
473 xpt_release_simq(isp->isp_sim, 1);
437 return;
438 }
439 }
440
441
442 /*
443 * Next check to see whether this is a target/lun wildcard action.
444 *
445 * If so, we enable/disable target mode but don't do any lun enabling.
446 */
447 if (lun == CAM_LUN_WILDCARD && tgt == CAM_TARGET_WILDCARD) {
448 int av;
449 tptr = &isp->isp_osinfo.tsdflt;
450 if (cel->enable) {
451 if (isp->isp_osinfo.tmflags & TM_TMODE_ENABLED) {
452 ccb->ccb_h.status = CAM_LUN_ALRDY_ENA;
474 return;
475 }
476 }
477
478
479 /*
480 * Next check to see whether this is a target/lun wildcard action.
481 *
482 * If so, we enable/disable target mode but don't do any lun enabling.
483 */
484 if (lun == CAM_LUN_WILDCARD && tgt == CAM_TARGET_WILDCARD) {
485 int av;
486 tptr = &isp->isp_osinfo.tsdflt;
487 if (cel->enable) {
488 if (isp->isp_osinfo.tmflags & TM_TMODE_ENABLED) {
489 ccb->ccb_h.status = CAM_LUN_ALRDY_ENA;
490 if (frozen)
491 xpt_release_simq(isp->isp_sim, 1);
453 return;
454 }
455 ccb->ccb_h.status =
456 xpt_create_path(&tptr->owner, NULL,
457 xpt_path_path_id(ccb->ccb_h.path),
458 xpt_path_target_id(ccb->ccb_h.path),
459 xpt_path_lun_id(ccb->ccb_h.path));
460 if (ccb->ccb_h.status != CAM_REQ_CMP) {
492 return;
493 }
494 ccb->ccb_h.status =
495 xpt_create_path(&tptr->owner, NULL,
496 xpt_path_path_id(ccb->ccb_h.path),
497 xpt_path_target_id(ccb->ccb_h.path),
498 xpt_path_lun_id(ccb->ccb_h.path));
499 if (ccb->ccb_h.status != CAM_REQ_CMP) {
500 if (frozen)
501 xpt_release_simq(isp->isp_sim, 1);
461 return;
462 }
463 SLIST_INIT(&tptr->atios);
464 SLIST_INIT(&tptr->inots);
465 av = 1;
466 ISP_LOCK(isp);
467 av = isp_control(isp, ISPCTL_TOGGLE_TMODE, &av);
468 if (av) {
469 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
470 xpt_free_path(tptr->owner);
471 ISP_UNLOCK(isp);
502 return;
503 }
504 SLIST_INIT(&tptr->atios);
505 SLIST_INIT(&tptr->inots);
506 av = 1;
507 ISP_LOCK(isp);
508 av = isp_control(isp, ISPCTL_TOGGLE_TMODE, &av);
509 if (av) {
510 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
511 xpt_free_path(tptr->owner);
512 ISP_UNLOCK(isp);
513 if (frozen)
514 xpt_release_simq(isp->isp_sim, 1);
472 return;
473 }
474 isp->isp_osinfo.tmflags |= TM_TMODE_ENABLED;
475 ISP_UNLOCK(isp);
476 } else {
477 if ((isp->isp_osinfo.tmflags & TM_TMODE_ENABLED) == 0) {
478 ccb->ccb_h.status = CAM_LUN_INVALID;
515 return;
516 }
517 isp->isp_osinfo.tmflags |= TM_TMODE_ENABLED;
518 ISP_UNLOCK(isp);
519 } else {
520 if ((isp->isp_osinfo.tmflags & TM_TMODE_ENABLED) == 0) {
521 ccb->ccb_h.status = CAM_LUN_INVALID;
522 if (frozen)
523 xpt_release_simq(isp->isp_sim, 1);
479 return;
480 }
481 if (are_any_luns_enabled(isp)) {
482 ccb->ccb_h.status = CAM_SCSI_BUSY;
524 return;
525 }
526 if (are_any_luns_enabled(isp)) {
527 ccb->ccb_h.status = CAM_SCSI_BUSY;
528 if (frozen)
529 xpt_release_simq(isp->isp_sim, 1);
483 return;
484 }
485 av = 0;
486 ISP_LOCK(isp);
487 av = isp_control(isp, ISPCTL_TOGGLE_TMODE, &av);
488 if (av) {
489 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
490 ISP_UNLOCK(isp);
530 return;
531 }
532 av = 0;
533 ISP_LOCK(isp);
534 av = isp_control(isp, ISPCTL_TOGGLE_TMODE, &av);
535 if (av) {
536 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
537 ISP_UNLOCK(isp);
538 if (frozen)
539 xpt_release_simq(isp->isp_sim, 1);
491 return;
492 }
493 isp->isp_osinfo.tmflags &= ~TM_TMODE_ENABLED;
494 ISP_UNLOCK(isp);
495 ccb->ccb_h.status = CAM_REQ_CMP;
496 }
497 xpt_print_path(ccb->ccb_h.path);
498 printf(lfmt, (cel->enable) ? "en" : "dis");
540 return;
541 }
542 isp->isp_osinfo.tmflags &= ~TM_TMODE_ENABLED;
543 ISP_UNLOCK(isp);
544 ccb->ccb_h.status = CAM_REQ_CMP;
545 }
546 xpt_print_path(ccb->ccb_h.path);
547 printf(lfmt, (cel->enable) ? "en" : "dis");
548 if (frozen)
549 xpt_release_simq(isp->isp_sim, 1);
499 return;
500 }
501
502 /*
550 return;
551 }
552
553 /*
503 * Do some sanity checking first.
554 * We can move along now...
504 */
505
555 */
556
506 if (lun < 0 || lun >= (lun_id_t) isp->isp_maxluns) {
507 ccb->ccb_h.status = CAM_LUN_INVALID;
508 return;
509 }
510 if (IS_SCSI(isp)) {
511 if (tgt != CAM_TARGET_WILDCARD &&
512 tgt != ((sdparam *) isp->isp_param)->isp_initiator_id) {
513 ccb->ccb_h.status = CAM_TID_INVALID;
514 return;
515 }
516 } else {
517 if (tgt != CAM_TARGET_WILDCARD &&
518 tgt != ((fcparam *) isp->isp_param)->isp_loopid) {
519 ccb->ccb_h.status = CAM_TID_INVALID;
520 return;
521 }
522 }
557 if (frozen)
558 xpt_release_simq(isp->isp_sim, 1);
523
524
525 if (cel->enable) {
526 ccb->ccb_h.status =
527 create_lun_state(isp, ccb->ccb_h.path, &tptr);
528 if (ccb->ccb_h.status != CAM_REQ_CMP) {
529 return;
530 }

--- 881 unchanged lines hidden (view full) ---

1412 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("isp_action\n"));
1413
1414 isp = (struct ispsoftc *)cam_sim_softc(sim);
1415 ccb->ccb_h.sim_priv.entries[0].field = 0;
1416 ccb->ccb_h.sim_priv.entries[1].ptr = isp;
1417 if (isp->isp_state != ISP_RUNSTATE &&
1418 ccb->ccb_h.func_code == XPT_SCSI_IO) {
1419 ISP_LOCK(isp);
559
560
561 if (cel->enable) {
562 ccb->ccb_h.status =
563 create_lun_state(isp, ccb->ccb_h.path, &tptr);
564 if (ccb->ccb_h.status != CAM_REQ_CMP) {
565 return;
566 }

--- 881 unchanged lines hidden (view full) ---

1448 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("isp_action\n"));
1449
1450 isp = (struct ispsoftc *)cam_sim_softc(sim);
1451 ccb->ccb_h.sim_priv.entries[0].field = 0;
1452 ccb->ccb_h.sim_priv.entries[1].ptr = isp;
1453 if (isp->isp_state != ISP_RUNSTATE &&
1454 ccb->ccb_h.func_code == XPT_SCSI_IO) {
1455 ISP_LOCK(isp);
1420 DISABLE_INTS(isp);
1421 isp_init(isp);
1422 if (isp->isp_state != ISP_INITSTATE) {
1423 ISP_UNLOCK(isp);
1424 /*
1425 * Lie. Say it was a selection timeout.
1426 */
1427 ccb->ccb_h.status = CAM_SEL_TIMEOUT | CAM_DEV_QFRZN;
1428 xpt_freeze_devq(ccb->ccb_h.path, 1);
1429 xpt_done(ccb);
1430 return;
1431 }
1432 isp->isp_state = ISP_RUNSTATE;
1456 isp_init(isp);
1457 if (isp->isp_state != ISP_INITSTATE) {
1458 ISP_UNLOCK(isp);
1459 /*
1460 * Lie. Say it was a selection timeout.
1461 */
1462 ccb->ccb_h.status = CAM_SEL_TIMEOUT | CAM_DEV_QFRZN;
1463 xpt_freeze_devq(ccb->ccb_h.path, 1);
1464 xpt_done(ccb);
1465 return;
1466 }
1467 isp->isp_state = ISP_RUNSTATE;
1433 ENABLE_INTS(isp);
1434 ISP_UNLOCK(isp);
1435 }
1436 isp_prt(isp, ISP_LOGDEBUG2, "isp_action code %x", ccb->ccb_h.func_code);
1437
1438 switch (ccb->ccb_h.func_code) {
1439 case XPT_SCSI_IO: /* Execute the requested I/O operation */
1440 /*
1441 * Do a couple of preliminary checks...

--- 802 unchanged lines hidden ---
1468 ISP_UNLOCK(isp);
1469 }
1470 isp_prt(isp, ISP_LOGDEBUG2, "isp_action code %x", ccb->ccb_h.func_code);
1471
1472 switch (ccb->ccb_h.func_code) {
1473 case XPT_SCSI_IO: /* Execute the requested I/O operation */
1474 /*
1475 * Do a couple of preliminary checks...

--- 802 unchanged lines hidden ---