summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authormjacob <mjacob@FreeBSD.org>1999-11-21 02:56:17 +0000
committermjacob <mjacob@FreeBSD.org>1999-11-21 02:56:17 +0000
commitb2895f817ad56cf7b76b6cb00b5b0de2cf91a581 (patch)
tree243bf38bc41f8608a74d5e17d3d1333666aa1a09 /sys
parentbdad2b18b405a0a3245e73849d17fa0d11e7c382 (diff)
downloadFreeBSD-src-b2895f817ad56cf7b76b6cb00b5b0de2cf91a581.zip
FreeBSD-src-b2895f817ad56cf7b76b6cb00b5b0de2cf91a581.tar.gz
Fix dmasetup functions to have 16 bit queue indices. Get the chip revision
out of the PCI CLASS reg and store it in the softc. Use the getenv_quad function to get a WWN override from the environment. Look for a config value for same. Make slightly less lame the wwn seed construction.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/isp/isp_pci.c68
-rw-r--r--sys/pci/isp_pci.c68
2 files changed, 80 insertions, 56 deletions
diff --git a/sys/dev/isp/isp_pci.c b/sys/dev/isp/isp_pci.c
index 323a399..3c6b1fd 100644
--- a/sys/dev/isp/isp_pci.c
+++ b/sys/dev/isp/isp_pci.c
@@ -56,7 +56,7 @@ static void isp_pci_wr_reg_1080 __P((struct ispsoftc *, int, u_int16_t));
#endif
static int isp_pci_mbxdma __P((struct ispsoftc *));
static int isp_pci_dmasetup __P((struct ispsoftc *, ISP_SCSI_XFER_T *,
- ispreq_t *, u_int8_t *, u_int8_t));
+ ispreq_t *, u_int16_t *, u_int16_t));
static void
isp_pci_dmateardown __P((struct ispsoftc *, ISP_SCSI_XFER_T *, u_int32_t));
@@ -314,9 +314,13 @@ isp_pci_probe(pcici_t tag, pcidi_t type)
static void
isp_pci_attach(pcici_t cfid, int unit)
{
+#ifdef SCSI_ISP_WWN
+ const char *name = SCSI_ISP_WWN;
+ char *vtp = NULL;
+#endif
int mapped, prefer_mem_map, bitmap;
pci_port_t io_port;
- u_int32_t data, linesz, psize, basetype;
+ u_int32_t data, rev, linesz, psize, basetype;
struct isp_pcisoftc *pcs;
struct ispsoftc *isp;
vm_offset_t vaddr, paddr;
@@ -408,6 +412,7 @@ isp_pci_attach(pcici_t cfid, int unit)
pcs->pci_st == IO_SPACE_MAPPING? "I/O" : "Memory");
data = pci_conf_read(cfid, PCI_ID_REG);
+ rev = pci_conf_read(cfid, PCI_CLASS_REG) & 0xff; /* revision */
pcs->pci_poff[BIU_BLOCK >> _BLK_REG_SHFT] = BIU_REGS_OFF;
pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = PCI_MBOX_REGS_OFF;
pcs->pci_poff[SXP_BLOCK >> _BLK_REG_SHFT] = PCI_SXP_REGS_OFF;
@@ -451,8 +456,7 @@ isp_pci_attach(pcici_t cfid, int unit)
psize = sizeof (fcparam);
pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] =
PCI_MBOX_REGS2100_OFF;
- data = pci_conf_read(cfid, PCI_CLASS_REG);
- if ((data & 0xff) < 3) {
+ if (rev < 3) {
/*
* XXX: Need to get the actual revision
* XXX: number of the 2100 FB. At any rate,
@@ -481,6 +485,7 @@ isp_pci_attach(pcici_t cfid, int unit)
bzero(isp->isp_param, psize);
isp->isp_mdvec = mdvp;
isp->isp_type = basetype;
+ isp->isp_revision = rev;
(void) snprintf(isp->isp_name, sizeof (isp->isp_name), "isp%d", unit);
isp->isp_osinfo.unit = unit;
@@ -583,30 +588,37 @@ isp_pci_attach(pcici_t cfid, int unit)
if (bitmap & (1 << unit))
isp->isp_confopts &= ~ISP_CFG_FULL_DUPLEX;
}
+ /*
+ * Look for overriding WWN. This is a Node WWN so it binds to
+ * all FC instances. A Port WWN will be constructed from it
+ * as appropriate.
+ */
+#ifdef SCSI_ISP_WWN
+ isp->isp_osinfo.default_wwn = strtoq(name, &vtp, 16);
+ if (vtp != name && *vtp == 0) {
+ isp->isp_confopts |= ISP_CFG_OWNWWN;
+ } else
+#endif
+ if (!getenv_quad("isp_wwn", (quad_t *) &isp->isp_osinfo.default_wwn)) {
+ int i;
+ u_int64_t seed = (u_int64_t) (intptr_t) isp;
- if (getenv_int("isp_seed", &isp->isp_osinfo.seed)) {
- isp->isp_osinfo.seed <<= 8;
- isp->isp_osinfo.seed += (unit + 1);
- } else {
+ seed <<= 16;
+ seed &= ((1LL << 48) - 1LL);
/*
- * poor man's attempt at pseudo randomness.
+ * This isn't very random, but it's the best we can do for
+ * the real edge case of cards that don't have WWNs. If
+ * you recompile a new vers.c, you'll get a different WWN.
*/
- long i = (intptr_t) isp;
-
- i >>= 5;
- i &= 0x7;
-
+ for (i = 0; version[i] != 0; i++) {
+ seed += version[i];
+ }
/*
- * This isn't very random, but it's the best we can do for
- * the real edge case of cards that don't have WWNs.
+ * Make sure the top nibble has something vaguely sensible.
*/
- isp->isp_osinfo.seed += ((int) cfid->bus) << 16;
- isp->isp_osinfo.seed += ((int) cfid->slot) << 8;
- isp->isp_osinfo.seed += ((int) cfid->func);
- while (version[i])
- isp->isp_osinfo.seed += (int) version[i++];
- isp->isp_osinfo.seed <<= 8;
- isp->isp_osinfo.seed += (unit + 1);
+ isp->isp_osinfo.default_wwn |= (4LL << 60) | seed;
+ } else {
+ isp->isp_confopts |= ISP_CFG_OWNWWN;
}
(void) getenv_int("isp_debug", &isp_debug);
ISP_LOCK(isp);
@@ -921,8 +933,8 @@ typedef struct {
struct ispsoftc *isp;
ISP_SCSI_XFER_T *ccb;
ispreq_t *rq;
- u_int8_t *iptrp;
- u_int8_t optr;
+ u_int16_t *iptrp;
+ u_int16_t optr;
u_int error;
} mush_t;
@@ -938,8 +950,8 @@ dma2(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
bus_dmamap_t *dp;
bus_dma_segment_t *eseg;
ispreq_t *rq;
- u_int8_t *iptrp;
- u_int8_t optr;
+ u_int16_t *iptrp;
+ u_int16_t optr;
ispcontreq_t *crq;
int drq, seglim, datalen;
@@ -1051,7 +1063,7 @@ dma2(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
static int
isp_pci_dmasetup(struct ispsoftc *isp, ISP_SCSI_XFER_T *ccb, ispreq_t *rq,
- u_int8_t *iptrp, u_int8_t optr)
+ u_int16_t *iptrp, u_int16_t optr)
{
struct isp_pcisoftc *pci = (struct isp_pcisoftc *)isp;
struct ccb_hdr *ccb_h;
diff --git a/sys/pci/isp_pci.c b/sys/pci/isp_pci.c
index 323a399..3c6b1fd 100644
--- a/sys/pci/isp_pci.c
+++ b/sys/pci/isp_pci.c
@@ -56,7 +56,7 @@ static void isp_pci_wr_reg_1080 __P((struct ispsoftc *, int, u_int16_t));
#endif
static int isp_pci_mbxdma __P((struct ispsoftc *));
static int isp_pci_dmasetup __P((struct ispsoftc *, ISP_SCSI_XFER_T *,
- ispreq_t *, u_int8_t *, u_int8_t));
+ ispreq_t *, u_int16_t *, u_int16_t));
static void
isp_pci_dmateardown __P((struct ispsoftc *, ISP_SCSI_XFER_T *, u_int32_t));
@@ -314,9 +314,13 @@ isp_pci_probe(pcici_t tag, pcidi_t type)
static void
isp_pci_attach(pcici_t cfid, int unit)
{
+#ifdef SCSI_ISP_WWN
+ const char *name = SCSI_ISP_WWN;
+ char *vtp = NULL;
+#endif
int mapped, prefer_mem_map, bitmap;
pci_port_t io_port;
- u_int32_t data, linesz, psize, basetype;
+ u_int32_t data, rev, linesz, psize, basetype;
struct isp_pcisoftc *pcs;
struct ispsoftc *isp;
vm_offset_t vaddr, paddr;
@@ -408,6 +412,7 @@ isp_pci_attach(pcici_t cfid, int unit)
pcs->pci_st == IO_SPACE_MAPPING? "I/O" : "Memory");
data = pci_conf_read(cfid, PCI_ID_REG);
+ rev = pci_conf_read(cfid, PCI_CLASS_REG) & 0xff; /* revision */
pcs->pci_poff[BIU_BLOCK >> _BLK_REG_SHFT] = BIU_REGS_OFF;
pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = PCI_MBOX_REGS_OFF;
pcs->pci_poff[SXP_BLOCK >> _BLK_REG_SHFT] = PCI_SXP_REGS_OFF;
@@ -451,8 +456,7 @@ isp_pci_attach(pcici_t cfid, int unit)
psize = sizeof (fcparam);
pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] =
PCI_MBOX_REGS2100_OFF;
- data = pci_conf_read(cfid, PCI_CLASS_REG);
- if ((data & 0xff) < 3) {
+ if (rev < 3) {
/*
* XXX: Need to get the actual revision
* XXX: number of the 2100 FB. At any rate,
@@ -481,6 +485,7 @@ isp_pci_attach(pcici_t cfid, int unit)
bzero(isp->isp_param, psize);
isp->isp_mdvec = mdvp;
isp->isp_type = basetype;
+ isp->isp_revision = rev;
(void) snprintf(isp->isp_name, sizeof (isp->isp_name), "isp%d", unit);
isp->isp_osinfo.unit = unit;
@@ -583,30 +588,37 @@ isp_pci_attach(pcici_t cfid, int unit)
if (bitmap & (1 << unit))
isp->isp_confopts &= ~ISP_CFG_FULL_DUPLEX;
}
+ /*
+ * Look for overriding WWN. This is a Node WWN so it binds to
+ * all FC instances. A Port WWN will be constructed from it
+ * as appropriate.
+ */
+#ifdef SCSI_ISP_WWN
+ isp->isp_osinfo.default_wwn = strtoq(name, &vtp, 16);
+ if (vtp != name && *vtp == 0) {
+ isp->isp_confopts |= ISP_CFG_OWNWWN;
+ } else
+#endif
+ if (!getenv_quad("isp_wwn", (quad_t *) &isp->isp_osinfo.default_wwn)) {
+ int i;
+ u_int64_t seed = (u_int64_t) (intptr_t) isp;
- if (getenv_int("isp_seed", &isp->isp_osinfo.seed)) {
- isp->isp_osinfo.seed <<= 8;
- isp->isp_osinfo.seed += (unit + 1);
- } else {
+ seed <<= 16;
+ seed &= ((1LL << 48) - 1LL);
/*
- * poor man's attempt at pseudo randomness.
+ * This isn't very random, but it's the best we can do for
+ * the real edge case of cards that don't have WWNs. If
+ * you recompile a new vers.c, you'll get a different WWN.
*/
- long i = (intptr_t) isp;
-
- i >>= 5;
- i &= 0x7;
-
+ for (i = 0; version[i] != 0; i++) {
+ seed += version[i];
+ }
/*
- * This isn't very random, but it's the best we can do for
- * the real edge case of cards that don't have WWNs.
+ * Make sure the top nibble has something vaguely sensible.
*/
- isp->isp_osinfo.seed += ((int) cfid->bus) << 16;
- isp->isp_osinfo.seed += ((int) cfid->slot) << 8;
- isp->isp_osinfo.seed += ((int) cfid->func);
- while (version[i])
- isp->isp_osinfo.seed += (int) version[i++];
- isp->isp_osinfo.seed <<= 8;
- isp->isp_osinfo.seed += (unit + 1);
+ isp->isp_osinfo.default_wwn |= (4LL << 60) | seed;
+ } else {
+ isp->isp_confopts |= ISP_CFG_OWNWWN;
}
(void) getenv_int("isp_debug", &isp_debug);
ISP_LOCK(isp);
@@ -921,8 +933,8 @@ typedef struct {
struct ispsoftc *isp;
ISP_SCSI_XFER_T *ccb;
ispreq_t *rq;
- u_int8_t *iptrp;
- u_int8_t optr;
+ u_int16_t *iptrp;
+ u_int16_t optr;
u_int error;
} mush_t;
@@ -938,8 +950,8 @@ dma2(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
bus_dmamap_t *dp;
bus_dma_segment_t *eseg;
ispreq_t *rq;
- u_int8_t *iptrp;
- u_int8_t optr;
+ u_int16_t *iptrp;
+ u_int16_t optr;
ispcontreq_t *crq;
int drq, seglim, datalen;
@@ -1051,7 +1063,7 @@ dma2(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
static int
isp_pci_dmasetup(struct ispsoftc *isp, ISP_SCSI_XFER_T *ccb, ispreq_t *rq,
- u_int8_t *iptrp, u_int8_t optr)
+ u_int16_t *iptrp, u_int16_t optr)
{
struct isp_pcisoftc *pci = (struct isp_pcisoftc *)isp;
struct ccb_hdr *ccb_h;
OpenPOWER on IntegriCloud