Deleted Added
full compact
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 ---