aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/aha
diff options
context:
space:
mode:
authorWarner Losh <imp@FreeBSD.org>1999-01-20 06:21:27 +0000
committerWarner Losh <imp@FreeBSD.org>1999-01-20 06:21:27 +0000
commit07353d42472c991d9807ca12497973a142d1d96e (patch)
treeada66243c0b3fa5e6dd008ff5811f96b4ac9d9f3 /sys/dev/aha
parentd7eb2472ac048d61b2f1041fdd2bba8a9f6b58c0 (diff)
Notes
Diffstat (limited to 'sys/dev/aha')
-rw-r--r--sys/dev/aha/aha.c39
-rw-r--r--sys/dev/aha/aha_isa.c99
-rw-r--r--sys/dev/aha/ahareg.h18
3 files changed, 134 insertions, 22 deletions
diff --git a/sys/dev/aha/aha.c b/sys/dev/aha/aha.c
index b213adc45e46..dcabdeaa71ad 100644
--- a/sys/dev/aha/aha.c
+++ b/sys/dev/aha/aha.c
@@ -55,9 +55,11 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: aha.c,v 1.17 1998/12/22 18:14:50 gibbs Exp $
+ * $Id: aha.c,v 1.18 1998/12/22 22:31:06 imp Exp $
*/
+#include "pnp.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
@@ -79,10 +81,15 @@
#include <vm/vm.h>
#include <vm/pmap.h>
+
+#if NPNP > 0
+#include <i386/isa/isa_device.h>
+#include <i386/isa/pnp.h> /* XXX pnp isn't x86 only */
+#endif
#include <dev/aha/ahareg.h>
-struct aha_softc *aha_softcs[NAHA];
+struct aha_softc *aha_softcs[NAHATOT];
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define PRVERB(x) if (bootverbose) printf x
@@ -209,7 +216,7 @@ aha_alloc(int unit, bus_space_tag_t tag, bus_space_handle_t bsh)
struct aha_softc *aha;
if (unit != AHA_TEMP_UNIT) {
- if (unit >= NAHA) {
+ if (unit >= NAHATOT) {
printf("aha: unit number (%d) too high\n", unit);
return NULL;
}
@@ -235,6 +242,8 @@ aha_alloc(int unit, bus_space_tag_t tag, bus_space_handle_t bsh)
aha->unit = unit;
aha->tag = tag;
aha->bsh = bsh;
+ aha->ccb_sg_opcode = INITIATOR_SG_CCB_WRESID;
+ aha->ccb_ccb_opcode = INITIATOR_CCB_WRESID;
if (aha->unit != AHA_TEMP_UNIT) {
aha_softcs[unit] = aha;
@@ -902,7 +911,7 @@ ahaaction(struct cam_sim *sim, union ccb *ccb)
csio = &ccb->csio;
ccbh = &csio->ccb_h;
- hccb->opcode = INITIATOR_CCB_WRESID;
+ hccb->opcode = aha->ccb_ccb_opcode;
hccb->datain = (ccb->ccb_h.flags & CAM_DIR_IN) != 0;
hccb->dataout = (ccb->ccb_h.flags & CAM_DIR_OUT) != 0;
hccb->cmd_len = csio->cdb_len;
@@ -1169,7 +1178,7 @@ ahaexecuteccb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
}
if (nseg > 1) {
- accb->hccb.opcode = INITIATOR_SG_CCB_WRESID;
+ accb->hccb.opcode = aha->ccb_sg_opcode;
ahautoa24((sizeof(aha_sg_t) * nseg),
accb->hccb.data_len);
ahautoa24(accb->sg_list_phys, accb->hccb.data_addr);
@@ -1360,7 +1369,10 @@ ahadone(struct aha_softc *aha, struct aha_ccb *accb, aha_mbi_comp_code_t comp_co
case AMBI_ABORT:
case AMBI_ERROR:
/* An error occured */
- csio->resid = aha_a24tou(accb->hccb.data_len);
+ if (accb->hccb.opcode < INITIATOR_CCB_WRESID)
+ csio->resid = 0;
+ else
+ csio->resid = aha_a24tou(accb->hccb.data_len);
switch(accb->hccb.ahastat) {
case AHASTAT_DATARUN_ERROR:
{
@@ -1406,8 +1418,16 @@ ahadone(struct aha_softc *aha, struct aha_ccb *accb, aha_mbi_comp_code_t comp_co
panic("%s: Inavlid Action code", aha_name(aha));
break;
case AHASTAT_INVALID_OPCODE:
- panic("%s: Invalid CCB Opcode code %x hccb = %p",
- aha_name(aha), accb->hccb.opcode, &accb->hccb);
+ if (accb->hccb.opcode < INITIATOR_CCB_WRESID)
+ panic("%s: Invalid CCB Opcode %x hccb = %p",
+ aha_name(aha), accb->hccb.opcode,
+ &accb->hccb);
+ printf("%s: AHA-1540A detected, compensating\n",
+ aha_name(aha));
+ aha->ccb_sg_opcode = INITIATOR_SG_CCB;
+ aha->ccb_ccb_opcode = INITIATOR_CCB;
+ xpt_freeze_devq(ccb->ccb_h.path, /*count*/1);
+ csio->ccb_h.status = CAM_REQUEUE_REQ;
break;
case AHASTAT_LINKED_CCB_LUN_MISMATCH:
/* We don't even support linked commands... */
@@ -1418,7 +1438,7 @@ ahadone(struct aha_softc *aha, struct aha_ccb *accb, aha_mbi_comp_code_t comp_co
break;
case AHASTAT_HA_SCSI_BUS_RESET:
if ((csio->ccb_h.status & CAM_STATUS_MASK)
- != CAM_CMD_TIMEOUT)
+ != CAM_CMD_TIMEOUT)
csio->ccb_h.status = CAM_SCSI_BUS_RESET;
break;
case AHASTAT_HA_BDR:
@@ -1440,6 +1460,7 @@ ahadone(struct aha_softc *aha, struct aha_ccb *accb, aha_mbi_comp_code_t comp_co
case AMBI_OK:
/* All completed without incident */
/* XXX DO WE NEED TO COPY SENSE BYTES HERE???? XXX */
+ /* I don't think so since it works???? */
ccb->ccb_h.status |= CAM_REQ_CMP;
if ((accb->flags & ACCB_RELEASE_SIMQ) != 0)
ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
diff --git a/sys/dev/aha/aha_isa.c b/sys/dev/aha/aha_isa.c
index f7183305baba..94266790e87f 100644
--- a/sys/dev/aha/aha_isa.c
+++ b/sys/dev/aha/aha_isa.c
@@ -28,11 +28,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: aha_isa.c,v 1.4 1998/10/12 18:53:33 imp Exp $
+ * $Id: aha_isa.c,v 1.5 1998/11/10 06:44:54 gibbs Exp $
*/
+#include "pnp.h"
+
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/kernel.h>
#include <machine/bus_pio.h>
#include <machine/bus.h>
@@ -42,9 +45,13 @@
#include <cam/scsi/scsi_all.h>
-static int aha_isa_probe __P((struct isa_device *dev));
-static int aha_isa_attach __P((struct isa_device *dev));
-static void aha_isa_intr __P((void *unit));
+#if NPNP > 0
+#include <i386/isa/pnp.h>
+#endif
+
+static int aha_isa_probe(struct isa_device *dev);
+static int aha_isa_attach(struct isa_device *dev);
+static void aha_isa_intr(void *unit);
struct isa_driver ahadriver =
{
@@ -70,14 +77,6 @@ aha_isa_probe(dev)
int port_index;
int max_port_index;
- /*
- * We ignore the unit number assigned by config to allow
- * consistant numbering between PCI/EISA/ISA devices.
- * This is a total kludge until we have a configuration
- * manager.
- */
- dev->id_unit = aha_unit;
-
aha = NULL;
/*
@@ -214,3 +213,79 @@ aha_isa_intr(void *unit)
struct aha_softc* arg = aha_softcs[(int)unit];
aha_intr((void *)arg);
}
+
+/*
+ * support PnP cards if we are using 'em
+ */
+
+#if NPNP > 0
+
+static char *ahapnp_probe(u_long csn, u_long vend_id);
+static void ahapnp_attach(u_long csn, u_long vend_id, char *name,
+ struct isa_device *dev);
+static u_long nahapnp = NAHA;
+
+static struct pnp_device ahapnp = {
+ "ahapnp",
+ ahapnp_probe,
+ ahapnp_attach,
+ &nahapnp,
+ &bio_imask
+};
+DATA_SET (pnpdevice_set, ahapnp);
+
+static char *
+ahapnp_probe(u_long csn, u_long vend_id)
+{
+ struct pnp_cinfo d;
+ char *s = NULL;
+
+ if (vend_id != AHA1542_PNP && vend_id != AHA1542_PNPCOMPAT)
+ return (NULL);
+
+ read_pnp_parms(&d, 0);
+ if (d.enable == 0 || d.flags & 1) {
+ printf("CSN %lu is disabled.\n", csn);
+ return (NULL);
+ }
+ s = "Adaptec 1542CP";
+
+ return (s);
+}
+
+static void
+ahapnp_attach(u_long csn, u_long vend_id, char *name, struct isa_device *dev)
+{
+ struct pnp_cinfo d;
+ struct isa_device *dvp;
+
+ if (dev->id_unit >= NAHATOT)
+ return;
+
+ if (read_pnp_parms(&d, 0) == 0) {
+ printf("failed to read pnp parms\n");
+ return;
+ }
+
+ write_pnp_parms(&d, 0);
+
+ enable_pnp_card();
+
+ dev->id_iobase = d.port[0];
+ dev->id_irq = (1 << d.irq[0]);
+ dev->id_intr = aha_intr;
+ dev->id_drq = d.drq[0];
+
+ if (dev->id_driver == NULL) {
+ dev->id_driver = &ahadriver;
+ dvp = find_isadev(isa_devtab_tty, &ahadriver, 0);
+ if (dvp != NULL)
+ dev->id_id = dvp->id_id;
+ }
+
+ if ((dev->id_alive = aha_isa_probe(dev)) != 0)
+ aha_isa_attach(dev);
+ else
+ printf("aha%d: probe failed\n", dev->id_unit);
+}
+#endif
diff --git a/sys/dev/aha/ahareg.h b/sys/dev/aha/ahareg.h
index 48bb20caf6a9..82f3f4a49bd4 100644
--- a/sys/dev/aha/ahareg.h
+++ b/sys/dev/aha/ahareg.h
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: ahareg.h,v 1.3 1998/10/02 04:37:49 imp Exp $
+ * $Id: ahareg.h,v 1.4 1998/11/10 06:44:42 gibbs Exp $
*/
#ifndef _AHAREG_H_
@@ -349,6 +349,8 @@ struct aha_softc {
LIST_HEAD(,ccb_hdr) pending_ccbs;
u_int active_ccbs;
u_int32_t aha_ccb_physbase;
+ aha_ccb_opcode_t ccb_sg_opcode;
+ aha_ccb_opcode_t ccb_ccb_opcode;
aha_mbox_in_t *in_boxes;
aha_mbox_out_t *out_boxes;
struct scsi_sense_data *sense_buffers;
@@ -428,4 +430,18 @@ int aha_cmd(struct aha_softc *aha, aha_op_t opcode,
#define aha_outb(aha, port, value) \
bus_space_write_1((aha)->tag, (aha)->bsh, port, value)
+
+#ifndef EXTRA_AHA
+#if NPNP > 0
+#define EXTRA_AHA MAX_PNP_CARDS
+#else
+#define EXTRA_AHA 0
+#endif
+#endif
+
+#define NAHATOT (NAHA + EXTRA_AHA)
+
+#define AHA1542_PNP 0x42159004 /* ADP1542 */
+#define AHA1542_PNPCOMPAT 0xA000D040 /* PNP00A0 */
+
#endif /* _AHA_H_ */