summaryrefslogtreecommitdiffstats
path: root/sys/pci/aic7870.c
blob: e0e4733f2d9882146ea02b7f3dabee4ef342cb37 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/*
 * Product specific probe and attach routines for:
 *      2940, aic7870, and aic7850 motherboard SCSI controllers
 *
 * Copyright (c) 1995 Justin T. Gibbs
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice immediately at the beginning of the file, without modification,
 *    this list of conditions, and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Absolutely no warranty of function or purpose is made by the author
 *    Justin T. Gibbs.
 * 4. Modifications may be freely made to this file if the above conditions
 *    are met.
 *
 *	$Id: aic7870.c,v 1.10.2.2 1995/06/09 18:06:53 davidg Exp $
 */

#include <pci.h>
#if NPCI > 0
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <scsi/scsi_all.h>
#include <scsi/scsiconf.h>
#include <pci/pcireg.h>
#include <pci/pcivar.h>
#include <i386/scsi/aic7xxx.h>

#define PCI_BASEADR0	PCI_MAP_REG_START
#define PCI_DEVICE_ID_ADAPTEC_2940	0x71789004ul
#define PCI_DEVICE_ID_ADAPTEC_AIC7870	0x70789004ul
#define PCI_DEVICE_ID_ADAPTEC_AIC7850	0x70759004ul

static char* aic7870_probe __P((pcici_t tag, pcidi_t type));
void aic7870_attach __P((pcici_t config_id, int unit));

static u_long aic7870_count;

struct  pci_device ahc_device = {
	"ahc",
        aic7870_probe,
        aic7870_attach,
        &aic7870_count,
	NULL
};

DATA_SET (pcidevice_set, ahc_device);

static  char*
aic7870_probe (pcici_t tag, pcidi_t type)
{
	switch(type) {
		case PCI_DEVICE_ID_ADAPTEC_2940:
			return ("Adaptec 294X SCSI host adapter");
			break;
		case PCI_DEVICE_ID_ADAPTEC_AIC7870:
			return ("Adaptec aic7870 SCSI host adapter");
			break;
		case PCI_DEVICE_ID_ADAPTEC_AIC7850:
			return ("Adaptec aic7850 SCSI host adapter");
			break;
		default:
			break;
	}
	return (0);

}

void
aic7870_attach(config_id, unit)
	pcici_t config_id;
	int	unit;
{
	u_long io_port;
	unsigned opri = 0;
	ahc_type ahc_t = AHC_NONE;
        if(!(io_port = pci_conf_read(config_id, PCI_BASEADR0)))
		return;
	/*
	 * Make the offsets the same as for EISA
	 * The first bit of PCI_BASEADR0 is always
	 * set hence we subtract 0xc01 instead of the
	 * 0xc00 that you would expect.
	 */
	io_port -= 0xc01ul;

	switch (pci_conf_read (config_id, PCI_ID_REG)) {
		case PCI_DEVICE_ID_ADAPTEC_2940:
			ahc_t = AHC_294;
			break;
		case PCI_DEVICE_ID_ADAPTEC_AIC7870:
			ahc_t = AHC_AIC7870;
			break;
		case PCI_DEVICE_ID_ADAPTEC_AIC7850:
			ahc_t = AHC_AIC7850;
			break;
		default:
			break;
	}

	if(ahcprobe(unit, io_port, ahc_t)){
		ahc_unit++;
		/*
		 * To be compatible with the isa style of
		 * interrupt handler, we pass the unit number
		 * not a pointer to our per device structure.
		 */
		if(!(pci_map_int(config_id, ahcintr, (void *)unit,
			&bio_imask))) {
			free(ahcdata[unit], M_TEMP);
			ahcdata[unit] = NULL;
			return;
		}
		/*
		 * Since ahc_attach will poll, protect ourself
		 * from the registered interrupt handler.
		 */
		opri = splbio();
		ahc_attach(unit);
		splx(opri);
	}
	return;
}

#endif /* NPCI > 0 */
OpenPOWER on IntegriCloud