isp_target.c (154704) | isp_target.c (155704) |
---|---|
1/*- 2 * Machine and OS Independent Target Mode Code for the Qlogic SCSI/FC adapters. 3 * 4 * Copyright (c) 1997-2006 by Matthew Jacob 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 11 unchanged lines hidden (view full) --- 20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ | 1/*- 2 * Machine and OS Independent Target Mode Code for the Qlogic SCSI/FC adapters. 3 * 4 * Copyright (c) 1997-2006 by Matthew Jacob 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 11 unchanged lines hidden (view full) --- 20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ |
28#ifdef __FreeBSD__ 29#include <sys/cdefs.h> 30__FBSDID("$FreeBSD: head/sys/dev/isp/isp_target.c 155704 2006-02-15 00:31:48Z mjacob $"); 31#endif |
|
28 29/* 30 * Bug fixes gratefully acknowledged from: 31 * Oded Kedem <oded@kashya.com> 32 */ 33/* 34 * Include header file appropriate for platform we're building on. 35 */ 36 37#ifdef __NetBSD__ 38#include <dev/ic/isp_netbsd.h> 39#endif 40#ifdef __FreeBSD__ | 32 33/* 34 * Bug fixes gratefully acknowledged from: 35 * Oded Kedem <oded@kashya.com> 36 */ 37/* 38 * Include header file appropriate for platform we're building on. 39 */ 40 41#ifdef __NetBSD__ 42#include <dev/ic/isp_netbsd.h> 43#endif 44#ifdef __FreeBSD__ |
41#include <sys/cdefs.h> 42__FBSDID("$FreeBSD: head/sys/dev/isp/isp_target.c 154704 2006-01-23 06:23:37Z mjacob $"); 43 | |
44#include <dev/isp/isp_freebsd.h> 45#endif 46#ifdef __OpenBSD__ 47#include <dev/ic/isp_openbsd.h> 48#endif 49#ifdef __linux__ 50#include "isp_linux.h" 51#endif --- 55 unchanged lines hidden (view full) --- 107 * has already swizzled it into the platform dependent from canonical form. 108 * 109 * Because of the way this driver is designed, unfortunately most of the 110 * actual synchronization work has to be done in the platform specific 111 * code- we have no synchroniation primitives in the common code. 112 */ 113 114int | 45#include <dev/isp/isp_freebsd.h> 46#endif 47#ifdef __OpenBSD__ 48#include <dev/ic/isp_openbsd.h> 49#endif 50#ifdef __linux__ 51#include "isp_linux.h" 52#endif --- 55 unchanged lines hidden (view full) --- 108 * has already swizzled it into the platform dependent from canonical form. 109 * 110 * Because of the way this driver is designed, unfortunately most of the 111 * actual synchronization work has to be done in the platform specific 112 * code- we have no synchroniation primitives in the common code. 113 */ 114 115int |
115isp_target_notify(struct ispsoftc *isp, void *vptr, u_int16_t *optrp) | 116isp_target_notify(struct ispsoftc *isp, void *vptr, uint16_t *optrp) |
116{ | 117{ |
117 u_int16_t status, seqid; | 118 uint16_t status, seqid; |
118 union { 119 at_entry_t *atiop; 120 at2_entry_t *at2iop; 121 at2e_entry_t *at2eiop; 122 ct_entry_t *ctiop; 123 ct2_entry_t *ct2iop; 124 ct2e_entry_t *ct2eiop; 125 lun_entry_t *lunenp; --- 15 unchanged lines hidden (view full) --- 141#define inotp unp.inotp 142#define inot_fcp unp.inot_fcp 143#define inote_fcp unp.inote_fcp 144#define nackp unp.nackp 145#define nack_fcp unp.nack_fcp 146#define nacke_fcp unp.nacke_fcp 147#define hdrp unp.hp 148 } unp; | 119 union { 120 at_entry_t *atiop; 121 at2_entry_t *at2iop; 122 at2e_entry_t *at2eiop; 123 ct_entry_t *ctiop; 124 ct2_entry_t *ct2iop; 125 ct2e_entry_t *ct2eiop; 126 lun_entry_t *lunenp; --- 15 unchanged lines hidden (view full) --- 142#define inotp unp.inotp 143#define inot_fcp unp.inot_fcp 144#define inote_fcp unp.inote_fcp 145#define nackp unp.nackp 146#define nack_fcp unp.nack_fcp 147#define nacke_fcp unp.nacke_fcp 148#define hdrp unp.hp 149 } unp; |
149 u_int8_t local[QENTRY_LEN]; | 150 uint8_t local[QENTRY_LEN]; |
150 int bus, type, rval = 1; 151 152 type = isp_get_response_type(isp, (isphdr_t *)vptr); 153 unp.vp = vptr; 154 155 ISP_TDQE(isp, "isp_target_notify", (int) *optrp, vptr); 156 157 switch(type) { --- 140 unchanged lines hidden (view full) --- 298 * The caller has checked for overlap and legality. 299 * 300 * Note that not all of bus, target or lun can be paid attention to. 301 * Note also that this action will not be complete until the f/w writes 302 * response entry. The caller is responsible for synchronizing this. 303 */ 304int 305isp_lun_cmd(struct ispsoftc *isp, int cmd, int bus, int tgt, int lun, | 151 int bus, type, rval = 1; 152 153 type = isp_get_response_type(isp, (isphdr_t *)vptr); 154 unp.vp = vptr; 155 156 ISP_TDQE(isp, "isp_target_notify", (int) *optrp, vptr); 157 158 switch(type) { --- 140 unchanged lines hidden (view full) --- 299 * The caller has checked for overlap and legality. 300 * 301 * Note that not all of bus, target or lun can be paid attention to. 302 * Note also that this action will not be complete until the f/w writes 303 * response entry. The caller is responsible for synchronizing this. 304 */ 305int 306isp_lun_cmd(struct ispsoftc *isp, int cmd, int bus, int tgt, int lun, |
306 int cmd_cnt, int inot_cnt, u_int32_t opaque) | 307 int cmd_cnt, int inot_cnt, uint32_t opaque) |
307{ 308 lun_entry_t el; | 308{ 309 lun_entry_t el; |
309 u_int16_t nxti, optr; | 310 uint16_t nxti, optr; |
310 void *outp; 311 312 313 MEMZERO(&el, sizeof (el)); 314 if (IS_DUALBUS(isp)) { 315 el.le_rsvd = (bus & 0x1) << 7; 316 } 317 el.le_cmd_count = cmd_cnt; --- 36 unchanged lines hidden (view full) --- 354 return (0); 355} 356 357 358int 359isp_target_put_entry(struct ispsoftc *isp, void *ap) 360{ 361 void *outp; | 311 void *outp; 312 313 314 MEMZERO(&el, sizeof (el)); 315 if (IS_DUALBUS(isp)) { 316 el.le_rsvd = (bus & 0x1) << 7; 317 } 318 el.le_cmd_count = cmd_cnt; --- 36 unchanged lines hidden (view full) --- 355 return (0); 356} 357 358 359int 360isp_target_put_entry(struct ispsoftc *isp, void *ap) 361{ 362 void *outp; |
362 u_int16_t nxti, optr; 363 u_int8_t etype = ((isphdr_t *) ap)->rqs_entry_type; | 363 uint16_t nxti, optr; 364 uint8_t etype = ((isphdr_t *) ap)->rqs_entry_type; |
364 365 if (isp_getrqentry(isp, &nxti, &optr, &outp)) { 366 isp_prt(isp, ISP_LOGWARN, 367 "Request Queue Overflow in isp_target_put_entry"); 368 return (-1); 369 } 370 switch (etype) { 371 case RQSTYPE_ATIO: --- 29 unchanged lines hidden (view full) --- 401 } atun; 402 403 MEMZERO(&atun, sizeof atun); 404 if (IS_FC(isp)) { 405 at2_entry_t *aep = arg; 406 atun._atio2.at_header.rqs_entry_type = RQSTYPE_ATIO2; 407 atun._atio2.at_header.rqs_entry_count = 1; 408 if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) { | 365 366 if (isp_getrqentry(isp, &nxti, &optr, &outp)) { 367 isp_prt(isp, ISP_LOGWARN, 368 "Request Queue Overflow in isp_target_put_entry"); 369 return (-1); 370 } 371 switch (etype) { 372 case RQSTYPE_ATIO: --- 29 unchanged lines hidden (view full) --- 402 } atun; 403 404 MEMZERO(&atun, sizeof atun); 405 if (IS_FC(isp)) { 406 at2_entry_t *aep = arg; 407 atun._atio2.at_header.rqs_entry_type = RQSTYPE_ATIO2; 408 atun._atio2.at_header.rqs_entry_count = 1; 409 if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) { |
409 atun._atio2.at_scclun = (u_int16_t) aep->at_scclun; | 410 atun._atio2.at_scclun = (uint16_t) aep->at_scclun; |
410 } else { | 411 } else { |
411 atun._atio2.at_lun = (u_int8_t) aep->at_lun; | 412 atun._atio2.at_lun = (uint8_t) aep->at_lun; |
412 } 413 if (IS_2KLOGIN(isp)) { 414 atun._atio2e.at_iid = ((at2e_entry_t *)aep)->at_iid; 415 } else { 416 atun._atio2.at_iid = aep->at_iid; 417 } 418 atun._atio2.at_rxid = aep->at_rxid; 419 atun._atio2.at_status = CT_OK; --- 27 unchanged lines hidden (view full) --- 447 * NB: inline SCSI sense reporting. As such, we lose this information. XXX. 448 * 449 * For both parallel && fibre channel, we use the feature that does 450 * an automatic resource autoreplenish so we don't have then later do 451 * put of an atio to replenish the f/w's resource count. 452 */ 453 454int | 413 } 414 if (IS_2KLOGIN(isp)) { 415 atun._atio2e.at_iid = ((at2e_entry_t *)aep)->at_iid; 416 } else { 417 atun._atio2.at_iid = aep->at_iid; 418 } 419 atun._atio2.at_rxid = aep->at_rxid; 420 atun._atio2.at_status = CT_OK; --- 27 unchanged lines hidden (view full) --- 448 * NB: inline SCSI sense reporting. As such, we lose this information. XXX. 449 * 450 * For both parallel && fibre channel, we use the feature that does 451 * an automatic resource autoreplenish so we don't have then later do 452 * put of an atio to replenish the f/w's resource count. 453 */ 454 455int |
455isp_endcmd(struct ispsoftc *isp, void *arg, u_int32_t code, u_int16_t hdl) | 456isp_endcmd(struct ispsoftc *isp, void *arg, uint32_t code, uint16_t hdl) |
456{ 457 int sts; 458 union { 459 ct_entry_t _ctio; 460 ct2_entry_t _ctio2; 461 ct2e_entry_t _ctio2e; 462 } un; 463 --- 140 unchanged lines hidden (view full) --- 604 * - abort: clean up the current command 605 * - abort tag and clear queue 606 */ 607 608static void 609isp_got_msg(struct ispsoftc *isp, in_entry_t *inp) 610{ 611 tmd_notify_t nt; | 457{ 458 int sts; 459 union { 460 ct_entry_t _ctio; 461 ct2_entry_t _ctio2; 462 ct2e_entry_t _ctio2e; 463 } un; 464 --- 140 unchanged lines hidden (view full) --- 605 * - abort: clean up the current command 606 * - abort tag and clear queue 607 */ 608 609static void 610isp_got_msg(struct ispsoftc *isp, in_entry_t *inp) 611{ 612 tmd_notify_t nt; |
612 u_int8_t status = inp->in_status & ~QLTM_SVALID; | 613 uint8_t status = inp->in_status & ~QLTM_SVALID; |
613 614 MEMZERO(&nt, sizeof (nt)); 615 nt.nt_hba = isp; 616 /* nt_str set in outer layers */ 617 nt.nt_iid = GET_IID_VAL(inp->in_iid); 618 nt.nt_tgt = inp->in_tgt; 619 nt.nt_lun = inp->in_lun; 620 IN_MAKE_TAGID(nt.nt_tagval, 0, inp); --- 63 unchanged lines hidden (view full) --- 684 } else { 685 nt.nt_lun = inp->in_lun; 686 } 687 IN_FC_MAKE_TAGID(nt.nt_tagval, 0, inp); 688 nt.nt_lreserved = inp; 689 690 if (inp->in_status != IN_MSG_RECEIVED) { 691 isp_prt(isp, ISP_LOGINFO, f2, "immediate notify status", | 614 615 MEMZERO(&nt, sizeof (nt)); 616 nt.nt_hba = isp; 617 /* nt_str set in outer layers */ 618 nt.nt_iid = GET_IID_VAL(inp->in_iid); 619 nt.nt_tgt = inp->in_tgt; 620 nt.nt_lun = inp->in_lun; 621 IN_MAKE_TAGID(nt.nt_tagval, 0, inp); --- 63 unchanged lines hidden (view full) --- 685 } else { 686 nt.nt_lun = inp->in_lun; 687 } 688 IN_FC_MAKE_TAGID(nt.nt_tagval, 0, inp); 689 nt.nt_lreserved = inp; 690 691 if (inp->in_status != IN_MSG_RECEIVED) { 692 isp_prt(isp, ISP_LOGINFO, f2, "immediate notify status", |
692 inp->in_status, nt.nt_lun, (u_int32_t) (nt.nt_iid >> 32), (u_int32_t) nt.nt_iid, | 693 inp->in_status, nt.nt_lun, (uint32_t) (nt.nt_iid >> 32), (uint32_t) nt.nt_iid, |
693 inp->in_task_flags, inp->in_seqid); 694 isp_notify_ack(isp, inp); 695 return; 696 } 697 698 if (inp->in_task_flags & TASK_FLAGS_ABORT_TASK_SET) { 699 isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK SET", | 694 inp->in_task_flags, inp->in_seqid); 695 isp_notify_ack(isp, inp); 696 return; 697 } 698 699 if (inp->in_task_flags & TASK_FLAGS_ABORT_TASK_SET) { 700 isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK SET", |
700 (u_int32_t) (nt.nt_iid >> 32), (u_int32_t) nt.nt_iid, nt.nt_lun, inp->in_seqid); | 701 (uint32_t) (nt.nt_iid >> 32), (uint32_t) nt.nt_iid, nt.nt_lun, inp->in_seqid); |
701 nt.nt_ncode = NT_ABORT_TASK_SET; 702 } else if (inp->in_task_flags & TASK_FLAGS_CLEAR_TASK_SET) { 703 isp_prt(isp, ISP_LOGINFO, f1, "CLEAR TASK SET", | 702 nt.nt_ncode = NT_ABORT_TASK_SET; 703 } else if (inp->in_task_flags & TASK_FLAGS_CLEAR_TASK_SET) { 704 isp_prt(isp, ISP_LOGINFO, f1, "CLEAR TASK SET", |
704 (u_int32_t) (nt.nt_iid >> 32), (u_int32_t) nt.nt_iid, nt.nt_lun, inp->in_seqid); | 705 (uint32_t) (nt.nt_iid >> 32), (uint32_t) nt.nt_iid, nt.nt_lun, inp->in_seqid); |
705 nt.nt_ncode = NT_CLEAR_TASK_SET; 706 } else if (inp->in_task_flags & TASK_FLAGS_LUN_RESET) { 707 isp_prt(isp, ISP_LOGINFO, f1, "LUN RESET", | 706 nt.nt_ncode = NT_CLEAR_TASK_SET; 707 } else if (inp->in_task_flags & TASK_FLAGS_LUN_RESET) { 708 isp_prt(isp, ISP_LOGINFO, f1, "LUN RESET", |
708 (u_int32_t) (nt.nt_iid >> 32), (u_int32_t) nt.nt_iid, nt.nt_lun, inp->in_seqid); | 709 (uint32_t) (nt.nt_iid >> 32), (uint32_t) nt.nt_iid, nt.nt_lun, inp->in_seqid); |
709 nt.nt_ncode = NT_LUN_RESET; 710 } else if (inp->in_task_flags & TASK_FLAGS_TARGET_RESET) { 711 isp_prt(isp, ISP_LOGINFO, f1, "TARGET RESET", | 710 nt.nt_ncode = NT_LUN_RESET; 711 } else if (inp->in_task_flags & TASK_FLAGS_TARGET_RESET) { 712 isp_prt(isp, ISP_LOGINFO, f1, "TARGET RESET", |
712 (u_int32_t) (nt.nt_iid >> 32), (u_int32_t) nt.nt_iid, nt.nt_lun, inp->in_seqid); | 713 (uint32_t) (nt.nt_iid >> 32), (uint32_t) nt.nt_iid, nt.nt_lun, inp->in_seqid); |
713 nt.nt_ncode = NT_TARGET_RESET; 714 } else if (inp->in_task_flags & TASK_FLAGS_CLEAR_ACA) { 715 isp_prt(isp, ISP_LOGINFO, f1, "CLEAR ACA", | 714 nt.nt_ncode = NT_TARGET_RESET; 715 } else if (inp->in_task_flags & TASK_FLAGS_CLEAR_ACA) { 716 isp_prt(isp, ISP_LOGINFO, f1, "CLEAR ACA", |
716 (u_int32_t) (nt.nt_iid >> 32), (u_int32_t) nt.nt_iid, nt.nt_lun, inp->in_seqid); | 717 (uint32_t) (nt.nt_iid >> 32), (uint32_t) nt.nt_iid, nt.nt_lun, inp->in_seqid); |
717 nt.nt_ncode = NT_CLEAR_ACA; 718 } else { 719 isp_prt(isp, ISP_LOGWARN, f2, "task flag", | 718 nt.nt_ncode = NT_CLEAR_ACA; 719 } else { 720 isp_prt(isp, ISP_LOGWARN, f2, "task flag", |
720 inp->in_status, nt.nt_lun, (u_int32_t) (nt.nt_iid >> 32), (u_int32_t) nt.nt_iid, | 721 inp->in_status, nt.nt_lun, (uint32_t) (nt.nt_iid >> 32), (uint32_t) nt.nt_iid, |
721 inp->in_task_flags, inp->in_seqid); 722 isp_notify_ack(isp, inp); 723 return; 724 } 725 (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &nt); 726} 727 728void 729isp_notify_ack(struct ispsoftc *isp, void *arg) 730{ 731 char storage[QENTRY_LEN]; | 722 inp->in_task_flags, inp->in_seqid); 723 isp_notify_ack(isp, inp); 724 return; 725 } 726 (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &nt); 727} 728 729void 730isp_notify_ack(struct ispsoftc *isp, void *arg) 731{ 732 char storage[QENTRY_LEN]; |
732 u_int16_t nxti, optr; | 733 uint16_t nxti, optr; |
733 void *outp; 734 735 if (isp_getrqentry(isp, &nxti, &optr, &outp)) { 736 isp_prt(isp, ISP_LOGWARN, 737 "Request Queue Overflow For isp_notify_ack"); 738 return; 739 } 740 --- 546 unchanged lines hidden --- | 734 void *outp; 735 736 if (isp_getrqentry(isp, &nxti, &optr, &outp)) { 737 isp_prt(isp, ISP_LOGWARN, 738 "Request Queue Overflow For isp_notify_ack"); 739 return; 740 } 741 --- 546 unchanged lines hidden --- |