isp.c (171014) | isp.c (171159) |
---|---|
1/*- 2 * Copyright (c) 1997-2007 by Matthew Jacob 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 * --- 32 unchanged lines hidden (view full) --- 41 */ 42#ifdef __NetBSD__ 43#include <sys/cdefs.h> 44__KERNEL_RCSID(0, "$NetBSD$"); 45#include <dev/ic/isp_netbsd.h> 46#endif 47#ifdef __FreeBSD__ 48#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1997-2007 by Matthew Jacob 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 * --- 32 unchanged lines hidden (view full) --- 41 */ 42#ifdef __NetBSD__ 43#include <sys/cdefs.h> 44__KERNEL_RCSID(0, "$NetBSD$"); 45#include <dev/ic/isp_netbsd.h> 46#endif 47#ifdef __FreeBSD__ 48#include <sys/cdefs.h> |
49__FBSDID("$FreeBSD: head/sys/dev/isp/isp.c 171014 2007-06-24 01:41:16Z mjacob $"); | 49__FBSDID("$FreeBSD: head/sys/dev/isp/isp.c 171159 2007-07-02 20:08:20Z mjacob $"); |
50#include <dev/isp/isp_freebsd.h> 51#endif 52#ifdef __OpenBSD__ 53#include <dev/ic/isp_openbsd.h> 54#endif 55#ifdef __linux__ 56#include "isp_linux.h" 57#endif --- 4199 unchanged lines hidden (view full) --- 4257 isp_destroy_handle(isp, handle); 4258 /* 4259 * dmasetup sets actual error in packet, and 4260 * return what we were given to return. 4261 */ 4262 return (i); 4263 } 4264 XS_SETERR(xs, HBA_NOERROR); | 50#include <dev/isp/isp_freebsd.h> 51#endif 52#ifdef __OpenBSD__ 53#include <dev/ic/isp_openbsd.h> 54#endif 55#ifdef __linux__ 56#include "isp_linux.h" 57#endif --- 4199 unchanged lines hidden (view full) --- 4257 isp_destroy_handle(isp, handle); 4258 /* 4259 * dmasetup sets actual error in packet, and 4260 * return what we were given to return. 4261 */ 4262 return (i); 4263 } 4264 XS_SETERR(xs, HBA_NOERROR); |
4265 isp_prt(isp, ISP_LOGDEBUG2, | 4265 isp_prt(isp, ISP_LOGDEBUG0, |
4266 "START cmd for %d.%d.%d cmd 0x%x datalen %ld", 4267 XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), XS_CDBP(xs)[0], 4268 (long) XS_XFRLEN(xs)); 4269 ISP_ADD_REQUEST(isp, nxti); 4270 isp->isp_nactive++; 4271 return (CMD_QUEUED); 4272} 4273 --- 460 unchanged lines hidden (view full) --- 4734 4735 /* 4736 * Synchronize our view of this response queue entry. 4737 */ 4738 MEMORYBARRIER(isp, SYNC_RESULT, oop, QENTRY_LEN); 4739 isp_get_hdr(isp, hp, &sp->req_header); 4740 etype = sp->req_header.rqs_entry_type; 4741 | 4266 "START cmd for %d.%d.%d cmd 0x%x datalen %ld", 4267 XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), XS_CDBP(xs)[0], 4268 (long) XS_XFRLEN(xs)); 4269 ISP_ADD_REQUEST(isp, nxti); 4270 isp->isp_nactive++; 4271 return (CMD_QUEUED); 4272} 4273 --- 460 unchanged lines hidden (view full) --- 4734 4735 /* 4736 * Synchronize our view of this response queue entry. 4737 */ 4738 MEMORYBARRIER(isp, SYNC_RESULT, oop, QENTRY_LEN); 4739 isp_get_hdr(isp, hp, &sp->req_header); 4740 etype = sp->req_header.rqs_entry_type; 4741 |
4742 if (IS_24XX(isp) && etype == RQSTYPE_T7RQS) { | 4742 if (IS_24XX(isp) && etype == RQSTYPE_RESPONSE) { |
4743 isp24xx_statusreq_t *sp2 = (isp24xx_statusreq_t *)qe; 4744 isp_get_24xx_response(isp, 4745 (isp24xx_statusreq_t *)hp, sp2); 4746 if (isp->isp_dblev & ISP_LOGDEBUG1) { 4747 isp_print_bytes(isp, 4748 "Response Queue Entry", QENTRY_LEN, sp2); 4749 } 4750 scsi_status = sp2->req_scsi_status; --- 133 unchanged lines hidden (view full) --- 4884 if (buddaboom) { 4885 XS_SETERR(xs, HBA_BOTCH); 4886 } 4887 4888 resp = NULL; 4889 rlen = 0; 4890 snsp = NULL; 4891 slen = 0; | 4743 isp24xx_statusreq_t *sp2 = (isp24xx_statusreq_t *)qe; 4744 isp_get_24xx_response(isp, 4745 (isp24xx_statusreq_t *)hp, sp2); 4746 if (isp->isp_dblev & ISP_LOGDEBUG1) { 4747 isp_print_bytes(isp, 4748 "Response Queue Entry", QENTRY_LEN, sp2); 4749 } 4750 scsi_status = sp2->req_scsi_status; --- 133 unchanged lines hidden (view full) --- 4884 if (buddaboom) { 4885 XS_SETERR(xs, HBA_BOTCH); 4886 } 4887 4888 resp = NULL; 4889 rlen = 0; 4890 snsp = NULL; 4891 slen = 0; |
4892 if (IS_24XX(isp) && (scsi_status & RQCS_RV) != 0) { | 4892 if (IS_24XX(isp) && (scsi_status & (RQCS_RV|RQCS_SV)) != 0) { |
4893 resp = ((isp24xx_statusreq_t *)sp)->req_rsp_sense; 4894 rlen = ((isp24xx_statusreq_t *)sp)->req_response_len; 4895 } else if (IS_FC(isp) && (scsi_status & RQCS_RV) != 0) { 4896 resp = sp->req_response; 4897 rlen = sp->req_response_len; 4898 } 4899 if (IS_FC(isp) && (scsi_status & RQCS_SV) != 0) { 4900 /* --- 21 unchanged lines hidden (view full) --- 4922 } 4923 4924 switch (etype) { 4925 case RQSTYPE_RESPONSE: 4926 XS_SET_STATE_STAT(isp, xs, sp); 4927 if (resp && rlen >= 4 && 4928 resp[FCP_RSPNS_CODE_OFFSET] != 0) { 4929 isp_prt(isp, ISP_LOGWARN, | 4893 resp = ((isp24xx_statusreq_t *)sp)->req_rsp_sense; 4894 rlen = ((isp24xx_statusreq_t *)sp)->req_response_len; 4895 } else if (IS_FC(isp) && (scsi_status & RQCS_RV) != 0) { 4896 resp = sp->req_response; 4897 rlen = sp->req_response_len; 4898 } 4899 if (IS_FC(isp) && (scsi_status & RQCS_SV) != 0) { 4900 /* --- 21 unchanged lines hidden (view full) --- 4922 } 4923 4924 switch (etype) { 4925 case RQSTYPE_RESPONSE: 4926 XS_SET_STATE_STAT(isp, xs, sp); 4927 if (resp && rlen >= 4 && 4928 resp[FCP_RSPNS_CODE_OFFSET] != 0) { 4929 isp_prt(isp, ISP_LOGWARN, |
4930 "%d.%d FCP RESPONSE: 0x%x", 4931 XS_TGT(xs), XS_LUN(xs), | 4930 "%d.%d.%d FCP RESPONSE: 0x%x", 4931 XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), |
4932 resp[FCP_RSPNS_CODE_OFFSET]); 4933 XS_SETERR(xs, HBA_BOTCH); 4934 } 4935 if (IS_24XX(isp)) { 4936 isp_parse_status_24xx(isp, 4937 (isp24xx_statusreq_t *)sp, xs, &resid); 4938 } else { 4939 isp_parse_status(isp, (void *)sp, xs, &resid); --- 64 unchanged lines hidden (view full) --- 5004 if (XS_NOERR(xs)) { 5005 XS_SETERR(xs, HBA_BOTCH); 5006 } 5007 break; 5008 } 5009 5010 /* 5011 * Free any DMA resources. As a side effect, this may | 4932 resp[FCP_RSPNS_CODE_OFFSET]); 4933 XS_SETERR(xs, HBA_BOTCH); 4934 } 4935 if (IS_24XX(isp)) { 4936 isp_parse_status_24xx(isp, 4937 (isp24xx_statusreq_t *)sp, xs, &resid); 4938 } else { 4939 isp_parse_status(isp, (void *)sp, xs, &resid); --- 64 unchanged lines hidden (view full) --- 5004 if (XS_NOERR(xs)) { 5005 XS_SETERR(xs, HBA_BOTCH); 5006 } 5007 break; 5008 } 5009 5010 /* 5011 * Free any DMA resources. As a side effect, this may |
5012 * also do any cache flushing necessary for data coherence. */ | 5012 * also do any cache flushing necessary for data coherence. 5013 */ |
5013 if (XS_XFRLEN(xs)) { 5014 ISP_DMAFREE(isp, xs, sp->req_handle); 5015 } 5016 5017 if (((isp->isp_dblev & (ISP_LOGDEBUG2|ISP_LOGDEBUG3))) || | 5014 if (XS_XFRLEN(xs)) { 5015 ISP_DMAFREE(isp, xs, sp->req_handle); 5016 } 5017 5018 if (((isp->isp_dblev & (ISP_LOGDEBUG2|ISP_LOGDEBUG3))) || |
5018 ((isp->isp_dblev & ISP_LOGDEBUG1) && ((!XS_NOERR(xs)) || | 5019 ((isp->isp_dblev & ISP_LOGDEBUG0) && ((!XS_NOERR(xs)) || |
5019 (*XS_STSP(xs) != SCSI_GOOD)))) { 5020 char skey; 5021 if (req_state_flags & RQSF_GOT_SENSE) { 5022 skey = XS_SNSKEY(xs) & 0xf; 5023 if (skey < 10) 5024 skey += '0'; 5025 else 5026 skey += 'a' - 10; --- 865 unchanged lines hidden (view full) --- 5892 XS_SETERR(xs, HBA_BOTCH); 5893 } 5894} 5895 5896static void 5897isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp, 5898 XS_T *xs, long *rp) 5899{ | 5020 (*XS_STSP(xs) != SCSI_GOOD)))) { 5021 char skey; 5022 if (req_state_flags & RQSF_GOT_SENSE) { 5023 skey = XS_SNSKEY(xs) & 0xf; 5024 if (skey < 10) 5025 skey += '0'; 5026 else 5027 skey += 'a' - 10; --- 865 unchanged lines hidden (view full) --- 5893 XS_SETERR(xs, HBA_BOTCH); 5894 } 5895} 5896 5897static void 5898isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp, 5899 XS_T *xs, long *rp) 5900{ |
5901 int ru_marked, sv_marked; |
|
5900 switch (sp->req_completion_status) { 5901 case RQCS_COMPLETE: 5902 if (XS_NOERR(xs)) { 5903 XS_SETERR(xs, HBA_NOERROR); 5904 } 5905 return; 5906 5907 case RQCS_DMA_ERROR: --- 30 unchanged lines hidden (view full) --- 5938 XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); 5939 if (XS_NOERR(xs)) { 5940 XS_SETERR(xs, HBA_CMDTIMEOUT); 5941 } 5942 return; 5943 5944 case RQCS_DATA_OVERRUN: 5945 XS_RESID(xs) = sp->req_resid; | 5902 switch (sp->req_completion_status) { 5903 case RQCS_COMPLETE: 5904 if (XS_NOERR(xs)) { 5905 XS_SETERR(xs, HBA_NOERROR); 5906 } 5907 return; 5908 5909 case RQCS_DMA_ERROR: --- 30 unchanged lines hidden (view full) --- 5940 XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); 5941 if (XS_NOERR(xs)) { 5942 XS_SETERR(xs, HBA_CMDTIMEOUT); 5943 } 5944 return; 5945 5946 case RQCS_DATA_OVERRUN: 5947 XS_RESID(xs) = sp->req_resid; |
5946 isp_prt(isp, ISP_LOGERR, "data overrun for command on %d.%d.%d", | 5948 isp_prt(isp, ISP_LOGERR, 5949 "data overrun for command on %d.%d.%d", |
5947 XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); 5948 if (XS_NOERR(xs)) { 5949 XS_SETERR(xs, HBA_DATAOVR); 5950 } 5951 return; 5952 5953 case RQCS_24XX_DRE: /* data reassembly error */ 5954 isp_prt(isp, ISP_LOGERR, "data reassembly error for target %d", --- 8 unchanged lines hidden (view full) --- 5963 isp_prt(isp, ISP_LOGERR, "target %d sent ABTS", 5964 XS_TGT(xs)); 5965 if (XS_NOERR(xs)) { 5966 XS_SETERR(xs, HBA_ABORTED); 5967 } 5968 return; 5969 5970 case RQCS_DATA_UNDERRUN: | 5950 XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); 5951 if (XS_NOERR(xs)) { 5952 XS_SETERR(xs, HBA_DATAOVR); 5953 } 5954 return; 5955 5956 case RQCS_24XX_DRE: /* data reassembly error */ 5957 isp_prt(isp, ISP_LOGERR, "data reassembly error for target %d", --- 8 unchanged lines hidden (view full) --- 5966 isp_prt(isp, ISP_LOGERR, "target %d sent ABTS", 5967 XS_TGT(xs)); 5968 if (XS_NOERR(xs)) { 5969 XS_SETERR(xs, HBA_ABORTED); 5970 } 5971 return; 5972 5973 case RQCS_DATA_UNDERRUN: |
5971 | 5974 ru_marked = (sp->req_scsi_status & RQCS_RU) != 0; 5975 /* 5976 * We can get an underrun w/o things being marked 5977 * if we got a non-zero status. 5978 */ 5979 sv_marked = (sp->req_scsi_status & (RQCS_SV|RQCS_RV)) != 0; 5980 if ((ru_marked == 0 && sv_marked == 0) || 5981 (sp->req_resid > XS_XFRLEN(xs))) { 5982 isp_prt(isp, ISP_LOGWARN, bun, XS_TGT(xs), 5983 XS_LUN(xs), XS_XFRLEN(xs), sp->req_resid, 5984 (ru_marked)? "marked" : "not marked"); 5985 if (XS_NOERR(xs)) { 5986 XS_SETERR(xs, HBA_BOTCH); 5987 } 5988 return; 5989 } |
5972 XS_RESID(xs) = sp->req_resid; | 5990 XS_RESID(xs) = sp->req_resid; |
5991 isp_prt(isp, ISP_LOGDEBUG0, 5992 "%d.%d.%d data underrun (%d) for command 0x%x", 5993 XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), 5994 sp->req_resid, XS_CDBP(xs)[0] & 0xff); |
|
5973 if (XS_NOERR(xs)) { 5974 XS_SETERR(xs, HBA_NOERROR); 5975 } 5976 return; 5977 5978 case RQCS_PORT_UNAVAILABLE: 5979 /* 5980 * No such port on the loop. Moral equivalent of SELTIMEO --- 1426 unchanged lines hidden (view full) --- 7407 } 7408 7409 dptr = (uint32_t *) nvram_data; 7410 for (lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) { 7411 isp_rd_2400_nvram(isp, addr++, dptr++); 7412 } 7413 if (nvram_data[0] != 'I' || nvram_data[1] != 'S' || 7414 nvram_data[2] != 'P') { | 5995 if (XS_NOERR(xs)) { 5996 XS_SETERR(xs, HBA_NOERROR); 5997 } 5998 return; 5999 6000 case RQCS_PORT_UNAVAILABLE: 6001 /* 6002 * No such port on the loop. Moral equivalent of SELTIMEO --- 1426 unchanged lines hidden (view full) --- 7429 } 7430 7431 dptr = (uint32_t *) nvram_data; 7432 for (lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) { 7433 isp_rd_2400_nvram(isp, addr++, dptr++); 7434 } 7435 if (nvram_data[0] != 'I' || nvram_data[1] != 'S' || 7436 nvram_data[2] != 'P') { |
7415 isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header"); | 7437 isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header (%x %x %x)", 7438 nvram_data[0], nvram_data[1], nvram_data[2]); |
7416 retval = -1; 7417 goto out; 7418 } 7419 dptr = (uint32_t *) nvram_data; 7420 for (csum = 0, lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) { | 7439 retval = -1; 7440 goto out; 7441 } 7442 dptr = (uint32_t *) nvram_data; 7443 for (csum = 0, lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) { |
7421 csum += dptr[lwrds]; | 7444 uint32_t tmp; 7445 ISP_IOXGET_32(isp, &dptr[lwrds], tmp); 7446 csum += tmp; |
7422 } 7423 if (csum != 0) { 7424 isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum"); 7425 retval = -1; 7426 goto out; 7427 } 7428 isp_parse_nvram_2400(isp, nvram_data); 7429out: --- 82 unchanged lines hidden (view full) --- 7512 for (loops = 0; loops < 5000; loops++) { 7513 USEC_DELAY(10); 7514 tmp = ISP_READ(isp, BIU2400_FLASH_ADDR); 7515 if ((tmp & (1U << 31)) != 0) { 7516 break; 7517 } 7518 } 7519 if (tmp & (1U << 31)) { | 7447 } 7448 if (csum != 0) { 7449 isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum"); 7450 retval = -1; 7451 goto out; 7452 } 7453 isp_parse_nvram_2400(isp, nvram_data); 7454out: --- 82 unchanged lines hidden (view full) --- 7537 for (loops = 0; loops < 5000; loops++) { 7538 USEC_DELAY(10); 7539 tmp = ISP_READ(isp, BIU2400_FLASH_ADDR); 7540 if ((tmp & (1U << 31)) != 0) { 7541 break; 7542 } 7543 } 7544 if (tmp & (1U << 31)) { |
7520 tmp = ISP_READ(isp, BIU2400_FLASH_DATA); 7521 *rp = tmp; | 7545 *rp = ISP_READ(isp, BIU2400_FLASH_DATA); 7546 ISP_SWIZZLE_NVRAM_LONG(isp, rp); |
7522 } else { 7523 *rp = 0xffffffff; 7524 } 7525} 7526 7527static void 7528isp_parse_nvram_1020(ispsoftc_t *isp, uint8_t *nvram_data) 7529{ --- 792 unchanged lines hidden --- | 7547 } else { 7548 *rp = 0xffffffff; 7549 } 7550} 7551 7552static void 7553isp_parse_nvram_1020(ispsoftc_t *isp, uint8_t *nvram_data) 7554{ --- 792 unchanged lines hidden --- |