isp_sbus.c (155251) | isp_sbus.c (155704) |
---|---|
1/*- 2 * PCI specific probe and attach routines for Qlogic ISP SCSI adapters. 3 * FreeBSD Version. 4 * 5 * Copyright (c) 1997-2006 by Matthew Jacob 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 14 unchanged lines hidden (view full) --- 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30#include <sys/cdefs.h> | 1/*- 2 * PCI specific probe and attach routines for Qlogic ISP SCSI adapters. 3 * FreeBSD Version. 4 * 5 * Copyright (c) 1997-2006 by Matthew Jacob 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 14 unchanged lines hidden (view full) --- 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30#include <sys/cdefs.h> |
31__FBSDID("$FreeBSD: head/sys/dev/isp/isp_sbus.c 155251 2006-02-03 12:35:42Z marius $"); | 31__FBSDID("$FreeBSD: head/sys/dev/isp/isp_sbus.c 155704 2006-02-15 00:31:48Z mjacob $"); |
32 33#include <sys/param.h> 34#include <sys/systm.h> 35#include <sys/bus.h> 36#include <sys/kernel.h> 37#include <sys/module.h> 38#include <sys/resource.h> 39 40#include <dev/ofw/ofw_bus.h> 41 42#include <machine/bus.h> 43#include <machine/resource.h> 44#include <sys/rman.h> 45#include <sparc64/sbus/sbusvar.h> 46 47#include <dev/isp/isp_freebsd.h> 48 | 32 33#include <sys/param.h> 34#include <sys/systm.h> 35#include <sys/bus.h> 36#include <sys/kernel.h> 37#include <sys/module.h> 38#include <sys/resource.h> 39 40#include <dev/ofw/ofw_bus.h> 41 42#include <machine/bus.h> 43#include <machine/resource.h> 44#include <sys/rman.h> 45#include <sparc64/sbus/sbusvar.h> 46 47#include <dev/isp/isp_freebsd.h> 48 |
49static u_int16_t isp_sbus_rd_reg(struct ispsoftc *, int); 50static void isp_sbus_wr_reg(struct ispsoftc *, int, u_int16_t); | 49static uint16_t isp_sbus_rd_reg(struct ispsoftc *, int); 50static void isp_sbus_wr_reg(struct ispsoftc *, int, uint16_t); |
51static int | 51static int |
52isp_sbus_rd_isr(struct ispsoftc *, u_int16_t *, u_int16_t *, u_int16_t *); | 52isp_sbus_rd_isr(struct ispsoftc *, uint16_t *, uint16_t *, uint16_t *); |
53static int isp_sbus_mbxdma(struct ispsoftc *); 54static int | 53static int isp_sbus_mbxdma(struct ispsoftc *); 54static int |
55isp_sbus_dmasetup(struct ispsoftc *, XS_T *, ispreq_t *, u_int16_t *, u_int16_t); | 55isp_sbus_dmasetup(struct ispsoftc *, XS_T *, ispreq_t *, uint16_t *, uint16_t); |
56static void | 56static void |
57isp_sbus_dmateardown(struct ispsoftc *, XS_T *, u_int16_t); | 57isp_sbus_dmateardown(struct ispsoftc *, XS_T *, uint16_t); |
58 59static void isp_sbus_reset1(struct ispsoftc *); 60static void isp_sbus_dumpregs(struct ispsoftc *, const char *); 61 62static struct ispmdvec mdvec = { 63 isp_sbus_rd_isr, 64 isp_sbus_rd_reg, 65 isp_sbus_wr_reg, --- 303 unchanged lines hidden (view full) --- 369 */ 370 return (ENXIO); 371} 372 373static void 374isp_sbus_intr(void *arg) 375{ 376 struct ispsoftc *isp = arg; | 58 59static void isp_sbus_reset1(struct ispsoftc *); 60static void isp_sbus_dumpregs(struct ispsoftc *, const char *); 61 62static struct ispmdvec mdvec = { 63 isp_sbus_rd_isr, 64 isp_sbus_rd_reg, 65 isp_sbus_wr_reg, --- 303 unchanged lines hidden (view full) --- 369 */ 370 return (ENXIO); 371} 372 373static void 374isp_sbus_intr(void *arg) 375{ 376 struct ispsoftc *isp = arg; |
377 u_int16_t isr, sema, mbox; | 377 uint16_t isr, sema, mbox; |
378 379 ISP_LOCK(isp); 380 isp->isp_intcnt++; 381 if (ISP_READ_ISR(isp, &isr, &sema, &mbox) == 0) { 382 isp->isp_intbogus++; 383 } else { 384 int iok = isp->isp_osinfo.intsok; 385 isp->isp_osinfo.intsok = 0; --- 6 unchanged lines hidden (view full) --- 392#define IspVirt2Off(a, x) \ 393 (((struct isp_sbussoftc *)a)->sbus_poff[((x) & _BLK_REG_MASK) >> \ 394 _BLK_REG_SHFT] + ((x) & 0xff)) 395 396#define BXR2(sbc, off) \ 397 bus_space_read_2(sbc->sbus_st, sbc->sbus_sh, off) 398 399static int | 378 379 ISP_LOCK(isp); 380 isp->isp_intcnt++; 381 if (ISP_READ_ISR(isp, &isr, &sema, &mbox) == 0) { 382 isp->isp_intbogus++; 383 } else { 384 int iok = isp->isp_osinfo.intsok; 385 isp->isp_osinfo.intsok = 0; --- 6 unchanged lines hidden (view full) --- 392#define IspVirt2Off(a, x) \ 393 (((struct isp_sbussoftc *)a)->sbus_poff[((x) & _BLK_REG_MASK) >> \ 394 _BLK_REG_SHFT] + ((x) & 0xff)) 395 396#define BXR2(sbc, off) \ 397 bus_space_read_2(sbc->sbus_st, sbc->sbus_sh, off) 398 399static int |
400isp_sbus_rd_isr(struct ispsoftc *isp, u_int16_t *isrp, 401 u_int16_t *semap, u_int16_t *mbp) | 400isp_sbus_rd_isr(struct ispsoftc *isp, uint16_t *isrp, 401 uint16_t *semap, uint16_t *mbp) |
402{ 403 struct isp_sbussoftc *sbc = (struct isp_sbussoftc *) isp; | 402{ 403 struct isp_sbussoftc *sbc = (struct isp_sbussoftc *) isp; |
404 u_int16_t isr, sema; | 404 uint16_t isr, sema; |
405 406 isr = BXR2(sbc, IspVirt2Off(isp, BIU_ISR)); 407 sema = BXR2(sbc, IspVirt2Off(isp, BIU_SEMA)); 408 isp_prt(isp, ISP_LOGDEBUG3, "ISR 0x%x SEMA 0x%x", isr, sema); 409 isr &= INT_PENDING_MASK(isp); 410 sema &= BIU_SEMA_LOCK; 411 if (isr == 0 && sema == 0) { 412 return (0); 413 } 414 *isrp = isr; 415 if ((*semap = sema) != 0) { 416 *mbp = BXR2(sbc, IspVirt2Off(isp, OUTMAILBOX0)); 417 } 418 return (1); 419} 420 | 405 406 isr = BXR2(sbc, IspVirt2Off(isp, BIU_ISR)); 407 sema = BXR2(sbc, IspVirt2Off(isp, BIU_SEMA)); 408 isp_prt(isp, ISP_LOGDEBUG3, "ISR 0x%x SEMA 0x%x", isr, sema); 409 isr &= INT_PENDING_MASK(isp); 410 sema &= BIU_SEMA_LOCK; 411 if (isr == 0 && sema == 0) { 412 return (0); 413 } 414 *isrp = isr; 415 if ((*semap = sema) != 0) { 416 *mbp = BXR2(sbc, IspVirt2Off(isp, OUTMAILBOX0)); 417 } 418 return (1); 419} 420 |
421static u_int16_t | 421static uint16_t |
422isp_sbus_rd_reg(struct ispsoftc *isp, int regoff) 423{ | 422isp_sbus_rd_reg(struct ispsoftc *isp, int regoff) 423{ |
424 u_int16_t rval; | 424 uint16_t rval; |
425 struct isp_sbussoftc *sbs = (struct isp_sbussoftc *) isp; 426 int offset = sbs->sbus_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT]; 427 offset += (regoff & 0xff); 428 rval = bus_space_read_2(sbs->sbus_st, sbs->sbus_sh, offset); 429 isp_prt(isp, ISP_LOGDEBUG3, 430 "isp_sbus_rd_reg(off %x) = %x", regoff, rval); 431 return (rval); 432} 433 434static void | 425 struct isp_sbussoftc *sbs = (struct isp_sbussoftc *) isp; 426 int offset = sbs->sbus_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT]; 427 offset += (regoff & 0xff); 428 rval = bus_space_read_2(sbs->sbus_st, sbs->sbus_sh, offset); 429 isp_prt(isp, ISP_LOGDEBUG3, 430 "isp_sbus_rd_reg(off %x) = %x", regoff, rval); 431 return (rval); 432} 433 434static void |
435isp_sbus_wr_reg(struct ispsoftc *isp, int regoff, u_int16_t val) | 435isp_sbus_wr_reg(struct ispsoftc *isp, int regoff, uint16_t val) |
436{ 437 struct isp_sbussoftc *sbs = (struct isp_sbussoftc *) isp; 438 int offset = sbs->sbus_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT]; 439 offset += (regoff & 0xff); 440 isp_prt(isp, ISP_LOGDEBUG3, 441 "isp_sbus_wr_reg(off %x) = %x", regoff, val); 442 bus_space_write_2(sbs->sbus_st, sbs->sbus_sh, offset, val); 443} --- 26 unchanged lines hidden (view full) --- 470 */ 471#define ISP_NSEGS ((MAXPHYS / PAGE_SIZE) + 1) 472 473static int 474isp_sbus_mbxdma(struct ispsoftc *isp) 475{ 476 struct isp_sbussoftc *sbs = (struct isp_sbussoftc *)isp; 477 caddr_t base; | 436{ 437 struct isp_sbussoftc *sbs = (struct isp_sbussoftc *) isp; 438 int offset = sbs->sbus_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT]; 439 offset += (regoff & 0xff); 440 isp_prt(isp, ISP_LOGDEBUG3, 441 "isp_sbus_wr_reg(off %x) = %x", regoff, val); 442 bus_space_write_2(sbs->sbus_st, sbs->sbus_sh, offset, val); 443} --- 26 unchanged lines hidden (view full) --- 470 */ 471#define ISP_NSEGS ((MAXPHYS / PAGE_SIZE) + 1) 472 473static int 474isp_sbus_mbxdma(struct ispsoftc *isp) 475{ 476 struct isp_sbussoftc *sbs = (struct isp_sbussoftc *)isp; 477 caddr_t base; |
478 u_int32_t len; | 478 uint32_t len; |
479 int i, error, ns; 480 struct imush im; 481 482 /* 483 * Already been here? If so, leave... 484 */ 485 if (isp->isp_rquest) { 486 return (0); --- 93 unchanged lines hidden (view full) --- 580 isp->isp_rquest = NULL; 581 return (1); 582} 583 584typedef struct { 585 struct ispsoftc *isp; 586 void *cmd_token; 587 void *rq; | 479 int i, error, ns; 480 struct imush im; 481 482 /* 483 * Already been here? If so, leave... 484 */ 485 if (isp->isp_rquest) { 486 return (0); --- 93 unchanged lines hidden (view full) --- 580 isp->isp_rquest = NULL; 581 return (1); 582} 583 584typedef struct { 585 struct ispsoftc *isp; 586 void *cmd_token; 587 void *rq; |
588 u_int16_t *nxtip; 589 u_int16_t optr; 590 u_int error; | 588 uint16_t *nxtip; 589 uint16_t optr; 590 int error; |
591} mush_t; 592 593#define MUSHERR_NOQENTRIES -2 594 595 596static void dma2(void *, bus_dma_segment_t *, int, int); 597 598static void 599dma2(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error) 600{ 601 mush_t *mp; 602 struct ispsoftc *isp; 603 struct ccb_scsiio *csio; 604 struct isp_sbussoftc *sbs; 605 bus_dmamap_t *dp; 606 bus_dma_segment_t *eseg; 607 ispreq_t *rq; 608 int seglim, datalen; | 591} mush_t; 592 593#define MUSHERR_NOQENTRIES -2 594 595 596static void dma2(void *, bus_dma_segment_t *, int, int); 597 598static void 599dma2(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error) 600{ 601 mush_t *mp; 602 struct ispsoftc *isp; 603 struct ccb_scsiio *csio; 604 struct isp_sbussoftc *sbs; 605 bus_dmamap_t *dp; 606 bus_dma_segment_t *eseg; 607 ispreq_t *rq; 608 int seglim, datalen; |
609 u_int16_t nxti; | 609 uint16_t nxti; |
610 611 mp = (mush_t *) arg; 612 if (error) { 613 mp->error = error; 614 return; 615 } 616 617 if (nseg < 1) { --- 43 unchanged lines hidden (view full) --- 661 rq->req_dataseg[rq->req_seg_count].ds_base = dm_segs->ds_addr; 662 rq->req_dataseg[rq->req_seg_count].ds_count = dm_segs->ds_len; 663 datalen -= dm_segs->ds_len; 664 rq->req_seg_count++; 665 dm_segs++; 666 } 667 668 while (datalen > 0 && dm_segs != eseg) { | 610 611 mp = (mush_t *) arg; 612 if (error) { 613 mp->error = error; 614 return; 615 } 616 617 if (nseg < 1) { --- 43 unchanged lines hidden (view full) --- 661 rq->req_dataseg[rq->req_seg_count].ds_base = dm_segs->ds_addr; 662 rq->req_dataseg[rq->req_seg_count].ds_count = dm_segs->ds_len; 663 datalen -= dm_segs->ds_len; 664 rq->req_seg_count++; 665 dm_segs++; 666 } 667 668 while (datalen > 0 && dm_segs != eseg) { |
669 u_int16_t onxti; | 669 uint16_t onxti; |
670 ispcontreq_t local, *crq = &local, *cqe; 671 672 cqe = (ispcontreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, nxti); 673 onxti = nxti; 674 nxti = ISP_NXT_QENTRY(onxti, RQUEST_QUEUE_LEN(isp)); 675 if (nxti == mp->optr) { 676 isp_prt(isp, ISP_LOGDEBUG0, "Request Queue Overflow++"); 677 mp->error = MUSHERR_NOQENTRIES; --- 18 unchanged lines hidden (view full) --- 696 isp_put_cont_req(isp, crq, cqe); 697 MEMORYBARRIER(isp, SYNC_REQUEST, onxti, QENTRY_LEN); 698 } 699 *mp->nxtip = nxti; 700} 701 702static int 703isp_sbus_dmasetup(struct ispsoftc *isp, struct ccb_scsiio *csio, ispreq_t *rq, | 670 ispcontreq_t local, *crq = &local, *cqe; 671 672 cqe = (ispcontreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, nxti); 673 onxti = nxti; 674 nxti = ISP_NXT_QENTRY(onxti, RQUEST_QUEUE_LEN(isp)); 675 if (nxti == mp->optr) { 676 isp_prt(isp, ISP_LOGDEBUG0, "Request Queue Overflow++"); 677 mp->error = MUSHERR_NOQENTRIES; --- 18 unchanged lines hidden (view full) --- 696 isp_put_cont_req(isp, crq, cqe); 697 MEMORYBARRIER(isp, SYNC_REQUEST, onxti, QENTRY_LEN); 698 } 699 *mp->nxtip = nxti; 700} 701 702static int 703isp_sbus_dmasetup(struct ispsoftc *isp, struct ccb_scsiio *csio, ispreq_t *rq, |
704 u_int16_t *nxtip, u_int16_t optr) | 704 uint16_t *nxtip, uint16_t optr) |
705{ 706 struct isp_sbussoftc *sbs = (struct isp_sbussoftc *)isp; 707 ispreq_t *qep; 708 bus_dmamap_t *dp = NULL; 709 mush_t mush, *mp; 710 void (*eptr)(void *, bus_dma_segment_t *, int, int); 711 712 qep = (ispreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, isp->isp_reqidx); --- 84 unchanged lines hidden (view full) --- 797 isp_put_extended_request(isp, (ispextreq_t *)rq, 798 (ispextreq_t *)qep); 799 break; 800 } 801 return (CMD_QUEUED); 802} 803 804static void | 705{ 706 struct isp_sbussoftc *sbs = (struct isp_sbussoftc *)isp; 707 ispreq_t *qep; 708 bus_dmamap_t *dp = NULL; 709 mush_t mush, *mp; 710 void (*eptr)(void *, bus_dma_segment_t *, int, int); 711 712 qep = (ispreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, isp->isp_reqidx); --- 84 unchanged lines hidden (view full) --- 797 isp_put_extended_request(isp, (ispextreq_t *)rq, 798 (ispextreq_t *)qep); 799 break; 800 } 801 return (CMD_QUEUED); 802} 803 804static void |
805isp_sbus_dmateardown(struct ispsoftc *isp, XS_T *xs, u_int16_t handle) | 805isp_sbus_dmateardown(struct ispsoftc *isp, XS_T *xs, uint16_t handle) |
806{ 807 struct isp_sbussoftc *sbs = (struct isp_sbussoftc *)isp; 808 bus_dmamap_t *dp = &sbs->dmaps[isp_handle_index(handle)]; 809 if ((xs->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { 810 bus_dmamap_sync(sbs->dmat, *dp, BUS_DMASYNC_POSTREAD); 811 } else { 812 bus_dmamap_sync(sbs->dmat, *dp, BUS_DMASYNC_POSTWRITE); 813 } --- 41 unchanged lines hidden --- | 806{ 807 struct isp_sbussoftc *sbs = (struct isp_sbussoftc *)isp; 808 bus_dmamap_t *dp = &sbs->dmaps[isp_handle_index(handle)]; 809 if ((xs->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { 810 bus_dmamap_sync(sbs->dmat, *dp, BUS_DMASYNC_POSTREAD); 811 } else { 812 bus_dmamap_sync(sbs->dmat, *dp, BUS_DMASYNC_POSTWRITE); 813 } --- 41 unchanged lines hidden --- |