xref: /openbsd-src/sys/dev/pci/arc.c (revision 91f110e064cd7c194e59e019b83bb7496c1c84d4)
1 /*	$OpenBSD: arc.c,v 1.101 2014/02/08 16:02:42 chris Exp $ */
2 
3 /*
4  * Copyright (c) 2006 David Gwynne <dlg@openbsd.org>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 /*
20  * Ching Huang   Support ARC1880,1882,1213,1223,1214
21  */
22 #include "bio.h"
23 
24 #include <sys/param.h>
25 #include <sys/systm.h>
26 #include <sys/buf.h>
27 #include <sys/kernel.h>
28 #include <sys/malloc.h>
29 #include <sys/mutex.h>
30 #include <sys/device.h>
31 #include <sys/rwlock.h>
32 
33 #include <machine/bus.h>
34 
35 #include <dev/pci/pcireg.h>
36 #include <dev/pci/pcivar.h>
37 #include <dev/pci/pcidevs.h>
38 
39 #include <scsi/scsi_all.h>
40 #include <scsi/scsiconf.h>
41 
42 #include <sys/sensors.h>
43 #if NBIO > 0
44 #include <sys/ioctl.h>
45 #include <dev/biovar.h>
46 #endif
47 
48 #ifdef ARC_DEBUG
49 #define ARC_D_INIT	(1<<0)
50 #define ARC_D_RW	(1<<1)
51 #define ARC_D_DB	(1<<2)
52 
53 int arcdebug = 0;
54 
55 #define DPRINTF(p...)		do { if (arcdebug) printf(p); } while (0)
56 #define DNPRINTF(n, p...)	do { if ((n) & arcdebug) printf(p); } while (0)
57 
58 #else
59 #define DPRINTF(p...)		/* p */
60 #define DNPRINTF(n, p...)	/* n, p */
61 #endif
62 
63 #define ARC_HBA_TYPE_A    0x00000001
64 #define ARC_HBA_TYPE_B    0x00000002
65 #define ARC_HBA_TYPE_C    0x00000003
66 #define ARC_HBA_TYPE_D    0x00000004
67 
68 #define ARC_RA_PCI_BAR			PCI_MAPREG_START
69 #define ARC_RB_DOORBELL_BAR		PCI_MAPREG_START
70 #define ARC_RB_RWBUFFER_BAR		PCI_MAPREG_PPB_END
71 #define ARC_RC_PCI_BAR			PCI_MAPREG_PCB_END
72 #define ARC_RD_PCI_BAR			PCI_MAPREG_START
73 
74 #define ARCMSR_MAX_CCB_COUNT		264
75 #define ARCMSR_MAX_HBB_POSTQUEUE	264
76 #define ARCMSR_MAX_HBD_POSTQUEUE	256
77 
78 /* Areca boards using the Intel IOP are Type A (RA) */
79 
80 #define ARC_RA_INB_MSG0				0x0010
81 #define  ARC_RA_INB_MSG0_NOP			(0x00000000)
82 #define  ARC_RA_INB_MSG0_GET_CONFIG		(0x00000001)
83 #define  ARC_RA_INB_MSG0_SET_CONFIG		(0x00000002)
84 #define  ARC_RA_INB_MSG0_ABORT_CMD		(0x00000003)
85 #define  ARC_RA_INB_MSG0_STOP_BGRB		(0x00000004)
86 #define  ARC_RA_INB_MSG0_FLUSH_CACHE		(0x00000005)
87 #define  ARC_RA_INB_MSG0_START_BGRB		(0x00000006)
88 #define  ARC_RA_INB_MSG0_CHK331PENDING		(0x00000007)
89 #define  ARC_RA_INB_MSG0_SYNC_TIMER		(0x00000008)
90 #define ARC_RA_INB_MSG1				0x0014
91 #define ARC_RA_OUTB_ADDR0			0x0018
92 #define ARC_RA_OUTB_ADDR1			0x001c
93 #define  ARC_RA_OUTB_ADDR1_FIRMWARE_OK		(1<<31)
94 #define ARC_RA_INB_DOORBELL			0x0020
95 #define  ARC_RA_INB_DOORBELL_WRITE_OK		(1<<0)
96 #define  ARC_RA_INB_DOORBELL_READ_OK		(1<<1)
97 #define ARC_RA_OUTB_DOORBELL			0x002c
98 #define  ARC_RA_OUTB_DOORBELL_WRITE_OK		(1<<0)
99 #define  ARC_RA_OUTB_DOORBELL_READ_OK		(1<<1)
100 #define ARC_RA_INTRSTAT				0x0030
101 #define  ARC_RA_INTRSTAT_MSG0			(1<<0)
102 #define  ARC_RA_INTRSTAT_MSG1			(1<<1)
103 #define  ARC_RA_INTRSTAT_DOORBELL		(1<<2)
104 #define  ARC_RA_INTRSTAT_POSTQUEUE		(1<<3)
105 #define  ARC_RA_INTRSTAT_PCI			(1<<4)
106 #define  ARC_RA_INTR_STAT_ALL			0x1F
107 #define ARC_RA_INTRMASK				0x0034
108 #define  ARC_RA_INTRMASK_MSG0			(1<<0)
109 #define  ARC_RA_INTRMASK_MSG1			(1<<1)
110 #define  ARC_RA_INTRMASK_DOORBELL		(1<<2)
111 #define  ARC_RA_INTRMASK_POSTQUEUE		(1<<3)
112 #define  ARC_RA_INTRMASK_PCI			(1<<4)
113 #define  ARC_RA_INTR_MASK_ALL			0x1F
114 #define ARC_RA_POST_QUEUE			0x0040
115 #define  ARC_RA_POST_QUEUE_ADDR_SHIFT		5
116 #define  ARC_RA_POST_QUEUE_IAMBIOS		(1<<30)
117 #define  ARC_RA_POST_QUEUE_BIGFRAME		(1<<31)
118 #define ARC_RA_REPLY_QUEUE			0x0044
119 #define  ARC_RA_REPLY_QUEUE_ADDR_SHIFT		5
120 #define  ARC_RA_REPLY_QUEUE_ERR			(1<<28)
121 #define  ARC_RA_REPLY_QUEUE_IAMBIOS		(1<<30)
122 #define ARC_RA_MSGBUF				0x0a00
123 #define  ARC_RA_MSGBUF_LEN			1024
124 #define ARC_RA_IOC_WBUF_LEN			0x0e00
125 #define ARC_RA_IOC_WBUF				0x0e04
126 #define ARC_RA_IOC_RBUF_LEN			0x0f00
127 #define ARC_RA_IOC_RBUF				0x0f04
128 #define  ARC_RA_IOC_RWBUF_MAXLEN		124 /* for both RBUF and WBUF */
129 
130 /* Areca boards using the Marvel IOP0 are Type B (RB) */
131 
132 #define ARC_RB_DRV2IOP_DOORBELL		0x00020400
133 #define ARC_RB_DRV2IOP_DOORBELL_MASK	0x00020404
134 #define ARC_RB_IOP2DRV_DOORBELL		0x00020408
135 #define ARC_RB_IOP2DRV_DOORBELL_FIRMWARE_OK	(1<<31)
136 #define ARC_RB_IOP2DRV_DOORBELL_MASK	0x0002040c
137 
138 /* Areca boards using the LSI IOP are Type C (RC) */
139 
140 #define ARC_RC_INB_DOORBELL	   	0x20
141 #define ARC_RC_INTR_STAT		0x30
142 #define	ARC_RC_INTR_MASK		0x34
143 #define	ARC_RC_OUTB_DOORBELL		0x9C
144 #define	ARC_RC_OUTB_DOORBELL_CLR	0xA0
145 #define	ARC_RC_D2I_MSG_CMD_DONE		0x08
146 #define	ARC_RC_I2D_MSG_CMD_DONE		0x08
147 #define	ARC_RC_I2D_MSG_CMD_DONE_CLR	0x08
148 #define ARC_RC_INB_MSGADDR0		0xB0
149 #define ARC_RC_INB_MSGADDR1		0xB4
150 #define ARC_RC_OUTB_MSGADDR0		0xB8
151 #define ARC_RC_OUTB_MSGADDR1		0xBC
152 #define ARC_RC_OUTB_MSG_FIRMWARE_OK	0x80000000
153 #define ARC_RC_INB_POSTQ_LOW		0xC0
154 #define ARC_RC_INB_POSTQ_HIGH		0xC4
155 #define	ARC_RC_OUTB_REPLYQ_LOW		0xC8
156 #define	ARC_RC_OUTB_REPLYQ_HIGH		0xCC
157 #define	ARC_RC_MSG_WBUF_LEN		0x2000
158 #define	ARC_RC_MSG_WBUF			0x2004
159 #define	ARC_RC_MSG_RBUF_LEN		0x2100
160 #define	ARC_RC_MSG_RBUF			0x2104
161 #define	ARC_RC_MSG_RWBUF		0x2200
162 
163 #define ARC_RC_INB_MSG0_NOP		(0x00000000)
164 #define ARC_RC_INB_MSG0_GET_CONFIG	(0x00000001)
165 #define ARC_RC_INB_MSG0_SET_CONFIG	(0x00000002)
166 #define ARC_RC_INB_MSG0_ABORT_CMD	(0x00000003)
167 #define ARC_RC_INB_MSG0_STOP_BGRB	(0x00000004)
168 #define ARC_RC_INB_MSG0_FLUSH_CACHE	(0x00000005)
169 #define ARC_RC_INB_MSG0_START_BGRB	(0x00000006)
170 #define ARC_RC_INB_MSG0_CHK331PENDING	(0x00000007)
171 #define ARC_RC_INB_MSG0_SYNC_TIMER	(0x00000008)
172 
173 #define ARC_RC_D2I_DATA_WRITE_OK	0x00000002
174 #define ARC_RC_D2I_DATA_READ_OK		0x00000004
175 #define ARC_RC_D2I_MESSAGE_CMD_DONE	0x00000008
176 #define ARC_RC_D2I_POSTQUEUE_THROTTLING	0x00000010
177 #define ARC_RC_I2D_DATA_WRITE_OK	0x00000002
178 #define ARC_RC_I2D_DATA_WRITE_OK_CLEAR	0x00000002
179 #define ARC_RC_I2D_DATA_READ_OK		0x00000004
180 #define ARC_RC_I2D_DATA_READ_OK_CLEAR	0x00000004
181 #define ARC_RC_I2D_MESSAGE_CMD_DONE	0x00000008
182 #define ARC_RC_I2D_MESSAGE_CMD_DONE_CLEAR 0x00000008
183 #define ARC_RC_MESSAGE_FIRMWARE_OK	0x80000000
184 
185 #define ARC_RC_INTR_STAT_UTILITY_A	(1<<0)
186 #define ARC_RC_INTR_STAT_DOORBELL	(1<<2)
187 #define ARC_RC_INTR_STAT_POSTQUEUE	(1<<3)
188 #define ARC_RC_INTR_MASK_ALL		0x0000000D
189 #define ARC_RC_INTR_MASK_UTILITY_A	(1<<0)
190 #define ARC_RC_INTR_MASK_DOORBELL	(1<<2)
191 #define ARC_RC_INTR_MASK_POSTQUEUE	(1<<3)
192 #define ARC_RC_REPLY_QUEUE_ERR		1
193 #define	ARC_RC_THROTTLE			12
194 
195 /* Areca boards using the Marvell IOP 9580 are Type D (RD) */
196 
197 #define ARC_RD_INTR_STAT		0x200
198 #define ARC_RD_HOST_INT_ENABLE		0x204
199 #define	ARC_RD_INTR_ENABLE		0x20C
200 #define	ARC_RD_D2I_MSG_CMD_DONE		0x08
201 #define	ARC_RD_I2D_MSG_CMD_DONE		0x2000000
202 #define	ARC_RD_I2D_MSG_CMD_DONE_CLR	0x2000000
203 #define ARC_RD_INB_MSGADDR0		0x400
204 #define ARC_RD_INB_MSGADDR1		0x404
205 #define ARC_RD_OUTB_MSGADDR0		0x420
206 #define ARC_RD_OUTB_MSGADDR1		0x424
207 #define ARC_RD_INB_DOORBELL		0x460
208 #define	ARC_RD_OUTB_DOORBELL		0x480
209 #define	ARC_RD_OUTB_DOORBELL_CLR	0x480
210 #define	ARC_RD_OUTB_DOORBELL_ENABLE	0x484
211 #define ARC_RD_OUTB_MSG_FIRMWARE_OK	0x80000000
212 #define ARC_RD_INB_POSTQ_LOW		0x1000
213 #define ARC_RD_INB_POSTQ_HIGH		0x1004
214 #define	ARC_RD_OUTB_REPLYQ_LOW		0x1060
215 #define	ARC_RD_OUTB_REPLYQ_HIGH		0x1064
216 
217 #define ARC_RD_INB_WRITE_PTR		0x1018
218 #define ARC_RD_INB_READ_PTR		0x101C
219 #define	ARC_RD_OUTB_COPY_PTR		0x106C
220 #define	ARC_RD_OUTB_READ_PTR		0x1070
221 #define	ARC_RD_OUTB_INTR_CAUSE		0x1088
222 #define	ARC_RD_OUTB_INT_ENABLE		0x108C
223 #define	ARC_RD_MSG_WBUF_LEN		0x2000
224 #define	ARC_RD_MSG_WBUF			0x2004
225 #define	ARC_RD_MSG_RBUF_LEN		0x2100
226 #define	ARC_RD_MSG_RBUF			0x2104
227 #define	ARC_RD_MSG_RWBUF		0x2200
228 
229 #define ARC_RD_INB_MSG0_NOP		(0x00000000)
230 #define ARC_RD_INB_MSG0_GET_CONFIG	(0x00000001)
231 #define ARC_RD_INB_MSG0_SET_CONFIG	(0x00000002)
232 #define ARC_RD_INB_MSG0_ABORT_CMD	(0x00000003)
233 #define ARC_RD_INB_MSG0_STOP_BGRB	(0x00000004)
234 #define ARC_RD_INB_MSG0_FLUSH_CACHE	(0x00000005)
235 #define ARC_RD_INB_MSG0_START_BGRB	(0x00000006)
236 #define ARC_RD_INB_MSG0_CHK331PENDING	(0x00000007)
237 #define ARC_RD_INB_MSG0_SYNC_TIMER	(0x00000008)
238 
239 #define ARC_RD_D2I_DATA_WRITE_OK	0x00000001
240 #define ARC_RD_D2I_DATA_READ_OK		0x00000002
241 #define ARC_RD_D2I_MESSAGE_CMD_DONE	0x02000000
242 #define ARC_RD_D2I_POSTQUEUE_THROTTLING	0x00000010
243 #define ARC_RD_I2D_DATA_WRITE_OK	0x00000001
244 #define ARC_RD_I2D_DATA_WRITE_CLEAR	0x00000001
245 #define ARC_RD_I2D_DATA_READ_OK		0x00000002
246 #define ARC_RD_I2D_DATA_READ_CLEAR	0x00000002
247 #define ARC_RD_I2D_MESSAGE_CMD_DONE	0x02000000
248 #define ARC_RD_I2D_MESSAGE_CMD_DONE_CLEAR 0x02000000
249 #define ARC_RD_MESSAGE_FIRMWARE_OK	0x80000000
250 
251 #define ARC_RD_INTR_STAT_DOORBELL	0x00001000
252 #define ARC_RD_INTR_STAT_POSTQUEUE	0x00000010
253 #define ARC_RD_INTR_ENABLE_ALL		0x00001010
254 #define ARC_RD_INTR_DISABLE_ALL		0x00000000
255 #define ARC_RD_INTR_ENABLE_DOORBELL	0x00001000
256 #define ARC_RD_INTR_ENABLE_POSTQUEUE	0x00000010
257 #define ARC_RD_REPLY_QUEUE_ERR		1
258 #define	ARC_RD_OUTB_LIST_INT_CLR	1
259 
260 struct arc_msg_firmware_info {
261 	u_int32_t		signature;
262 #define ARC_FWINFO_SIGNATURE_GET_CONFIG		(0x87974060)
263 #define ARC_FWINFO_SIGNATURE_SET_CONFIG		(0x87974063)
264 	u_int32_t		request_len;
265 	u_int32_t		queue_len;
266 	u_int32_t		sdram_size;
267 	u_int32_t		sata_ports;
268 	u_int8_t		vendor[40];
269 	u_int8_t		model[8];
270 	u_int8_t		fw_version[16];
271 	u_int8_t		device_map[16];
272 	u_int32_t		cfgVersion;
273 	u_int8_t		cfgSerial[16];
274 	u_int32_t		cfgPicStatus;
275 } __packed;
276 
277 /* definitions of the firmware commands sent via the doorbells */
278 
279 struct arc_fw_hdr {
280 	u_int8_t		byte1;
281 	u_int8_t		byte2;
282 	u_int8_t		byte3;
283 } __packed;
284 
285 /* the fw header must always equal this */
286 struct arc_fw_hdr arc_fw_hdr = { 0x5e, 0x01, 0x61 };
287 
288 struct arc_fw_bufhdr {
289 	struct arc_fw_hdr	hdr;
290 	u_int16_t		len;
291 } __packed;
292 
293 #define ARC_FW_RAIDINFO		0x20	/* opcode + raid# */
294 #define ARC_FW_VOLINFO		0x21	/* opcode + vol# */
295 #define ARC_FW_DISKINFO		0x22	/* opcode + physdisk# */
296 #define ARC_FW_SYSINFO		0x23	/* opcode. reply is fw_sysinfo */
297 #define ARC_FW_MUTE_ALARM	0x30	/* opcode only */
298 #define ARC_FW_SET_ALARM	0x31	/* opcode + 1 byte for setting */
299 #define ARC_FW_SET_ALARM_DISABLE	0x00
300 #define ARC_FW_SET_ALARM_ENABLE		0x01
301 #define ARC_FW_NOP		0x38	/* opcode only */
302 
303 #define ARC_FW_CMD_OK		0x41
304 #define ARC_FW_BLINK		0x43
305 #define ARC_FW_BLINK_ENABLE		0x00
306 #define ARC_FW_BLINK_DISABLE	0x01
307 #define ARC_FW_CMD_PASS_REQD	0x4d
308 
309 struct arc_fw_comminfo {
310 	u_int8_t		baud_rate;
311 	u_int8_t		data_bits;
312 	u_int8_t		stop_bits;
313 	u_int8_t		parity;
314 	u_int8_t		flow_control;
315 } __packed;
316 
317 struct arc_fw_scsiattr {
318 	u_int8_t		channel; /* channel for SCSI target (0/1) */
319 	u_int8_t		target;
320 	u_int8_t		lun;
321 	u_int8_t		tagged;
322 	u_int8_t		cache;
323 	u_int8_t		speed;
324 } __packed;
325 
326 struct arc_fw_raidinfo {
327 	u_int8_t		set_name[16];
328 	u_int32_t		capacity;
329 	u_int32_t		capacity2;
330 	u_int32_t		fail_mask;
331 	u_int8_t		device_array[32];
332 	u_int8_t		member_devices;
333 	u_int8_t		new_member_devices;
334 	u_int8_t		raid_state;
335 	u_int8_t		volumes;
336 	u_int8_t		volume_list[16];
337 	u_int8_t		reserved1[3];
338 	u_int8_t		free_segments;
339 	u_int32_t		raw_stripes[8];
340 	u_int32_t		reserved2[3];
341 	u_int8_t		vol_ListX[112];
342 	u_int8_t		devEncArray[32];
343 } __packed;
344 
345 struct arc_fw_volinfo {
346 	u_int8_t		set_name[16];
347 	u_int32_t		capacity;
348 	u_int32_t		capacity2;
349 	u_int32_t		fail_mask;
350 	u_int32_t		stripe_size; /* in blocks */
351 	u_int32_t		new_fail_mask;
352 	u_int32_t		new_stripe_size;
353 	u_int32_t		volume_status;
354 #define ARC_FW_VOL_STATUS_NORMAL	0x00
355 #define ARC_FW_VOL_STATUS_INITTING	(1<<0)
356 #define ARC_FW_VOL_STATUS_FAILED	(1<<1)
357 #define ARC_FW_VOL_STATUS_MIGRATING	(1<<2)
358 #define ARC_FW_VOL_STATUS_REBUILDING	(1<<3)
359 #define ARC_FW_VOL_STATUS_NEED_INIT	(1<<4)
360 #define ARC_FW_VOL_STATUS_NEED_MIGRATE	(1<<5)
361 #define ARC_FW_VOL_STATUS_INIT_FLAG	(1<<6)
362 #define ARC_FW_VOL_STATUS_NEED_REGEN	(1<<7)
363 #define ARC_FW_VOL_STATUS_CHECKING	(1<<8)
364 #define ARC_FW_VOL_STATUS_NEED_CHECK	(1<<9)
365 	u_int32_t		progress;
366 	struct arc_fw_scsiattr	scsi_attr;
367 	u_int8_t		member_disks;
368 	u_int8_t		raid_level;
369 #define ARC_FW_VOL_RAIDLEVEL_0		0x00
370 #define ARC_FW_VOL_RAIDLEVEL_1		0x01
371 #define ARC_FW_VOL_RAIDLEVEL_3		0x02
372 #define ARC_FW_VOL_RAIDLEVEL_5		0x03
373 #define ARC_FW_VOL_RAIDLEVEL_6		0x04
374 #define ARC_FW_VOL_RAIDLEVEL_PASSTHRU	0x05
375 	u_int8_t		new_member_disks;
376 	u_int8_t		new_raid_level;
377 	u_int8_t		raid_set_number;
378 	u_int8_t		vol_state0;
379 	u_int32_t		host_speed;
380 	u_int32_t		vol_state;
381 	u_int8_t		vol_array[16];
382 	u_int8_t		num_5060volumes;
383 	u_int8_t		reserved[43];
384 } __packed;
385 
386 struct arc_fw_diskinfo {
387 	u_int8_t		model[40];
388 	u_int8_t		serial[20];
389 	u_int8_t		firmware_rev[8];
390 	u_int32_t		capacity;
391 	u_int32_t		capacity2;
392 	u_int8_t		device_state;
393 	u_int8_t		pio_mode;
394 	u_int8_t		current_udma_mode;
395 	u_int8_t		udma_mode;
396 	u_int8_t		hot_spare_type;
397 	u_int8_t		raid_number; /* 0xff unowned */
398 	struct arc_fw_scsiattr	scsi_attr;
399 	u_int8_t		reserved[170];
400 } __packed;
401 
402 struct arc_fw_sysinfo {
403 	u_int8_t		vendor_name[40];
404 	u_int8_t		serial_number[16];
405 	u_int8_t		firmware_version[16];
406 	u_int8_t		boot_version[16];
407 	u_int8_t		mb_version[16];
408 	u_int8_t		model_name[8];
409 
410 	u_int8_t		local_ip[4];
411 	u_int8_t		current_ip[4];
412 
413 	u_int32_t		time_tick;
414 	u_int32_t		cpu_speed;
415 	u_int32_t		icache;
416 	u_int32_t		dcache;
417 	u_int32_t		scache;
418 	u_int32_t		memory_size;
419 	u_int32_t		memory_speed;
420 	u_int32_t		events;
421 
422 	u_int8_t		gsiMacAddress[6];
423 	u_int8_t		gsiDhcp;
424 	u_int8_t		alarm;
425 	u_int8_t		channel_usage;
426 	u_int8_t		max_ata_mode;
427 	u_int8_t		sdram_ecc;
428 	u_int8_t		rebuild_priority;
429 	struct arc_fw_comminfo	comm_a;
430 	struct arc_fw_comminfo	comm_b;
431 	u_int8_t		ide_channels;
432 	u_int8_t		scsi_host_channels;
433 	u_int8_t		ide_host_channels;
434 	u_int8_t		max_volume_set;
435 	u_int8_t		max_raid_set;
436 	u_int8_t		ether_port;
437 	u_int8_t		raid6_engine;
438 	u_int8_t		reserved[75];
439 } __packed;
440 
441 struct arc_iop;
442 struct arc_ccb;
443 SLIST_HEAD(arc_ccb_list, arc_ccb);
444 
445 struct InBound_SRB {
446 	u_int32_t addressLow;	/* pointer to SRB block */
447 	u_int32_t addressHigh;
448 	u_int32_t length;	/* in DWORDs */
449 	u_int32_t reserved0;
450 };
451 
452 struct OutBound_SRB {
453 	u_int32_t addressLow;	/* pointer to SRB block */
454 	u_int32_t addressHigh;
455 };
456 
457 struct arc_HBD_Msgu {
458  	struct InBound_SRB post_qbuffer[ARCMSR_MAX_HBD_POSTQUEUE];
459    	struct OutBound_SRB done_qbuffer[ARCMSR_MAX_HBD_POSTQUEUE+1];
460 	u_int16_t postq_index;
461 	u_int16_t doneq_index;
462 };
463 
464 #define		ARC_MAX_CMDQ_PTR_LEN	sizeof(struct arc_HBD_Msgu)
465 
466 struct arc_msg_scsicmd {
467 	u_int8_t		bus;
468 	u_int8_t		target;
469 	u_int8_t		lun;
470 	u_int8_t		function;
471 
472 	u_int8_t		cdb_len;
473 	u_int8_t		sgl_len;
474 	u_int8_t		flags;
475 #define ARC_MSG_SCSICMD_FLAG_SGL_BSIZE_512	(1<<0)
476 #define ARC_MSG_SCSICMD_FLAG_FROM_BIOS		(1<<1)
477 #define ARC_MSG_SCSICMD_FLAG_WRITE		(1<<2)
478 #define ARC_MSG_SCSICMD_FLAG_SIMPLEQ	(0x00)
479 #define ARC_MSG_SCSICMD_FLAG_HEADQ		(0x08)
480 #define ARC_MSG_SCSICMD_FLAG_ORDERQ		(0x10)
481 	u_int8_t		msgPages;
482 
483 	u_int32_t		context;
484 	u_int32_t		data_len;
485 
486 #define ARC_MSG_CDBLEN				16
487 	u_int8_t		cdb[ARC_MSG_CDBLEN];
488 
489 	u_int8_t		status;
490 #define ARC_MSG_STATUS_SELTIMEOUT		0xf0
491 #define ARC_MSG_STATUS_ABORTED			0xf1
492 #define ARC_MSG_STATUS_INIT_FAIL		0xf2
493 #define ARC_MSG_SENSELEN			15
494 	u_int8_t		sense_data[ARC_MSG_SENSELEN];
495 
496 	/* followed by an sgl */
497 } __packed;
498 
499 struct arc_sge {
500 	u_int32_t		sg_length;
501 #define ARC_SGE_64BIT				(1<<24)
502 	u_int32_t		sg_lo_addr;
503 	u_int32_t		sg_hi_addr;
504 } __packed;
505 
506 #define ARC_MAX_TARGET		16
507 #define ARC_MAX_LUN		8
508 #define ARC_MAX_IOCMDLEN	512
509 #define ARC_BLOCKSIZE		512
510 
511 /* the firmware deals with up to 256 or 512 byte command frames. */
512 /* sizeof(struct arc_msg_scsicmd) + (sizeof(struct arc_sge) * 38) == 508 */
513 #define ARC_SGL_MAXLEN		38
514 /* sizeof(struct arc_msg_scsicmd) + (sizeof(struct arc_sge) * 17) == 252 */
515 #define ARC_SGL_256LEN		17
516 
517 struct arc_io_cmd {
518 	struct arc_msg_scsicmd	cmd;
519 	struct arc_sge	sgl[ARC_SGL_MAXLEN];
520 	u_int32_t		reserved1;
521 	struct arc_ccb	*ccb;
522 	u_int32_t		reserved2[6];
523 } __packed;
524 
525 #define ARC_IO_CMD_LEN	512+32
526 
527 /* stuff to manage a scsi command */
528 struct arc_ccb {
529 	struct arc_softc	*ccb_sc;
530 
531 	struct scsi_xfer	*ccb_xs;
532 
533 	bus_dmamap_t		ccb_dmamap;
534 	bus_addr_t		cmd_dma_offset;
535 	struct arc_io_cmd	*ccb_cmd;
536 	u_int32_t		ccb_cmd_post;
537 
538 	SLIST_ENTRY(arc_ccb)	ccb_link;
539 	u_int32_t		arc_io_cmd_length;
540 };
541 
542 struct arc_softc {
543 	struct device		sc_dev;
544 	const struct arc_iop	*sc_iop;
545 	struct scsi_link	sc_link;
546 
547 	pci_chipset_tag_t	sc_pc;
548 	pcitag_t		sc_tag;
549 
550 	bus_space_tag_t		sc_iot;
551 	bus_space_handle_t	sc_ioh;
552 	bus_size_t		sc_ios;
553 	bus_dma_tag_t		sc_dmat;
554 
555 	void			*sc_ih;
556 
557 	u_int32_t		sc_req_count;
558 
559 	struct arc_dmamem	*sc_requests;
560 	struct arc_ccb		*sc_ccbs;
561 	struct arc_ccb_list	sc_ccb_free;
562 	struct mutex		sc_ccb_mtx;
563 
564 	struct scsi_iopool	sc_iopool;
565 	struct scsibus_softc	*sc_scsibus;
566 
567 	struct rwlock		sc_lock;
568 	volatile int		sc_talking;
569 
570 	struct ksensor		*sc_sensors;
571 	struct ksensordev	sc_sensordev;
572 	int			sc_nsensors;
573 
574 	u_int32_t		sc_ledmask;
575 	u_int32_t		sc_adp_type;
576 	u_int32_t		sc_ccb_phys_hi;
577 	u_int32_t		postQ_buffer;
578 	u_int32_t		doneQ_buffer;
579 	bus_addr_t		cmdQ_ptr_offset;
580 	struct arc_HBD_Msgu *pmu;
581 };
582 #define DEVNAME(_s)		((_s)->sc_dev.dv_xname)
583 
584 /* wrap up the bus_dma api */
585 struct arc_dmamem {
586 	bus_dmamap_t		adm_map;
587 	bus_dma_segment_t	adm_seg;
588 	size_t			adm_size;
589 	caddr_t			adm_kva;
590 };
591 #define ARC_DMA_MAP(_adm)	((_adm)->adm_map)
592 #define ARC_DMA_DVA(_adm)	((_adm)->adm_map->dm_segs[0].ds_addr)
593 #define ARC_DMA_KVA(_adm)	((void *)(_adm)->adm_kva)
594 
595 int	arc_match(struct device *, void *, void *);
596 void	arc_attach(struct device *, struct device *, void *);
597 int	arc_detach(struct device *, int);
598 int	arc_activate(struct device *, int);
599 int	arc_intr(void *);
600 int	arc_intr_A(void *);
601 int	arc_intr_C(void *);
602 int	arc_intr_D(void *);
603 
604 /* interface for scsi midlayer to talk to */
605 void	arc_scsi_cmd(struct scsi_xfer *);
606 void	arc_minphys(struct buf *, struct scsi_link *);
607 
608 /* code to deal with getting bits in and out of the bus space */
609 u_int32_t	arc_read(struct arc_softc *, bus_size_t);
610 void		arc_read_region(struct arc_softc *, bus_size_t,
611 			    void *, size_t);
612 void		arc_write(struct arc_softc *, bus_size_t, u_int32_t);
613 void		arc_write_region(struct arc_softc *, bus_size_t,
614 			    void *, size_t);
615 int			arc_wait_eq(struct arc_softc *, bus_size_t,
616 			    u_int32_t, u_int32_t);
617 int			arc_wait_ne(struct arc_softc *, bus_size_t,
618 			    u_int32_t, u_int32_t);
619 int			arc_msg0(struct arc_softc *, u_int32_t);
620 
621 struct arc_dmamem	*arc_dmamem_alloc(struct arc_softc *, size_t);
622 void		arc_dmamem_free(struct arc_softc *,
623 			    struct arc_dmamem *);
624 void arc_free_ccb_src(struct arc_softc *sc);
625 
626 int			arc_alloc_ccbs(struct arc_softc *);
627 struct arc_ccb	*arc_get_ccb(struct arc_softc *);
628 void		arc_put_ccb(struct arc_softc *, struct arc_ccb *);
629 int			arc_load_xs(struct arc_ccb *);
630 int			arc_complete(struct arc_softc *, struct arc_ccb *,
631 			    int);
632 void		arc_scsi_cmd_done(struct arc_softc *, struct arc_ccb *,
633 			    u_int32_t);
634 
635 int			arc_map_pci_resources(struct arc_softc *,
636 			    struct pci_attach_args *);
637 void		arc_unmap_pci_resources(struct arc_softc *);
638 int		arc_chipA_firmware(struct arc_softc *);
639 int		arc_chipB_firmware(struct arc_softc *);
640 int		arc_chipC_firmware(struct arc_softc *);
641 int		arc_chipD_firmware(struct arc_softc *);
642 void 		arc_enable_all_intr(struct arc_softc *);
643 void 		arc_disable_all_intr(struct arc_softc *);
644 void 		arc_stop_bgrb_proc(struct arc_softc *sc);
645 void 		arc_flush_cache(struct arc_softc *sc);
646 void		arc_iop_set_conf(struct arc_softc *sc);
647 
648 #if NBIO > 0
649 /* stuff to do messaging via the doorbells */
650 void		arc_lock(struct arc_softc *);
651 void		arc_unlock(struct arc_softc *);
652 void		arc_wait(struct arc_softc *);
653 u_int8_t	arc_msg_cksum(void *, u_int16_t);
654 int			arc_msgbuf(struct arc_softc *, void *, size_t,
655 			    void *, size_t, int);
656 
657 /* bioctl */
658 int			arc_bioctl(struct device *, u_long, caddr_t);
659 int			arc_bio_inq(struct arc_softc *, struct bioc_inq *);
660 int			arc_bio_vol(struct arc_softc *, struct bioc_vol *);
661 int			arc_bio_disk(struct arc_softc *, struct bioc_disk *);
662 int			arc_bio_alarm(struct arc_softc *, struct bioc_alarm *);
663 int			arc_bio_alarm_state(struct arc_softc *,
664 			    struct bioc_alarm *);
665 int			arc_bio_blink(struct arc_softc *, struct bioc_blink *);
666 
667 int			arc_bio_getvol(struct arc_softc *, int,
668 			    struct arc_fw_volinfo *);
669 
670 #ifndef SMALL_KERNEL
671 /* sensors */
672 void			arc_create_sensors(void *, void *);
673 void			arc_refresh_sensors(void *);
674 #endif /* SMALL_KERNEL */
675 #endif
676 
677 struct cfattach arc_ca = {
678 	sizeof(struct arc_softc), arc_match, arc_attach, arc_detach,
679 	arc_activate
680 };
681 
682 struct cfdriver arc_cd = {
683 	NULL, "arc", DV_DULL
684 };
685 
686 struct scsi_adapter arc_switch = {
687 	arc_scsi_cmd, arc_minphys, NULL, NULL, NULL
688 };
689 
690 /* real stuff for dealing with the hardware */
691 struct arc_iop {
692 	int			(*iop_query_firmware)(struct arc_softc *);
693 };
694 
695 static const struct arc_iop arc_intel = {
696 	arc_chipA_firmware
697 };
698 
699 static const struct arc_iop arc_marvell = {
700 	arc_chipB_firmware
701 };
702 
703 static const struct arc_iop arc_lsi = {
704 	arc_chipC_firmware
705 };
706 
707 static const struct arc_iop arc_marvell2 = {
708 	arc_chipD_firmware
709 };
710 
711 struct arc_board {
712 	pcireg_t		ab_vendor;
713 	pcireg_t		ab_product;
714 	const struct arc_iop	*ab_iop;
715 };
716 const struct arc_board	*arc_match_board(struct pci_attach_args *);
717 
718 static const struct arc_board arc_devices[] = {
719 	{ PCI_VENDOR_ARECA, PCI_PRODUCT_ARECA_ARC1110, &arc_intel },
720 	{ PCI_VENDOR_ARECA, PCI_PRODUCT_ARECA_ARC1120, &arc_intel },
721 	{ PCI_VENDOR_ARECA, PCI_PRODUCT_ARECA_ARC1130, &arc_intel },
722 	{ PCI_VENDOR_ARECA, PCI_PRODUCT_ARECA_ARC1160, &arc_intel },
723 	{ PCI_VENDOR_ARECA, PCI_PRODUCT_ARECA_ARC1170, &arc_intel },
724 	{ PCI_VENDOR_ARECA, PCI_PRODUCT_ARECA_ARC1200, &arc_intel },
725 	{ PCI_VENDOR_ARECA, PCI_PRODUCT_ARECA_ARC1200_B, &arc_marvell },
726 	{ PCI_VENDOR_ARECA, PCI_PRODUCT_ARECA_ARC1202, &arc_intel },
727 	{ PCI_VENDOR_ARECA, PCI_PRODUCT_ARECA_ARC1210, &arc_intel },
728 	{ PCI_VENDOR_ARECA, PCI_PRODUCT_ARECA_ARC1214, &arc_marvell2 },
729 	{ PCI_VENDOR_ARECA, PCI_PRODUCT_ARECA_ARC1220, &arc_intel },
730 	{ PCI_VENDOR_ARECA, PCI_PRODUCT_ARECA_ARC1230, &arc_intel },
731 	{ PCI_VENDOR_ARECA, PCI_PRODUCT_ARECA_ARC1260, &arc_intel },
732 	{ PCI_VENDOR_ARECA, PCI_PRODUCT_ARECA_ARC1270, &arc_intel },
733 	{ PCI_VENDOR_ARECA, PCI_PRODUCT_ARECA_ARC1280, &arc_intel },
734 	{ PCI_VENDOR_ARECA, PCI_PRODUCT_ARECA_ARC1380, &arc_intel },
735 	{ PCI_VENDOR_ARECA, PCI_PRODUCT_ARECA_ARC1381, &arc_intel },
736 	{ PCI_VENDOR_ARECA, PCI_PRODUCT_ARECA_ARC1680, &arc_intel },
737 	{ PCI_VENDOR_ARECA, PCI_PRODUCT_ARECA_ARC1681, &arc_intel },
738 	{ PCI_VENDOR_ARECA, PCI_PRODUCT_ARECA_ARC1880, &arc_lsi }
739 };
740 
741 const struct arc_board *
742 arc_match_board(struct pci_attach_args *pa)
743 {
744 	const struct arc_board		*ab;
745 	int				i;
746 
747 	for (i = 0; i < sizeof(arc_devices) / sizeof(arc_devices[0]); i++) {
748 		ab = &arc_devices[i];
749 
750 		if (PCI_VENDOR(pa->pa_id) == ab->ab_vendor &&
751 		    PCI_PRODUCT(pa->pa_id) == ab->ab_product)
752 			return (ab);
753 	}
754 
755 	return (NULL);
756 }
757 
758 int
759 arc_match(struct device *parent, void *match, void *aux)
760 {
761 	return ((arc_match_board(aux) == NULL) ? 0 : 1);
762 }
763 
764 void
765 arc_attach(struct device *parent, struct device *self, void *aux)
766 {
767 	struct arc_softc		*sc = (struct arc_softc *)self;
768 	struct pci_attach_args		*pa = aux;
769 	struct scsibus_attach_args	saa;
770 	struct device			*child;
771 
772 	sc->sc_talking = 0;
773 	rw_init(&sc->sc_lock, "arcmsg");
774 
775 	sc->sc_iop = arc_match_board(pa)->ab_iop;
776 	if(sc->sc_iop == &arc_intel)
777 		sc->sc_adp_type = ARC_HBA_TYPE_A;
778 	else if(sc->sc_iop == &arc_marvell)
779 		sc->sc_adp_type = ARC_HBA_TYPE_B;
780 	else if(sc->sc_iop == &arc_lsi)
781 		sc->sc_adp_type = ARC_HBA_TYPE_C;
782 	else if(sc->sc_iop == &arc_marvell2)
783 		sc->sc_adp_type = ARC_HBA_TYPE_D;
784 	if (arc_map_pci_resources(sc, pa) != 0) {
785 		/* error message printed by arc_map_pci_resources */
786 		return;
787 	}
788 
789 	if (arc_alloc_ccbs(sc) != 0) {
790 		/* error message printed by arc_alloc_ccbs */
791 		goto unmap_pci;
792 	}
793 
794 	arc_iop_set_conf(sc);
795 
796 	if (sc->sc_iop->iop_query_firmware(sc) != 0) {
797 		/* error message printed by arc_query_firmware */
798 		goto unmap_pci;
799 	}
800 
801 	sc->sc_link.adapter = &arc_switch;
802 	sc->sc_link.adapter_softc = sc;
803 	sc->sc_link.adapter_target = ARC_MAX_TARGET;
804 	sc->sc_link.adapter_buswidth = ARC_MAX_TARGET;
805 	sc->sc_link.openings = sc->sc_req_count;
806 	sc->sc_link.pool = &sc->sc_iopool;
807 
808 	bzero(&saa, sizeof(saa));
809 	saa.saa_sc_link = &sc->sc_link;
810 
811 	child = config_found(self, &saa, scsiprint);
812 	sc->sc_scsibus = (struct scsibus_softc *)child;
813 
814 	/* enable interrupts */
815 	arc_enable_all_intr(sc);
816 
817 #if NBIO > 0
818 	if (bio_register(self, arc_bioctl) != 0)
819 		panic("%s: bioctl registration failed", DEVNAME(sc));
820 
821 #ifndef SMALL_KERNEL
822 	/*
823 	 * you need to talk to the firmware to get volume info. our firmware
824 	 * interface relies on being able to sleep, so we need to use a thread
825 	 * to do the work.
826 	 */
827 	if (scsi_task(arc_create_sensors, sc, NULL, 1) != 0)
828 		printf("%s: unable to schedule arc_create_sensors as a "
829 		    "scsi task", DEVNAME(sc));
830 #endif
831 #endif
832 
833 	return;
834 unmap_pci:
835 	arc_unmap_pci_resources(sc);
836 }
837 
838 int
839 arc_activate(struct device *self, int act)
840 {
841 	int rv = 0;
842 
843 	switch (act) {
844 	case DVACT_POWERDOWN:
845 		rv = config_activate_children(self, act);
846 		arc_detach(self, 0);
847 		break;
848 	default:
849 		rv = config_activate_children(self, act);
850 		break;
851 	}
852 	return (rv);
853 }
854 
855 int
856 arc_detach(struct device *self, int flags)
857 {
858 	struct arc_softc		*sc = (struct arc_softc *)self;
859 
860 	arc_stop_bgrb_proc(sc);
861 	arc_flush_cache(sc);
862 
863 	return (0);
864 }
865 
866 int
867 arc_intr_A(void *arg)
868 {
869 	struct arc_softc		*sc = arg;
870 	struct arc_ccb			*ccb = NULL;
871 	char				*kva = ARC_DMA_KVA(sc->sc_requests);
872 	struct arc_io_cmd		*cmd;
873 	u_int32_t			reg, intrstat, error;
874 	int				ret = 0;
875 
876 	intrstat = arc_read(sc, ARC_RA_INTRSTAT);
877 	intrstat &= ARC_RA_INTRSTAT_POSTQUEUE | ARC_RA_INTRSTAT_DOORBELL |
878 		ARC_RA_INTRSTAT_MSG0;
879 	arc_write(sc, ARC_RA_INTRSTAT, intrstat);
880 
881 	if (intrstat & ARC_RA_INTRSTAT_DOORBELL) {
882 		ret = 1;
883 		if (sc->sc_talking) {
884 			/* if an ioctl is talking, wake it up */
885 			arc_write(sc, ARC_RA_INTRMASK,
886 			    ~ARC_RA_INTRMASK_POSTQUEUE);
887 			wakeup(sc);
888 		} else {
889 			/* otherwise drop it */
890 			reg = arc_read(sc, ARC_RA_OUTB_DOORBELL);
891 			arc_write(sc, ARC_RA_OUTB_DOORBELL, reg);
892 			if (reg & ARC_RA_OUTB_DOORBELL_WRITE_OK)
893 				arc_write(sc, ARC_RA_INB_DOORBELL,
894 				    ARC_RA_INB_DOORBELL_READ_OK);
895 		}
896 	}
897 
898 	if (intrstat & ARC_RA_INTRSTAT_POSTQUEUE) {
899 		while ((reg = arc_read(sc, ARC_RA_REPLY_QUEUE)) != 0xffffffff) {
900 			ret = 1;
901 			cmd = (struct arc_io_cmd *)(kva +
902 		    	((reg << ARC_RA_REPLY_QUEUE_ADDR_SHIFT) -
903 		    	(u_int32_t)ARC_DMA_DVA(sc->sc_requests)));
904 			ccb = cmd->ccb;
905 
906 			bus_dmamap_sync(sc->sc_dmat, ARC_DMA_MAP(sc->sc_requests),
907 		    	ccb->cmd_dma_offset, ARC_MAX_IOCMDLEN,
908 		    	BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
909 
910 			error = (reg & ARC_RA_REPLY_QUEUE_ERR)? 1:0;
911 			arc_scsi_cmd_done(sc, ccb, error);
912 		}
913 	}
914 	return (ret);
915 }
916 
917 int
918 arc_intr_C(void *arg)
919 {
920 	struct arc_softc		*sc = arg;
921 	struct arc_ccb			*ccb = NULL;
922 	char				*kva = ARC_DMA_KVA(sc->sc_requests);
923 	struct arc_io_cmd		*cmd;
924 	u_int32_t			reg, intrstat, obmsg, error;
925 	int				ret = 0, throttling;
926 
927 	intrstat = arc_read(sc, ARC_RC_INTR_STAT);
928 	if (!(intrstat & (ARC_RC_INTR_STAT_POSTQUEUE |
929 		ARC_RC_INTR_STAT_DOORBELL)))
930 		return (ret);
931 
932 	if (intrstat & ARC_RC_INTR_STAT_DOORBELL) {
933 		ret = 1;
934 		if (sc->sc_talking) {
935 			/* if an ioctl is talking, wake it up */
936 			arc_write(sc, ARC_RC_INTR_MASK,
937 			    ~ARC_RC_INTR_MASK_POSTQUEUE);
938 			wakeup(sc);
939 		} else {
940 			/* otherwise drop it */
941 			reg = arc_read(sc, ARC_RC_OUTB_DOORBELL);
942 			arc_write(sc, ARC_RC_OUTB_DOORBELL_CLR, reg);
943 			if (reg & ARC_RC_I2D_DATA_WRITE_OK) {
944 				arc_write(sc, ARC_RC_INB_DOORBELL,
945 				    ARC_RC_I2D_DATA_READ_OK);
946 			}
947 /*			if (reg & ARC_RC_I2D_DATA_READ_OK) {
948 				arc_write(sc, ARC_RC_INB_DOORBELL,
949 				    ARC_RC_D2I_DATA_WRITE_OK);
950 			}
951 */
952 			if (reg & ARC_RC_I2D_MESSAGE_CMD_DONE) {
953 				arc_write(sc, ARC_RC_OUTB_DOORBELL_CLR,
954 					ARC_RC_I2D_MSG_CMD_DONE_CLR);
955 				obmsg = arc_read(sc, ARC_RC_MSG_RWBUF);
956 				if (obmsg == ARC_FWINFO_SIGNATURE_GET_CONFIG)
957 					;	/* handle devices hot-plug */
958 			}
959 
960 		}
961 	}
962 
963 	if (intrstat & ARC_RC_INTR_STAT_POSTQUEUE) {
964 		ret = 1;
965 		throttling = 0;
966 		while (arc_read(sc, ARC_RC_INTR_STAT) &
967 			ARC_RC_INTR_STAT_POSTQUEUE) {
968 			reg = arc_read(sc, ARC_RC_OUTB_REPLYQ_LOW);
969 			cmd = (struct arc_io_cmd *)(kva + ((reg & 0xFFFFFFE0) -
970 		    	(u_int32_t)ARC_DMA_DVA(sc->sc_requests)));
971 			ccb = cmd->ccb;
972 
973 			bus_dmamap_sync(sc->sc_dmat, ARC_DMA_MAP(sc->sc_requests),
974 		    	ccb->cmd_dma_offset, ARC_MAX_IOCMDLEN,
975 		    	BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
976 
977 			error = (reg & ARC_RC_REPLY_QUEUE_ERR);
978 			arc_scsi_cmd_done(sc, ccb, error);
979 			throttling++;
980 			if(throttling == ARC_RC_THROTTLE) {
981 				arc_write(sc, ARC_RC_INB_DOORBELL,
982 				    ARC_RC_D2I_POSTQUEUE_THROTTLING);
983 				throttling = 0;
984 			}
985 		}
986 	}
987 
988 	return (ret);
989 }
990 
991 static u_int16_t
992 arcmsr_get_doneq_index(struct arc_HBD_Msgu *phbdmu)
993 {
994 	u_int16_t doneq_index, index_stripped;
995 
996 	doneq_index = phbdmu->doneq_index;
997 	if (doneq_index & 0x4000) {
998 		index_stripped = doneq_index & 0xFF;
999 		index_stripped += 1;
1000 		index_stripped %= ARCMSR_MAX_HBD_POSTQUEUE;
1001 		phbdmu->doneq_index = index_stripped ?
1002 		    (index_stripped | 0x4000) : index_stripped;
1003 	} else {
1004 		index_stripped = doneq_index;
1005 		index_stripped += 1;
1006 		index_stripped %= ARCMSR_MAX_HBD_POSTQUEUE;
1007 		phbdmu->doneq_index = index_stripped ?
1008 		    index_stripped : (index_stripped | 0x4000);
1009 	}
1010 	return (phbdmu->doneq_index);
1011 }
1012 
1013 int
1014 arc_intr_D(void *arg)
1015 {
1016 	struct arc_softc		*sc = arg;
1017 	struct arc_ccb			*ccb = NULL;
1018 	char				*kva = ARC_DMA_KVA(sc->sc_requests);
1019 	struct arc_io_cmd		*cmd;
1020 	u_int32_t			reg, intrstat, obmsg, error;
1021 	u_int32_t ob_write_ptr;
1022 	u_int16_t doneq_index;
1023 	int				ret = 0;
1024 	struct arc_HBD_Msgu *pmu;
1025 
1026 	intrstat = arc_read(sc, ARC_RD_INTR_STAT);
1027 	if (!(intrstat & (ARC_RD_INTR_STAT_POSTQUEUE |
1028 		ARC_RD_INTR_STAT_DOORBELL)))
1029 		return (ret);
1030 
1031 	if (intrstat & ARC_RD_INTR_STAT_DOORBELL) {
1032 		ret = 1;
1033 		if (sc->sc_talking) {
1034 			/* if an ioctl is talking, wake it up */
1035 			arc_write(sc, ARC_RD_INTR_ENABLE,
1036 			    ARC_RD_INTR_ENABLE_POSTQUEUE);
1037 			wakeup(sc);
1038 		} else {
1039 			/* otherwise drop it */
1040 			reg = arc_read(sc, ARC_RD_OUTB_DOORBELL);
1041 			arc_write(sc, ARC_RD_OUTB_DOORBELL, reg);
1042 			if (reg & ARC_RD_I2D_DATA_WRITE_OK) {
1043 				arc_write(sc, ARC_RD_INB_DOORBELL,
1044 				    ARC_RD_I2D_DATA_READ_OK);
1045 			}
1046 /*			if (reg & ARC_RD_I2D_DATA_READ_OK) {
1047 				arc_write(sc, ARC_RD_INB_DOORBELL,
1048 				    ARC_RD_D2I_DATA_WRITE_OK);
1049 			}
1050 */
1051 			if (reg & ARC_RD_I2D_MESSAGE_CMD_DONE) {
1052 				arc_write(sc, ARC_RD_OUTB_DOORBELL_CLR,
1053 					ARC_RD_I2D_MSG_CMD_DONE_CLR);
1054 				obmsg = arc_read(sc, ARC_RD_MSG_RWBUF);
1055 				if (obmsg == ARC_FWINFO_SIGNATURE_GET_CONFIG)
1056 					;	/* handle devices hot-plug */
1057 			}
1058 
1059 		}
1060 	}
1061 
1062 	if (intrstat & ARC_RD_INTR_STAT_POSTQUEUE) {
1063 		ret = 1;
1064 		arc_write(sc, ARC_RD_OUTB_INTR_CAUSE, ARC_RD_OUTB_LIST_INT_CLR);
1065 		bus_dmamap_sync(sc->sc_dmat, ARC_DMA_MAP(sc->sc_requests),
1066 		    sc->cmdQ_ptr_offset, ARC_MAX_CMDQ_PTR_LEN,
1067 		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
1068 		pmu = sc->pmu;
1069 		ob_write_ptr = pmu->done_qbuffer[0].addressLow;
1070 		doneq_index = pmu->doneq_index;
1071 		while ((doneq_index & 0xFF) != (ob_write_ptr & 0xFF)) {
1072 			doneq_index = arcmsr_get_doneq_index(pmu);
1073 			reg = pmu->done_qbuffer[(doneq_index & 0xFF)+1].addressLow;
1074 			cmd = (struct arc_io_cmd *)(kva + ((reg & 0xFFFFFFF0) -
1075 		    	(u_int32_t)ARC_DMA_DVA(sc->sc_requests)));
1076 			ccb = cmd->ccb;
1077 			bus_dmamap_sync(sc->sc_dmat, ARC_DMA_MAP(sc->sc_requests),
1078 		   		ccb->cmd_dma_offset, ARC_MAX_IOCMDLEN,
1079 		   		BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
1080 			error = (reg & ARC_RD_REPLY_QUEUE_ERR);
1081 			arc_scsi_cmd_done(sc, ccb, error);
1082 			arc_write(sc, ARC_RD_OUTB_READ_PTR, doneq_index);
1083 			ob_write_ptr = pmu->done_qbuffer[0].addressLow;
1084 		}
1085 	}
1086 
1087 	return (ret);
1088 }
1089 
1090 int
1091 arc_intr(void *arg)
1092 {
1093 	struct arc_softc	*sc = arg;
1094 	int		ret = 0;
1095 
1096 	switch(sc->sc_adp_type) {
1097 	case ARC_HBA_TYPE_A:
1098 		ret = arc_intr_A(arg);
1099 		break;
1100 	case ARC_HBA_TYPE_C:
1101 		ret = arc_intr_C(arg);
1102 		break;
1103 	case ARC_HBA_TYPE_D:
1104 		ret = arc_intr_D(arg);
1105 		break;
1106 	}
1107 	return (ret);
1108 }
1109 
1110 void
1111 arc_scsi_cmd(struct scsi_xfer *xs)
1112 {
1113 	struct scsi_link		*link = xs->sc_link;
1114 	struct arc_softc		*sc = link->adapter_softc;
1115 	struct arc_ccb			*ccb;
1116 	struct arc_msg_scsicmd		*cmd;
1117 	u_int32_t			reg, cdb_len;
1118 	int				s;
1119 	struct arc_HBD_Msgu *pmu;
1120 	u_int16_t index_stripped;
1121 	u_int16_t postq_index;
1122 	struct InBound_SRB *pinbound_srb;
1123 
1124 	if (xs->cmdlen > ARC_MSG_CDBLEN) {
1125 		bzero(&xs->sense, sizeof(xs->sense));
1126 		xs->sense.error_code = SSD_ERRCODE_VALID | 0x70;
1127 		xs->sense.flags = SKEY_ILLEGAL_REQUEST;
1128 		xs->sense.add_sense_code = 0x20;
1129 		xs->error = XS_SENSE;
1130 		scsi_done(xs);
1131 		return;
1132 	}
1133 
1134 	ccb = xs->io;
1135 	ccb->ccb_xs = xs;
1136 
1137 	if (arc_load_xs(ccb) != 0) {
1138 		xs->error = XS_DRIVER_STUFFUP;
1139 		scsi_done(xs);
1140 		return;
1141 	}
1142 
1143 	cmd = &ccb->ccb_cmd->cmd;
1144 	reg = ccb->ccb_cmd_post;
1145 	ccb->ccb_cmd->ccb = ccb;
1146 	/* bus is always 0 */
1147 	cmd->target = link->target;
1148 	cmd->lun = link->lun;
1149 	cmd->function = 1; /* XXX magic number */
1150 
1151 	cmd->cdb_len = xs->cmdlen;
1152 	cmd->sgl_len = ccb->ccb_dmamap->dm_nsegs;
1153 	if (xs->flags & SCSI_DATA_OUT)
1154 		cmd->flags = ARC_MSG_SCSICMD_FLAG_WRITE;
1155 	if (ccb->ccb_dmamap->dm_nsegs > ARC_SGL_256LEN) {
1156 		cmd->flags |= ARC_MSG_SCSICMD_FLAG_SGL_BSIZE_512;
1157 /*		reg |= ARC_RA_POST_QUEUE_BIGFRAME; */
1158 	}
1159 
1160 	cmd->data_len = htole32(xs->datalen);
1161 
1162 	bcopy(xs->cmd, cmd->cdb, xs->cmdlen);
1163 
1164 	/* we've built the command, let's put it on the hw */
1165 	bus_dmamap_sync(sc->sc_dmat, ARC_DMA_MAP(sc->sc_requests),
1166 	    ccb->cmd_dma_offset, ARC_MAX_IOCMDLEN,
1167 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
1168 
1169 	s = splbio();
1170 	switch(sc->sc_adp_type) {
1171 	case ARC_HBA_TYPE_A:
1172 		if (cmd->flags & ARC_MSG_SCSICMD_FLAG_SGL_BSIZE_512)
1173 			reg |= ARC_RA_POST_QUEUE_BIGFRAME;
1174 		arc_write(sc, ARC_RA_POST_QUEUE, reg);
1175 		break;
1176 	case ARC_HBA_TYPE_C:
1177 		cdb_len = sizeof(struct arc_msg_scsicmd) +
1178 			sizeof(struct arc_sge) * ccb->ccb_dmamap->dm_nsegs;
1179 		if (cdb_len > 0x300)
1180 			cdb_len = 0x300;
1181 		reg = reg | ((cdb_len - 1) >> 6) | 1;
1182 		if (sc->sc_ccb_phys_hi)
1183 			arc_write(sc, ARC_RC_INB_POSTQ_HIGH, sc->sc_ccb_phys_hi);
1184 		arc_write(sc, ARC_RC_INB_POSTQ_LOW, reg);
1185 		break;
1186 	case ARC_HBA_TYPE_D:
1187 			pmu = sc->pmu;
1188 			postq_index = pmu->postq_index;
1189 			pinbound_srb = (struct InBound_SRB *)&pmu->post_qbuffer[postq_index & 0xFF];
1190 
1191 			pinbound_srb->addressHigh = sc->sc_ccb_phys_hi;
1192 			pinbound_srb->addressLow = ccb->ccb_cmd_post;
1193 			pinbound_srb->length = ccb->arc_io_cmd_length >> 2;
1194 			cmd->context = ccb->ccb_cmd_post;
1195 			if (postq_index & 0x4000) {
1196 				index_stripped = postq_index & 0xFF;
1197 				index_stripped += 1;
1198 				index_stripped %= ARCMSR_MAX_HBD_POSTQUEUE;
1199 				pmu->postq_index = index_stripped ? (index_stripped | 0x4000) : index_stripped;
1200 			} else {
1201 				index_stripped = postq_index;
1202 				index_stripped += 1;
1203 				index_stripped %= ARCMSR_MAX_HBD_POSTQUEUE;
1204 				pmu->postq_index = index_stripped ? index_stripped : (index_stripped | 0x4000);
1205 			}
1206 			bus_dmamap_sync(sc->sc_dmat, ARC_DMA_MAP(sc->sc_requests),
1207 			    sc->cmdQ_ptr_offset, ARC_MAX_CMDQ_PTR_LEN,
1208 			    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
1209 			arc_write(sc, ARC_RD_INB_WRITE_PTR, postq_index);
1210 		break;
1211 	}
1212 	if (xs->flags & SCSI_POLL) {
1213 		if (arc_complete(sc, ccb, xs->timeout) != 0) {
1214 			xs->error = XS_DRIVER_STUFFUP;
1215 			scsi_done(xs);
1216 		}
1217 	}
1218 	splx(s);
1219 }
1220 
1221 int
1222 arc_load_xs(struct arc_ccb *ccb)
1223 {
1224 	struct arc_softc		*sc = ccb->ccb_sc;
1225 	struct scsi_xfer		*xs = ccb->ccb_xs;
1226 	bus_dmamap_t			dmap = ccb->ccb_dmamap;
1227 	struct arc_sge			*sgl = ccb->ccb_cmd->sgl, *sge;
1228 	u_int64_t			addr;
1229 	int				i, error;
1230 	u_int32_t	msg_length;
1231 
1232 	if (xs->datalen == 0)
1233 	{
1234 		ccb->arc_io_cmd_length = sizeof(struct arc_msg_scsicmd);
1235 		ccb->ccb_cmd->cmd.msgPages = 1;
1236 		return (0);
1237 	}
1238 	error = bus_dmamap_load(sc->sc_dmat, dmap,
1239 	    xs->data, xs->datalen, NULL,
1240 	    (xs->flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
1241 	if (error != 0) {
1242 		printf("%s: error %d loading dmamap\n", DEVNAME(sc), error);
1243 		return (1);
1244 	}
1245 
1246 	for (i = 0; i < dmap->dm_nsegs; i++) {
1247 		sge = &sgl[i];
1248 
1249 		sge->sg_length = htole32(ARC_SGE_64BIT | dmap->dm_segs[i].ds_len);
1250 		addr = dmap->dm_segs[i].ds_addr;
1251 		sge->sg_hi_addr = htole32((u_int32_t)(addr >> 32));
1252 		sge->sg_lo_addr = htole32((u_int32_t)addr);
1253 	}
1254 	ccb->arc_io_cmd_length = sizeof(struct arc_msg_scsicmd) +
1255 	    sizeof(struct arc_sge) * dmap->dm_nsegs;
1256 	msg_length = ccb->arc_io_cmd_length;
1257 	ccb->ccb_cmd->cmd.msgPages = (msg_length/256) + ((msg_length % 256) ? 1 : 0);
1258 
1259 	bus_dmamap_sync(sc->sc_dmat, dmap, 0, dmap->dm_mapsize,
1260 	    (xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_PREREAD :
1261 	    BUS_DMASYNC_PREWRITE);
1262 
1263 	return (0);
1264 }
1265 
1266 void
1267 arc_scsi_cmd_done(struct arc_softc *sc, struct arc_ccb *ccb, u_int32_t error)
1268 {
1269 	struct scsi_xfer		*xs = ccb->ccb_xs;
1270 	struct arc_msg_scsicmd		*cmd;
1271 
1272 	if (xs->datalen != 0) {
1273 		bus_dmamap_sync(sc->sc_dmat, ccb->ccb_dmamap, 0,
1274 		    ccb->ccb_dmamap->dm_mapsize, (xs->flags & SCSI_DATA_IN) ?
1275 		    BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
1276 		bus_dmamap_unload(sc->sc_dmat, ccb->ccb_dmamap);
1277 	}
1278 
1279 	if (error) {
1280 		cmd = &ccb->ccb_cmd->cmd;
1281 		DPRINTF("%s: arc_scsi_cmd_done error! target 0x%x, lun 0x%x, "
1282 			"status = 0x%x\n", DEVNAME(sc), cmd->target, cmd->lun,
1283 			cmd->status);
1284 		DPRINTF("%s: scsi cdb: 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x"
1285 			", 0x%x, 0x%x, 0x%x\n", DEVNAME(sc), cmd->cdb[0], cmd->cdb[1],
1286 			cmd->cdb[2], cmd->cdb[3],cmd->cdb[4], cmd->cdb[5],
1287 			cmd->cdb[6], cmd->cdb[7],cmd->cdb[8], cmd->cdb[9]);
1288 
1289 		switch (cmd->status) {
1290 		case ARC_MSG_STATUS_SELTIMEOUT:
1291 		case ARC_MSG_STATUS_ABORTED:
1292 		case ARC_MSG_STATUS_INIT_FAIL:
1293 			xs->status = SCSI_OK;
1294 			xs->error = XS_SELTIMEOUT;
1295 			break;
1296 
1297 		case SCSI_CHECK:
1298 			bzero(&xs->sense, sizeof(xs->sense));
1299 			bcopy(cmd->sense_data, &xs->sense,
1300 			    min(ARC_MSG_SENSELEN, sizeof(xs->sense)));
1301 			xs->sense.error_code = SSD_ERRCODE_VALID | 0x70;
1302 			xs->status = SCSI_CHECK;
1303 			xs->error = XS_SENSE;
1304 			xs->resid = 0;
1305 			break;
1306 
1307 		default:
1308 			/* unknown device status */
1309 			xs->error = XS_BUSY; /* try again later? */
1310 			xs->status = SCSI_BUSY;
1311 			break;
1312 		}
1313 	} else {
1314 		xs->status = SCSI_OK;
1315 		xs->error = XS_NOERROR;
1316 		xs->resid = 0;
1317 	}
1318 
1319 	scsi_done(xs);
1320 }
1321 
1322 int
1323 arc_complete(struct arc_softc *sc, struct arc_ccb *nccb, int timeout)
1324 {
1325 	struct arc_ccb			*ccb = NULL;
1326 	char				*kva = ARC_DMA_KVA(sc->sc_requests);
1327 	struct arc_io_cmd		*cmd;
1328 	u_int32_t			reg, error, write_ptr;
1329 	u_int16_t	doneq_index;
1330 	struct arc_HBD_Msgu *phbdmu;
1331 	int		ret = 0;
1332 
1333 	arc_disable_all_intr(sc);
1334 	do {
1335 		switch(sc->sc_adp_type) {
1336 		case ARC_HBA_TYPE_A:
1337 			reg = arc_read(sc, ARC_RA_REPLY_QUEUE);
1338 			error = (reg & ARC_RA_REPLY_QUEUE_ERR)? 1:0;
1339 			break;
1340 		case ARC_HBA_TYPE_C:
1341 			reg = arc_read(sc, ARC_RC_OUTB_REPLYQ_LOW);
1342 			error = (reg & ARC_RC_REPLY_QUEUE_ERR);
1343 			break;
1344 		case ARC_HBA_TYPE_D:
1345 			phbdmu = sc->pmu;
1346 			write_ptr = phbdmu->done_qbuffer[0].addressLow;
1347 			doneq_index = phbdmu->doneq_index;
1348 			if((write_ptr & 0xff) == (doneq_index & 0xff)) {
1349 Loop0:
1350 				reg = 0xffffffff;
1351 			}
1352 			else {
1353 				doneq_index = arcmsr_get_doneq_index(phbdmu);
1354 				reg = phbdmu->done_qbuffer[(doneq_index & 0xFF)+1].addressLow;
1355 				if (reg == 0)
1356 					goto Loop0;
1357 				arc_write(sc, ARC_RD_OUTB_READ_PTR, doneq_index);
1358 			}
1359 			error = (reg & ARC_RD_REPLY_QUEUE_ERR);
1360 			break;
1361 		}
1362 		if (reg == 0xffffffff) {
1363 			if (timeout-- == 0) {
1364 				return (1);
1365 			}
1366 			delay(1000);
1367 			continue;
1368 		}
1369 
1370 		switch(sc->sc_adp_type) {
1371 		case ARC_HBA_TYPE_A:
1372 			cmd = (struct arc_io_cmd *)(kva +
1373 		    	((reg << ARC_RA_REPLY_QUEUE_ADDR_SHIFT) -
1374 		    	ARC_DMA_DVA(sc->sc_requests)));
1375 		    break;
1376 		case ARC_HBA_TYPE_C:
1377 		case ARC_HBA_TYPE_D:
1378 			cmd = (struct arc_io_cmd *)(kva + ((reg & 0xFFFFFFE0) -
1379 		    	ARC_DMA_DVA(sc->sc_requests)));
1380 		    break;
1381 		}
1382 		ccb = cmd->ccb;
1383 
1384 		bus_dmamap_sync(sc->sc_dmat, ARC_DMA_MAP(sc->sc_requests),
1385 		    ccb->cmd_dma_offset, ARC_MAX_IOCMDLEN,
1386 		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
1387 
1388 		arc_scsi_cmd_done(sc, ccb, error);
1389 
1390 	} while (nccb != ccb);
1391 	arc_enable_all_intr(sc);
1392 
1393 	return (ret);
1394 }
1395 
1396 void
1397 arc_minphys(struct buf *bp, struct scsi_link *sl)
1398 {
1399 	if (bp->b_bcount > MAXPHYS)
1400 		bp->b_bcount = MAXPHYS;
1401 	minphys(bp);
1402 }
1403 
1404 void
1405 arc_enable_all_intr(struct arc_softc *sc)
1406 {
1407 	u_int32_t int_mask;
1408 
1409 	switch(sc->sc_adp_type) {
1410 	case ARC_HBA_TYPE_A:
1411 		int_mask = arc_read(sc, ARC_RA_INTRMASK);
1412 		int_mask &= ~(ARC_RA_INTRMASK_POSTQUEUE |
1413 			ARC_RA_INTRMASK_DOORBELL | ARC_RA_INTRMASK_MSG0);
1414 		arc_write(sc, ARC_RA_INTRMASK, int_mask);
1415 	    break;
1416 	case ARC_HBA_TYPE_C:
1417 		int_mask = arc_read(sc, ARC_RC_INTR_MASK);
1418 		int_mask &= ~(ARC_RC_INTR_MASK_POSTQUEUE |
1419 			ARC_RC_INTR_MASK_DOORBELL | ARC_RC_INTR_MASK_UTILITY_A);
1420 		arc_write(sc, ARC_RC_INTR_MASK, int_mask);
1421 	    break;
1422 	case ARC_HBA_TYPE_D:
1423 		int_mask = arc_read(sc, ARC_RD_INTR_ENABLE);
1424 		int_mask |= ARC_RD_INTR_ENABLE_ALL;
1425 		arc_write(sc, ARC_RD_INTR_ENABLE, int_mask);
1426 	    break;
1427 	}
1428 }
1429 
1430 void
1431 arc_disable_all_intr(struct arc_softc *sc)
1432 {
1433 	u_int32_t int_mask;
1434 
1435 	switch(sc->sc_adp_type) {
1436 	case ARC_HBA_TYPE_A:
1437 		int_mask = arc_read(sc, ARC_RA_INTRMASK);
1438 		int_mask |= ARC_RA_INTR_MASK_ALL;
1439 		arc_write(sc, ARC_RA_INTRMASK, int_mask);
1440 		break;
1441 	case ARC_HBA_TYPE_C:
1442 		int_mask = arc_read(sc, ARC_RC_INTR_MASK);
1443 		int_mask |= ARC_RC_INTR_MASK_ALL;
1444 		arc_write(sc, ARC_RC_INTR_MASK, int_mask);
1445 		break;
1446 	case ARC_HBA_TYPE_D:
1447 		int_mask = arc_read(sc, ARC_RD_INTR_ENABLE);
1448 		int_mask &= ~ARC_RD_INTR_ENABLE_ALL;
1449 		arc_write(sc, ARC_RD_INTR_ENABLE, ARC_RD_INTR_DISABLE_ALL);
1450 		break;
1451 	}
1452 }
1453 
1454 int
1455 arc_map_pci_resources(struct arc_softc *sc, struct pci_attach_args *pa)
1456 {
1457 	pcireg_t			memtype;
1458 	pci_intr_handle_t		ih;
1459 
1460 	sc->sc_pc = pa->pa_pc;
1461 	sc->sc_tag = pa->pa_tag;
1462 	sc->sc_dmat = pa->pa_dmat;
1463 
1464 	switch(sc->sc_adp_type) {
1465 		case ARC_HBA_TYPE_A:
1466 		memtype = pci_mapreg_type(sc->sc_pc, sc->sc_tag, ARC_RA_PCI_BAR);
1467 		if (pci_mapreg_map(pa, ARC_RA_PCI_BAR, memtype, 0, &sc->sc_iot,
1468 	    	&sc->sc_ioh, NULL, &sc->sc_ios, 0) != 0) {
1469 			printf(": unable to map ARC_HBA_TYPE_A system"
1470 				" interface register\n");
1471 			return(1);
1472 		}
1473 		break;
1474 		case ARC_HBA_TYPE_C:
1475 		memtype = pci_mapreg_type(sc->sc_pc, sc->sc_tag, ARC_RC_PCI_BAR);
1476 		if (pci_mapreg_map(pa, ARC_RC_PCI_BAR, memtype, 0, &sc->sc_iot,
1477 	    	&sc->sc_ioh, NULL, &sc->sc_ios, 0) != 0) {
1478 			printf(": unable to map ARC_HBA_TYPE_C system"
1479 				" interface register\n");
1480 			return(1);
1481 		}
1482 		break;
1483 		case ARC_HBA_TYPE_D:
1484 		memtype = pci_mapreg_type(sc->sc_pc, sc->sc_tag, ARC_RD_PCI_BAR);
1485 		if (pci_mapreg_map(pa, ARC_RD_PCI_BAR, memtype, 0, &sc->sc_iot,
1486 	    	&sc->sc_ioh, NULL, &sc->sc_ios, 0) != 0) {
1487 			printf(": unable to map ARC_HBA_TYPE_D system"
1488 				" interface register\n");
1489 			return(1);
1490 		}
1491 		break;
1492 	}
1493 
1494 	arc_disable_all_intr(sc);
1495 
1496 	if (pci_intr_map(pa, &ih) != 0) {
1497 		printf(": unable to map interrupt\n");
1498 		goto unmap;
1499 	}
1500 	sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO,
1501 	    arc_intr, sc, DEVNAME(sc));
1502 	if (sc->sc_ih == NULL) {
1503 		printf(": unable to map interrupt\n");
1504 		goto unmap;
1505 	}
1506 	printf(": %s\n", pci_intr_string(pa->pa_pc, ih));
1507 
1508 	return (0);
1509 
1510 unmap:
1511 	bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
1512 	sc->sc_ios = 0;
1513 	return (1);
1514 }
1515 
1516 void
1517 arc_unmap_pci_resources(struct arc_softc *sc)
1518 {
1519 	pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
1520 	bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
1521 	sc->sc_ios = 0;
1522 }
1523 
1524 int
1525 arc_chipA_firmware(struct arc_softc *sc)
1526 {
1527 	struct arc_msg_firmware_info	fwinfo;
1528 	char				string[81]; /* sizeof(vendor)*2+1 */
1529 	u_int32_t	ob_doorbell;
1530 
1531 	if (arc_wait_eq(sc, ARC_RA_OUTB_ADDR1, ARC_RA_OUTB_ADDR1_FIRMWARE_OK,
1532 	    ARC_RA_OUTB_ADDR1_FIRMWARE_OK) != 0) {
1533 		printf("%s: timeout waiting for firmware ok\n", DEVNAME(sc));
1534 		return (1);
1535 	}
1536 
1537 	if (arc_msg0(sc, ARC_RA_INB_MSG0_GET_CONFIG) != 0) {
1538 		printf("%s: timeout waiting for get config\n", DEVNAME(sc));
1539 		return (1);
1540 	}
1541 
1542 	arc_read_region(sc, ARC_RA_MSGBUF, &fwinfo, sizeof(fwinfo));
1543 
1544 	DNPRINTF(ARC_D_INIT, "%s: signature: 0x%08x\n", DEVNAME(sc),
1545 	    letoh32(fwinfo.signature));
1546 
1547 	if (letoh32(fwinfo.signature) != ARC_FWINFO_SIGNATURE_GET_CONFIG) {
1548 		printf("%s: invalid firmware info from iop\n", DEVNAME(sc));
1549 		return (1);
1550 	}
1551 
1552 	DNPRINTF(ARC_D_INIT, "%s: request_len: %d\n", DEVNAME(sc),
1553 	    letoh32(fwinfo.request_len));
1554 	DNPRINTF(ARC_D_INIT, "%s: queue_len: %d\n", DEVNAME(sc),
1555 	    letoh32(fwinfo.queue_len));
1556 	DNPRINTF(ARC_D_INIT, "%s: sdram_size: %d\n", DEVNAME(sc),
1557 	    letoh32(fwinfo.sdram_size));
1558 	DNPRINTF(ARC_D_INIT, "%s: sata_ports: %d\n", DEVNAME(sc),
1559 	    letoh32(fwinfo.sata_ports), letoh32(fwinfo.sata_ports));
1560 
1561 	scsi_strvis(string, fwinfo.vendor, sizeof(fwinfo.vendor));
1562 	DNPRINTF(ARC_D_INIT, "%s: vendor: \"%s\"\n", DEVNAME(sc), string);
1563 	scsi_strvis(string, fwinfo.model, sizeof(fwinfo.model));
1564 	DNPRINTF(ARC_D_INIT, "%s: model: \"%s\"\n", DEVNAME(sc), string);
1565 
1566 	scsi_strvis(string, fwinfo.fw_version, sizeof(fwinfo.fw_version));
1567 	DNPRINTF(ARC_D_INIT, "%s: firmware: \"%s\"\n", DEVNAME(sc), string);
1568 
1569 	if (letoh32(fwinfo.request_len) != ARC_MAX_IOCMDLEN) {
1570 		printf("%s: unexpected request frame size (%d != %d)\n",
1571 		    DEVNAME(sc), letoh32(fwinfo.request_len), ARC_MAX_IOCMDLEN);
1572 		return (1);
1573 	}
1574 
1575 	sc->sc_req_count = letoh32(fwinfo.queue_len);
1576 
1577 	if (arc_msg0(sc, ARC_RA_INB_MSG0_START_BGRB) != 0) {
1578 		printf("%s: timeout waiting to start bg rebuild\n",
1579 		    DEVNAME(sc));
1580 		return (1);
1581 	}
1582 
1583 	/* clear doorbell buffer */
1584 	ob_doorbell = arc_read(sc, ARC_RA_OUTB_DOORBELL);
1585 	arc_write(sc, ARC_RA_OUTB_DOORBELL, ob_doorbell);
1586 	arc_write(sc, ARC_RA_INB_DOORBELL, ARC_RA_INB_DOORBELL_READ_OK);
1587 
1588 	printf("%s: %d ports, %dMB SDRAM, firmware %s\n",
1589 	    DEVNAME(sc), letoh32(fwinfo.sata_ports),
1590 	    letoh32(fwinfo.sdram_size), string);
1591 
1592 	return (0);
1593 }
1594 
1595 int
1596 arc_chipB_firmware(struct arc_softc *sc)
1597 {
1598 	if (arc_wait_eq(sc, ARC_RB_IOP2DRV_DOORBELL,
1599 	    ARC_RA_OUTB_ADDR1_FIRMWARE_OK,
1600 	    ARC_RA_OUTB_ADDR1_FIRMWARE_OK) != 0) {
1601 		printf("%s: timeout waiting for firmware ok\n", DEVNAME(sc));
1602 		return (1);
1603 	}
1604 
1605 	return (1);
1606 }
1607 
1608 int
1609 arc_chipC_firmware(struct arc_softc *sc)
1610 {
1611 	struct arc_msg_firmware_info	fwinfo;
1612 	char	string[81]; /* sizeof(vendor)*2+1 */
1613 	u_int32_t	ob_doorbell;
1614 
1615 	if (arc_wait_eq(sc, ARC_RC_OUTB_MSGADDR1, ARC_RC_OUTB_MSG_FIRMWARE_OK,
1616 	    ARC_RC_OUTB_MSG_FIRMWARE_OK) != 0) {
1617 		printf("%s: timeout waiting for firmware ok\n", DEVNAME(sc));
1618 		return (1);
1619 	}
1620 
1621 	if (arc_msg0(sc, ARC_RC_INB_MSG0_GET_CONFIG) != 0) {
1622 		printf("%s: timeout waiting for get config\n", DEVNAME(sc));
1623 		return (1);
1624 	}
1625 
1626 	arc_read_region(sc, ARC_RC_MSG_RWBUF, &fwinfo, sizeof(fwinfo));
1627 
1628 	DNPRINTF(ARC_D_INIT, "%s: signature: 0x%08x\n", DEVNAME(sc),
1629 	    letoh32(fwinfo.signature));
1630 
1631 	if (letoh32(fwinfo.signature) != ARC_FWINFO_SIGNATURE_GET_CONFIG) {
1632 		printf("%s: invalid firmware info from iop\n", DEVNAME(sc));
1633 		return (1);
1634 	}
1635 
1636 	DNPRINTF(ARC_D_INIT, "%s: request_len: %d\n", DEVNAME(sc),
1637 	    letoh32(fwinfo.request_len));
1638 	DNPRINTF(ARC_D_INIT, "%s: queue_len: %d\n", DEVNAME(sc),
1639 	    letoh32(fwinfo.queue_len));
1640 	DNPRINTF(ARC_D_INIT, "%s: sdram_size: %d\n", DEVNAME(sc),
1641 	    letoh32(fwinfo.sdram_size));
1642 	DNPRINTF(ARC_D_INIT, "%s: sata_ports: %d\n", DEVNAME(sc),
1643 	    letoh32(fwinfo.sata_ports), letoh32(fwinfo.sata_ports));
1644 
1645 	scsi_strvis(string, fwinfo.vendor, sizeof(fwinfo.vendor));
1646 	DNPRINTF(ARC_D_INIT, "%s: vendor: \"%s\"\n", DEVNAME(sc), string);
1647 	scsi_strvis(string, fwinfo.model, sizeof(fwinfo.model));
1648 	DNPRINTF(ARC_D_INIT, "%s: model: \"%s\"\n", DEVNAME(sc), string);
1649 
1650 	scsi_strvis(string, fwinfo.fw_version, sizeof(fwinfo.fw_version));
1651 	DNPRINTF(ARC_D_INIT, "%s: firmware: \"%s\"\n", DEVNAME(sc), string);
1652 
1653 	if (letoh32(fwinfo.request_len) != ARC_MAX_IOCMDLEN) {
1654 		printf("%s: unexpected request frame size (%d != %d)\n",
1655 		    DEVNAME(sc), letoh32(fwinfo.request_len), ARC_MAX_IOCMDLEN);
1656 		return (1);
1657 	}
1658 
1659 	sc->sc_req_count = letoh32(fwinfo.queue_len);
1660 
1661 	if (arc_msg0(sc, ARC_RC_INB_MSG0_START_BGRB) != 0) {
1662 		printf("%s: timeout waiting to start bg rebuild\n",
1663 		    DEVNAME(sc));
1664 		return (1);
1665 	}
1666 
1667 	/* clear doorbell buffer */
1668 	ob_doorbell = arc_read(sc, ARC_RC_OUTB_DOORBELL);
1669 	arc_write(sc, ARC_RC_OUTB_DOORBELL_CLR, ob_doorbell);
1670 	arc_write(sc, ARC_RC_INB_DOORBELL, ARC_RC_D2I_DATA_READ_OK);
1671 
1672 	printf("%s: %d ports, %dMB SDRAM, firmware %s\n",
1673 	    DEVNAME(sc), letoh32(fwinfo.sata_ports),
1674 	    letoh32(fwinfo.sdram_size), string);
1675 
1676 	return (0);
1677 }
1678 
1679 int
1680 arc_chipD_firmware(struct arc_softc *sc)
1681 {
1682 	struct arc_msg_firmware_info	fwinfo;
1683 	char	string[81]; /* sizeof(vendor)*2+1 */
1684 	u_int32_t	ob_doorbell;
1685 
1686 	if (arc_wait_eq(sc, ARC_RD_OUTB_MSGADDR1, ARC_RD_OUTB_MSG_FIRMWARE_OK,
1687 	    ARC_RD_OUTB_MSG_FIRMWARE_OK) != 0) {
1688 		printf("%s: timeout waiting for firmware ok\n", DEVNAME(sc));
1689 		return (1);
1690 	}
1691 
1692 	if ((arc_read(sc, ARC_RD_OUTB_DOORBELL) & ARC_RD_I2D_MESSAGE_CMD_DONE))
1693 		arc_write(sc, ARC_RD_OUTB_DOORBELL, ARC_RD_I2D_MESSAGE_CMD_DONE_CLEAR);
1694 
1695 	if (arc_msg0(sc, ARC_RD_INB_MSG0_GET_CONFIG) != 0) {
1696 		printf("%s: timeout waiting for get config\n", DEVNAME(sc));
1697 		return (1);
1698 	}
1699 
1700 	arc_read_region(sc, ARC_RD_MSG_RWBUF, &fwinfo, sizeof(fwinfo));
1701 
1702 	DNPRINTF(ARC_D_INIT, "%s: signature: 0x%08x\n", DEVNAME(sc),
1703 	    letoh32(fwinfo.signature));
1704 
1705 	if (letoh32(fwinfo.signature) != ARC_FWINFO_SIGNATURE_GET_CONFIG) {
1706 		printf("%s: invalid firmware info from iop\n", DEVNAME(sc));
1707 		return (1);
1708 	}
1709 
1710 	DNPRINTF(ARC_D_INIT, "%s: request_len: %d\n", DEVNAME(sc),
1711 	    letoh32(fwinfo.request_len));
1712 	DNPRINTF(ARC_D_INIT, "%s: queue_len: %d\n", DEVNAME(sc),
1713 	    letoh32(fwinfo.queue_len));
1714 	DNPRINTF(ARC_D_INIT, "%s: sdram_size: %d\n", DEVNAME(sc),
1715 	    letoh32(fwinfo.sdram_size));
1716 	DNPRINTF(ARC_D_INIT, "%s: sata_ports: %d\n", DEVNAME(sc),
1717 	    letoh32(fwinfo.sata_ports), letoh32(fwinfo.sata_ports));
1718 
1719 	scsi_strvis(string, fwinfo.vendor, sizeof(fwinfo.vendor));
1720 	DNPRINTF(ARC_D_INIT, "%s: vendor: \"%s\"\n", DEVNAME(sc), string);
1721 	scsi_strvis(string, fwinfo.model, sizeof(fwinfo.model));
1722 	DNPRINTF(ARC_D_INIT, "%s: model: \"%s\"\n", DEVNAME(sc), string);
1723 
1724 	scsi_strvis(string, fwinfo.fw_version, sizeof(fwinfo.fw_version));
1725 	DNPRINTF(ARC_D_INIT, "%s: firmware: \"%s\"\n", DEVNAME(sc), string);
1726 
1727 	if (letoh32(fwinfo.request_len) != ARC_MAX_IOCMDLEN) {
1728 		printf("%s: unexpected request frame size (%d != %d)\n",
1729 		    DEVNAME(sc), letoh32(fwinfo.request_len), ARC_MAX_IOCMDLEN);
1730 		return (1);
1731 	}
1732 
1733 	sc->sc_req_count = letoh32(fwinfo.queue_len) - 1;
1734 
1735 	if (arc_msg0(sc, ARC_RD_INB_MSG0_START_BGRB) != 0) {
1736 		printf("%s: timeout waiting to start bg rebuild\n",
1737 		    DEVNAME(sc));
1738 		return (1);
1739 	}
1740 
1741 	/* clear doorbell buffer */
1742 	ob_doorbell = arc_read(sc, ARC_RD_OUTB_DOORBELL);
1743 	arc_write(sc, ARC_RD_OUTB_DOORBELL_CLR, ob_doorbell);
1744 	arc_write(sc, ARC_RD_INB_DOORBELL, ARC_RD_D2I_DATA_READ_OK);
1745 
1746 	printf("%s: %d ports, %dMB SDRAM, firmware %s\n",
1747 	    DEVNAME(sc), letoh32(fwinfo.sata_ports),
1748 	    letoh32(fwinfo.sdram_size), string);
1749 
1750 	return (0);
1751 }
1752 
1753 void
1754 arc_stop_bgrb_proc(struct arc_softc *sc)
1755 {
1756 	switch(sc->sc_adp_type) {
1757 	case ARC_HBA_TYPE_A:
1758 		if (arc_msg0(sc, ARC_RA_INB_MSG0_STOP_BGRB) != 0)
1759 			printf("%s: timeout waiting to stop bg rebuild\n",
1760 				DEVNAME(sc));
1761 		break;
1762 	case ARC_HBA_TYPE_C:
1763 		if (arc_msg0(sc, ARC_RC_INB_MSG0_STOP_BGRB) != 0)
1764 			printf("%s: timeout waiting to stop bg rebuild\n",
1765 				DEVNAME(sc));
1766 		break;
1767 	case ARC_HBA_TYPE_D:
1768 		if (arc_msg0(sc, ARC_RD_INB_MSG0_STOP_BGRB) != 0)
1769 			printf("%s: timeout waiting to stop bg rebuild\n",
1770 				DEVNAME(sc));
1771 		break;
1772 	}
1773 }
1774 
1775 void
1776 arc_flush_cache(struct arc_softc *sc)
1777 {
1778 	switch(sc->sc_adp_type) {
1779 	case ARC_HBA_TYPE_A:
1780 		if (arc_msg0(sc, ARC_RA_INB_MSG0_FLUSH_CACHE) != 0)
1781 			printf("%s: timeout waiting to flush cache\n",
1782 				DEVNAME(sc));
1783 		break;
1784 	case ARC_HBA_TYPE_C:
1785 		if (arc_msg0(sc, ARC_RC_INB_MSG0_FLUSH_CACHE) != 0)
1786 			printf("%s: timeout waiting to flush cache\n",
1787 				DEVNAME(sc));
1788 		break;
1789 	case ARC_HBA_TYPE_D:
1790 		if (arc_msg0(sc, ARC_RD_INB_MSG0_FLUSH_CACHE) != 0)
1791 			printf("%s: timeout waiting to flush cache\n",
1792 				DEVNAME(sc));
1793 		break;
1794 	}
1795 }
1796 
1797 void
1798 arc_iop_set_conf(struct arc_softc *sc)
1799 {
1800 	u_int32_t ccb_phys_hi;
1801 	struct arc_HBD_Msgu *phbdmu;
1802 
1803 	ccb_phys_hi = sc->sc_ccb_phys_hi;
1804 	switch (sc->sc_adp_type) {
1805 	case ARC_HBA_TYPE_A:
1806 		arc_write(sc, ARC_RA_MSGBUF, ARC_FWINFO_SIGNATURE_SET_CONFIG);
1807 		arc_write(sc, ARC_RA_MSGBUF+1, ccb_phys_hi);
1808 		arc_msg0(sc, ARC_RA_INB_MSG0_SET_CONFIG);
1809 		break;
1810 	case ARC_HBA_TYPE_C:
1811 		arc_write(sc, ARC_RC_MSG_RWBUF, ARC_FWINFO_SIGNATURE_SET_CONFIG);
1812 		arc_write(sc, ARC_RC_MSG_RWBUF+1, ccb_phys_hi);
1813 		arc_msg0(sc, ARC_RC_INB_MSG0_SET_CONFIG);
1814 		break;
1815 	case ARC_HBA_TYPE_D:
1816 		phbdmu = sc->pmu;
1817 		phbdmu->postq_index = 0;
1818 		phbdmu->doneq_index = 0x40FF;
1819 		arc_write(sc, ARC_RD_MSG_RWBUF, ARC_FWINFO_SIGNATURE_SET_CONFIG);
1820 		arc_write(sc, ARC_RD_MSG_RWBUF+4, ccb_phys_hi);
1821 		arc_write(sc, ARC_RD_MSG_RWBUF+8, sc->postQ_buffer);
1822 		arc_write(sc, ARC_RD_MSG_RWBUF+12, sc->doneQ_buffer);
1823 		arc_write(sc, ARC_RD_MSG_RWBUF+16, 0x100);
1824 		arc_msg0(sc, ARC_RD_INB_MSG0_SET_CONFIG);
1825 		break;
1826 	}
1827 }
1828 
1829 #if NBIO > 0
1830 int
1831 arc_bioctl(struct device *self, u_long cmd, caddr_t addr)
1832 {
1833 	struct arc_softc		*sc = (struct arc_softc *)self;
1834 	int				error = 0;
1835 
1836 	DPRINTF("%s: arc_bioctl\n", DEVNAME(sc));
1837 	switch (cmd) {
1838 	case BIOCINQ:
1839 		error = arc_bio_inq(sc, (struct bioc_inq *)addr);
1840 		break;
1841 
1842 	case BIOCVOL:
1843 		error = arc_bio_vol(sc, (struct bioc_vol *)addr);
1844 		break;
1845 
1846 	case BIOCDISK:
1847 		error = arc_bio_disk(sc, (struct bioc_disk *)addr);
1848 		break;
1849 
1850 	case BIOCALARM:
1851 		error = arc_bio_alarm(sc, (struct bioc_alarm *)addr);
1852 		break;
1853 
1854 	case BIOCBLINK:
1855 		error = arc_bio_blink(sc, (struct bioc_blink *)addr);
1856 		break;
1857 
1858 	default:
1859 		error = ENOTTY;
1860 		break;
1861 	}
1862 
1863 	return (error);
1864 }
1865 
1866 int
1867 arc_bio_alarm(struct arc_softc *sc, struct bioc_alarm *ba)
1868 {
1869 	u_int8_t			request[2];
1870 	u_int8_t			reply[1];
1871 	size_t				len;
1872 	int				error = 0;
1873 
1874 	DPRINTF("%s: arc_bio_alarm\n", DEVNAME(sc));
1875 	switch (ba->ba_opcode) {
1876 	case BIOC_SAENABLE:
1877 	case BIOC_SADISABLE:
1878 		request[0] = ARC_FW_SET_ALARM;
1879 		request[1] = (ba->ba_opcode == BIOC_SAENABLE) ?
1880 		    ARC_FW_SET_ALARM_ENABLE : ARC_FW_SET_ALARM_DISABLE;
1881 		len = sizeof(request);
1882 
1883 		break;
1884 
1885 	case BIOC_SASILENCE:
1886 		request[0] = ARC_FW_MUTE_ALARM;
1887 		len = 1;
1888 
1889 		break;
1890 
1891 	case BIOC_GASTATUS:
1892 		/* system info is too big/ugly to deal with here */
1893 		return (arc_bio_alarm_state(sc, ba));
1894 
1895 	default:
1896 		return (EOPNOTSUPP);
1897 	}
1898 
1899 	arc_lock(sc);
1900 	error = arc_msgbuf(sc, request, len, reply, sizeof(reply), 0);
1901 	arc_unlock(sc);
1902 
1903 	if (error != 0)
1904 		return (error);
1905 
1906 	switch (reply[0]) {
1907 	case ARC_FW_CMD_OK:
1908 		return (0);
1909 	case ARC_FW_CMD_PASS_REQD:
1910 		return (EPERM);
1911 	default:
1912 		return (EIO);
1913 	}
1914 }
1915 
1916 int
1917 arc_bio_alarm_state(struct arc_softc *sc, struct bioc_alarm *ba)
1918 {
1919 	u_int8_t			request = ARC_FW_SYSINFO;
1920 	struct arc_fw_sysinfo		*sysinfo;
1921 	int				error = 0;
1922 
1923 	sysinfo = malloc(sizeof(struct arc_fw_sysinfo), M_TEMP, M_WAITOK);
1924 
1925 	request = ARC_FW_SYSINFO;
1926 
1927 	arc_lock(sc);
1928 	error = arc_msgbuf(sc, &request, sizeof(request),
1929 	    sysinfo, sizeof(struct arc_fw_sysinfo), 0);
1930 	arc_unlock(sc);
1931 
1932 	if (error != 0)
1933 		goto out;
1934 
1935 	ba->ba_status = sysinfo->alarm;
1936 
1937 out:
1938 	free(sysinfo, M_TEMP);
1939 	return (error);
1940 }
1941 
1942 
1943 int
1944 arc_bio_inq(struct arc_softc *sc, struct bioc_inq *bi)
1945 {
1946 	u_int8_t			request[2];
1947 	struct arc_fw_sysinfo		*sysinfo;
1948 	struct arc_fw_volinfo		*volinfo;
1949 	int				maxvols, nvols = 0, i;
1950 	int				error = 0;
1951 	char	string[20];
1952 
1953 	DPRINTF("%s: arc_bio_inq\n", DEVNAME(sc));
1954 	sysinfo = malloc(sizeof(struct arc_fw_sysinfo), M_TEMP, M_WAITOK);
1955 	volinfo = malloc(sizeof(struct arc_fw_volinfo), M_TEMP, M_WAITOK);
1956 
1957 	arc_lock(sc);
1958 
1959 	request[0] = ARC_FW_SYSINFO;
1960 	error = arc_msgbuf(sc, request, 1, sysinfo,
1961 	    sizeof(struct arc_fw_sysinfo), 0);
1962 	if (error != 0) {
1963 		DPRINTF("%s: arc_bio_inq get sysinfo failed!\n", DEVNAME(sc));
1964 		goto out;
1965 	}
1966 
1967 	maxvols = sysinfo->max_volume_set;
1968 
1969 	request[0] = ARC_FW_VOLINFO;
1970 	for (i = 0; i < maxvols; i++) {
1971 		request[1] = i;
1972 		error = arc_msgbuf(sc, request, sizeof(request), volinfo,
1973 		    sizeof(struct arc_fw_volinfo), 0);
1974 		if (error != 0) {
1975 			DPRINTF("%s: arc_bio_inq get volinfo failed!\n", DEVNAME(sc));
1976 			goto out;
1977 		}
1978 
1979 		/*
1980 		 * I can't find an easy way to see if the volume exists or not
1981 		 * except to say that if it has no capacity then it isn't there.
1982 		 * Ignore passthru volumes, bioc_vol doesn't understand them.
1983 		 */
1984 		if ((volinfo->capacity != 0 || volinfo->capacity2 != 0) &&
1985 		    volinfo->raid_level != ARC_FW_VOL_RAIDLEVEL_PASSTHRU) {
1986 			nvols++;
1987 			scsi_strvis(string, volinfo->set_name, 16);
1988 			DPRINTF("%s: volume set: \"%s\"\n", DEVNAME(sc), string);
1989 		}
1990 	}
1991 
1992 	strlcpy(bi->bi_dev, DEVNAME(sc), sizeof(bi->bi_dev));
1993 	bi->bi_novol = nvols;
1994 	DPRINTF("%s: volume set number = %d\n", DEVNAME(sc), nvols);
1995 out:
1996 	arc_unlock(sc);
1997 	free(volinfo, M_TEMP);
1998 	free(sysinfo, M_TEMP);
1999 	return (error);
2000 }
2001 
2002 int
2003 arc_bio_blink(struct arc_softc *sc, struct bioc_blink *blink)
2004 {
2005 	u_int8_t			 request[6];
2006 	u_int32_t			 mask;
2007 	int				 error = 0;
2008 
2009 	DPRINTF("%s: arc_bio_blink\n", DEVNAME(sc));
2010 	request[0] = ARC_FW_BLINK;
2011 	request[1] = ARC_FW_BLINK_ENABLE;
2012 
2013 	switch (blink->bb_status) {
2014 	case BIOC_SBUNBLINK:
2015 		sc->sc_ledmask &= ~(1 << blink->bb_target);
2016 		break;
2017 	case BIOC_SBBLINK:
2018 		sc->sc_ledmask |= (1 << blink->bb_target);
2019 		break;
2020 	default:
2021 		return (EINVAL);
2022 	}
2023 
2024 	mask = htole32(sc->sc_ledmask);
2025 	bcopy(&mask, &request[2], 4);
2026 
2027 	arc_lock(sc);
2028 	error = arc_msgbuf(sc, request, sizeof(request), NULL, 0, 0);
2029 	arc_unlock(sc);
2030 	if (error)
2031 		return (EIO);
2032 
2033 	return (0);
2034 }
2035 
2036 int
2037 arc_bio_getvol(struct arc_softc *sc, int vol, struct arc_fw_volinfo *volinfo)
2038 {
2039 	u_int8_t			request[2];
2040 	struct arc_fw_sysinfo		*sysinfo;
2041 	int				error = 0;
2042 	int				maxvols, nvols = 0, i;
2043 
2044 	DPRINTF("%s: arc_bio_getvol\n", DEVNAME(sc));
2045 	sysinfo = malloc(sizeof(struct arc_fw_sysinfo), M_TEMP, M_WAITOK);
2046 
2047 	request[0] = ARC_FW_SYSINFO;
2048 	error = arc_msgbuf(sc, request, 1, sysinfo,
2049 	    sizeof(struct arc_fw_sysinfo), 0);
2050 	if (error != 0)
2051 		goto out;
2052 
2053 	maxvols = sysinfo->max_volume_set;
2054 
2055 	request[0] = ARC_FW_VOLINFO;
2056 	for (i = 0; i < maxvols; i++) {
2057 		request[1] = i;
2058 		error = arc_msgbuf(sc, request, sizeof(request), volinfo,
2059 		    sizeof(struct arc_fw_volinfo), 0);
2060 		if (error != 0)
2061 			goto out;
2062 
2063 		if ((volinfo->capacity == 0 && volinfo->capacity2 == 0) ||
2064 		    volinfo->raid_level == ARC_FW_VOL_RAIDLEVEL_PASSTHRU)
2065 			continue;
2066 
2067 		if (nvols == vol)
2068 			break;
2069 
2070 		nvols++;
2071 	}
2072 
2073 	if (nvols != vol ||
2074 	    (volinfo->capacity == 0 && volinfo->capacity2 == 0) ||
2075 	    volinfo->raid_level == ARC_FW_VOL_RAIDLEVEL_PASSTHRU) {
2076 		error = ENODEV;
2077 		goto out;
2078 	}
2079 
2080 out:
2081 	free(sysinfo, M_TEMP);
2082 	return (error);
2083 }
2084 
2085 int
2086 arc_bio_vol(struct arc_softc *sc, struct bioc_vol *bv)
2087 {
2088 	struct arc_fw_volinfo		*volinfo;
2089 	struct scsi_link		*sc_link;
2090 	struct device			*dev;
2091 	u_int64_t			blocks;
2092 	u_int32_t			status;
2093 	int				error = 0;
2094 
2095 	DPRINTF("%s: arc_bio_vol\n", DEVNAME(sc));
2096 	volinfo = malloc(sizeof(struct arc_fw_volinfo), M_TEMP, M_WAITOK);
2097 
2098 	arc_lock(sc);
2099 	error = arc_bio_getvol(sc, bv->bv_volid, volinfo);
2100 	arc_unlock(sc);
2101 
2102 	if (error != 0)
2103 		goto out;
2104 
2105 	bv->bv_percent = -1;
2106 	bv->bv_seconds = 0;
2107 
2108 	status = letoh32(volinfo->volume_status);
2109 	if (status == 0x0) {
2110 		if (letoh32(volinfo->fail_mask) == 0x0)
2111 			bv->bv_status = BIOC_SVONLINE;
2112 		else
2113 			bv->bv_status = BIOC_SVDEGRADED;
2114 	} else if (status & ARC_FW_VOL_STATUS_NEED_REGEN)
2115 		bv->bv_status = BIOC_SVDEGRADED;
2116 	else if (status & ARC_FW_VOL_STATUS_FAILED)
2117 		bv->bv_status = BIOC_SVOFFLINE;
2118 	else if (status & ARC_FW_VOL_STATUS_INITTING) {
2119 		bv->bv_status = BIOC_SVBUILDING;
2120 		bv->bv_percent = letoh32(volinfo->progress) / 10;
2121 	} else if (status & ARC_FW_VOL_STATUS_REBUILDING) {
2122 		bv->bv_status = BIOC_SVREBUILD;
2123 		bv->bv_percent = letoh32(volinfo->progress) / 10;
2124 	}
2125 
2126 	blocks = (u_int64_t)letoh32(volinfo->capacity2) << 32;
2127 	blocks += (u_int64_t)letoh32(volinfo->capacity);
2128 	bv->bv_size = blocks * ARC_BLOCKSIZE; /* XXX */
2129 
2130 	switch (volinfo->raid_level) {
2131 	case ARC_FW_VOL_RAIDLEVEL_0:
2132 		bv->bv_level = 0;
2133 		break;
2134 	case ARC_FW_VOL_RAIDLEVEL_1:
2135 		bv->bv_level = 1;
2136 		break;
2137 	case ARC_FW_VOL_RAIDLEVEL_3:
2138 		bv->bv_level = 3;
2139 		break;
2140 	case ARC_FW_VOL_RAIDLEVEL_5:
2141 		bv->bv_level = 5;
2142 		break;
2143 	case ARC_FW_VOL_RAIDLEVEL_6:
2144 		bv->bv_level = 6;
2145 		break;
2146 	case ARC_FW_VOL_RAIDLEVEL_PASSTHRU:
2147 	default:
2148 		bv->bv_level = -1;
2149 		break;
2150 	}
2151 
2152 	bv->bv_nodisk = volinfo->member_disks;
2153 	sc_link = scsi_get_link(sc->sc_scsibus, volinfo->scsi_attr.target,
2154 	    volinfo->scsi_attr.lun);
2155 	if (sc_link != NULL) {
2156 		dev = sc_link->device_softc;
2157 		strlcpy(bv->bv_dev, dev->dv_xname, sizeof(bv->bv_dev));
2158 	}
2159 
2160 out:
2161 	free(volinfo, M_TEMP);
2162 	return (error);
2163 }
2164 
2165 int
2166 arc_bio_disk(struct arc_softc *sc, struct bioc_disk *bd)
2167 {
2168 	u_int8_t			request[2];
2169 	struct arc_fw_volinfo		*volinfo;
2170 	struct arc_fw_raidinfo		*raidinfo;
2171 	struct arc_fw_diskinfo		*diskinfo;
2172 	int				error = 0;
2173 	u_int64_t			blocks;
2174 	char				model[81];
2175 	char				serial[41];
2176 	char				rev[17];
2177 
2178 	DPRINTF("%s: arc_bio_disk\n", DEVNAME(sc));
2179 	volinfo = malloc(sizeof(struct arc_fw_volinfo), M_TEMP, M_WAITOK);
2180 	raidinfo = malloc(sizeof(struct arc_fw_raidinfo), M_TEMP, M_WAITOK);
2181 	diskinfo = malloc(sizeof(struct arc_fw_diskinfo), M_TEMP, M_WAITOK);
2182 
2183 	arc_lock(sc);
2184 
2185 	error = arc_bio_getvol(sc, bd->bd_volid, volinfo);
2186 	if (error != 0)
2187 		goto out;
2188 
2189 	request[0] = ARC_FW_RAIDINFO;
2190 	request[1] = volinfo->raid_set_number;
2191 	error = arc_msgbuf(sc, request, sizeof(request), raidinfo,
2192 	    sizeof(struct arc_fw_raidinfo), 0);
2193 	if (error != 0)
2194 		goto out;
2195 
2196 	if (bd->bd_diskid > raidinfo->member_devices) {
2197 		error = ENODEV;
2198 		goto out;
2199 	}
2200 
2201 	if (raidinfo->device_array[bd->bd_diskid] == 0xff) {
2202 		/*
2203 		 * the disk doesn't exist anymore. bio is too dumb to be
2204 		 * able to display that, so put it on another bus
2205 		 */
2206 		bd->bd_channel = 1;
2207 		bd->bd_target = 0;
2208 		bd->bd_lun = 0;
2209 		bd->bd_status = BIOC_SDOFFLINE;
2210 		strlcpy(bd->bd_vendor, "disk missing", sizeof(bd->bd_vendor));
2211 		goto out;
2212 	}
2213 
2214 	request[0] = ARC_FW_DISKINFO;
2215 	request[1] = raidinfo->device_array[bd->bd_diskid];
2216 	error = arc_msgbuf(sc, request, sizeof(request), diskinfo,
2217 	    sizeof(struct arc_fw_diskinfo), 1);
2218 	if (error != 0)
2219 		goto out;
2220 
2221 #if 0
2222 	bd->bd_channel = diskinfo->scsi_attr.channel;
2223 	bd->bd_target = diskinfo->scsi_attr.target;
2224 	bd->bd_lun = diskinfo->scsi_attr.lun;
2225 #endif
2226 	/*
2227 	 * the firwmare doesnt seem to fill scsi_attr in, so fake it with
2228 	 * the diskid.
2229 	 */
2230 	bd->bd_channel = 0;
2231 	bd->bd_target = raidinfo->device_array[bd->bd_diskid];
2232 	bd->bd_lun = 0;
2233 
2234 	bd->bd_status = BIOC_SDONLINE;
2235 	blocks = (u_int64_t)letoh32(diskinfo->capacity2) << 32;
2236 	blocks += (u_int64_t)letoh32(diskinfo->capacity);
2237 	bd->bd_size = blocks * ARC_BLOCKSIZE; /* XXX */
2238 
2239 	scsi_strvis(model, diskinfo->model, sizeof(diskinfo->model));
2240 	scsi_strvis(serial, diskinfo->serial, sizeof(diskinfo->serial));
2241 	scsi_strvis(rev, diskinfo->firmware_rev,
2242 	    sizeof(diskinfo->firmware_rev));
2243 
2244 	snprintf(bd->bd_vendor, sizeof(bd->bd_vendor), "%s %s",
2245 	    model, rev);
2246 	strlcpy(bd->bd_serial, serial, sizeof(bd->bd_serial));
2247 
2248 out:
2249 	arc_unlock(sc);
2250 	free(diskinfo, M_TEMP);
2251 	free(raidinfo, M_TEMP);
2252 	free(volinfo, M_TEMP);
2253 	return (error);
2254 }
2255 
2256 u_int8_t
2257 arc_msg_cksum(void *cmd, u_int16_t len)
2258 {
2259 	u_int8_t			*buf = cmd;
2260 	u_int8_t			cksum;
2261 	int				i;
2262 
2263 	cksum = (u_int8_t)(len >> 8) + (u_int8_t)len;
2264 	for (i = 0; i < len; i++)
2265 		cksum += buf[i];
2266 
2267 	return (cksum);
2268 }
2269 
2270 int
2271 arc_msgbuf(struct arc_softc *sc, void *wptr, size_t wbuflen, void *rptr,
2272     size_t rbuflen, int sreadok)
2273 {
2274 	u_int8_t			rwbuf[ARC_RA_IOC_RWBUF_MAXLEN];
2275 	u_int8_t			*wbuf, *rbuf, cksum;
2276 	int				wlen, wdone = 0, rlen, rdone = 0;
2277 	u_int16_t			rlenhdr = 0;
2278 	struct arc_fw_bufhdr		*bufhdr;
2279 	u_int32_t			reg, rwlen, write_ok, read_ok;
2280 	int				error = 0;
2281 #ifdef ARC_DEBUG
2282 	int				i;
2283 #endif
2284 
2285 	DPRINTF("%s: arc_msgbuf wbuflen: %d rbuflen: %d\n",
2286 	    DEVNAME(sc), wbuflen, rbuflen);
2287 
2288 	switch(sc->sc_adp_type) {
2289 	case ARC_HBA_TYPE_A:
2290 		reg = arc_read(sc, ARC_RA_OUTB_DOORBELL);
2291 		break;
2292 	case ARC_HBA_TYPE_C:
2293 		reg = arc_read(sc, ARC_RC_OUTB_DOORBELL);
2294 		break;
2295 	case ARC_HBA_TYPE_D:
2296 		reg = arc_read(sc, ARC_RD_OUTB_DOORBELL);
2297 		break;
2298 	}
2299 /*	if (reg)
2300 		return (EBUSY); */
2301 
2302 	wlen = sizeof(struct arc_fw_bufhdr) + wbuflen + 1; /* 1 for cksum */
2303 	wbuf = malloc(wlen, M_TEMP, M_WAITOK);
2304 
2305 	rlen = sizeof(struct arc_fw_bufhdr) + rbuflen + 1; /* 1 for cksum */
2306 	rbuf = malloc(rlen, M_TEMP, M_WAITOK);
2307 
2308 	DNPRINTF(ARC_D_DB, "%s: arc_msgbuf wlen: %d rlen: %d\n", DEVNAME(sc),
2309 	    wlen, rlen);
2310 
2311 	bufhdr = (struct arc_fw_bufhdr *)wbuf;
2312 	bufhdr->hdr = arc_fw_hdr;
2313 	bufhdr->len = htole16(wbuflen);
2314 	bcopy(wptr, wbuf + sizeof(struct arc_fw_bufhdr), wbuflen);
2315 	wbuf[wlen - 1] = arc_msg_cksum(wptr, wbuflen);
2316 
2317 /*	reg = ARC_RA_OUTB_DOORBELL_READ_OK; */
2318 	read_ok = 1;
2319 	do {
2320 		if ((read_ok) && wdone < wlen) {
2321 			bzero(rwbuf, sizeof(rwbuf));
2322 			rwlen = (wlen - wdone) % sizeof(rwbuf);
2323 			bcopy(&wbuf[wdone], rwbuf, rwlen);
2324 
2325 #ifdef ARC_DEBUG
2326 			if (arcdebug & ARC_D_DB) {
2327 				printf("%s: write %d:", DEVNAME(sc), rwlen);
2328 				for (i = 0; i < rwlen; i++)
2329 					printf(" 0x%02x", rwbuf[i]);
2330 				printf("\n");
2331 			}
2332 #endif
2333 
2334 			switch(sc->sc_adp_type) {
2335 			case ARC_HBA_TYPE_A:
2336 				/* copy the chunk to the hw */
2337 				arc_write(sc, ARC_RA_IOC_WBUF_LEN, rwlen);
2338 				arc_write_region(sc, ARC_RA_IOC_WBUF, rwbuf,
2339 			    	sizeof(rwbuf));
2340 
2341 				/* say we have a buffer for the hw */
2342 				arc_write(sc, ARC_RA_INB_DOORBELL,
2343 			    	ARC_RA_INB_DOORBELL_WRITE_OK);
2344 				break;
2345 			case ARC_HBA_TYPE_C:
2346 				/* copy the chunk to the hw */
2347 				arc_write(sc, ARC_RC_MSG_WBUF_LEN, rwlen);
2348 				arc_write_region(sc, ARC_RC_MSG_WBUF, rwbuf,
2349 			    	sizeof(rwbuf));
2350 
2351 				/* say we have a buffer for the hw */
2352 				arc_write(sc, ARC_RC_INB_DOORBELL,
2353 			    	ARC_RC_D2I_DATA_WRITE_OK);
2354 				break;
2355 			case ARC_HBA_TYPE_D:
2356 				/* copy the chunk to the hw */
2357 				arc_write(sc, ARC_RD_MSG_WBUF_LEN, rwlen);
2358 				arc_write_region(sc, ARC_RD_MSG_WBUF, rwbuf,
2359 			    	sizeof(rwbuf));
2360 
2361 				/* say we have a buffer for the hw */
2362 				arc_write(sc, ARC_RD_INB_DOORBELL,
2363 			    	ARC_RD_D2I_DATA_WRITE_OK);
2364 				break;
2365 			}
2366 			wdone += rwlen;
2367 		}
2368 
2369 		if (rptr == NULL)
2370 			goto out;
2371 
2372 		switch(sc->sc_adp_type) {
2373 		case ARC_HBA_TYPE_A:
2374 			while ((reg = arc_read(sc, ARC_RA_OUTB_DOORBELL)) == 0)
2375 				arc_wait(sc);
2376 			arc_write(sc, ARC_RA_OUTB_DOORBELL, reg);
2377 			write_ok = reg & ARC_RA_OUTB_DOORBELL_WRITE_OK;
2378 			read_ok = reg & ARC_RA_OUTB_DOORBELL_READ_OK;
2379 			break;
2380 		case ARC_HBA_TYPE_C:
2381 			while ((reg = arc_read(sc, ARC_RC_OUTB_DOORBELL)) == 0)
2382 				arc_wait(sc);
2383 			arc_write(sc, ARC_RC_OUTB_DOORBELL_CLR, reg);
2384 			write_ok = reg & ARC_RC_I2D_DATA_WRITE_OK;
2385 			read_ok = reg & ARC_RC_I2D_DATA_READ_OK;
2386 			break;
2387 		case ARC_HBA_TYPE_D:
2388 			while ((reg = arc_read(sc, ARC_RD_OUTB_DOORBELL)) == 0)
2389 				arc_wait(sc);
2390 			arc_write(sc, ARC_RD_OUTB_DOORBELL_CLR, reg);
2391 			write_ok = reg & ARC_RD_I2D_DATA_WRITE_OK;
2392 			read_ok = reg & ARC_RD_I2D_DATA_READ_OK;
2393 			break;
2394 		}
2395 		DNPRINTF(ARC_D_DB, "%s: reg: 0x%08x\n", DEVNAME(sc), reg);
2396 
2397 		if ((write_ok) && rdone < rlen) {
2398 			switch(sc->sc_adp_type) {
2399 			case ARC_HBA_TYPE_A:
2400 				rwlen = arc_read(sc, ARC_RA_IOC_RBUF_LEN);
2401 				break;
2402 			case ARC_HBA_TYPE_C:
2403 				rwlen = arc_read(sc, ARC_RC_MSG_RBUF_LEN);
2404 				break;
2405 			case ARC_HBA_TYPE_D:
2406 				rwlen = arc_read(sc, ARC_RD_MSG_RBUF_LEN);
2407 				break;
2408 			}
2409 			if (rwlen > sizeof(rwbuf)) {
2410 				DNPRINTF(ARC_D_DB, "%s:  rwlen too big\n",
2411 				    DEVNAME(sc));
2412 				error = EIO;
2413 				goto out;
2414 			}
2415 
2416 			switch(sc->sc_adp_type) {
2417 			case ARC_HBA_TYPE_A:
2418 				arc_read_region(sc, ARC_RA_IOC_RBUF, rwbuf,
2419 			    	sizeof(rwbuf));
2420 				arc_write(sc, ARC_RA_INB_DOORBELL,
2421 			    	ARC_RA_INB_DOORBELL_READ_OK);
2422 				break;
2423 			case ARC_HBA_TYPE_C:
2424 				arc_read_region(sc, ARC_RC_MSG_RBUF, rwbuf,
2425 			    	sizeof(rwbuf));
2426 				arc_write(sc, ARC_RC_INB_DOORBELL,
2427 			    	ARC_RC_I2D_DATA_READ_OK);
2428 				break;
2429 			case ARC_HBA_TYPE_D:
2430 				arc_read_region(sc, ARC_RD_MSG_RBUF, rwbuf,
2431 			    	sizeof(rwbuf));
2432 				arc_write(sc, ARC_RD_INB_DOORBELL,
2433 			    	ARC_RD_I2D_DATA_READ_OK);
2434 				break;
2435 			}
2436 			if ((rlen > 3) && (rdone == 3)) {
2437 				rlen = *(u_int16_t *)rwbuf;
2438 				rlen = sizeof(struct arc_fw_bufhdr) + rlen + 1;
2439 			}
2440 #ifdef ARC_DEBUG
2441 			printf("%s:  len: %d+%d=%d/%d\n", DEVNAME(sc),
2442 			    rwlen, rdone, rwlen + rdone, rlen);
2443 			if (arcdebug & ARC_D_DB) {
2444 				printf("%s: read:", DEVNAME(sc));
2445 				for (i = 0; i < rwlen; i++)
2446 					printf(" 0x%02x", rwbuf[i]);
2447 				printf("\n");
2448 			}
2449 #endif
2450 
2451 			if ((rdone + rwlen) > rlen) {
2452 				DNPRINTF(ARC_D_DB, "%s:  rwbuf too big\n",
2453 				    DEVNAME(sc));
2454 				error = EIO;
2455 				goto out;
2456 			}
2457 
2458 			bcopy(rwbuf, &rbuf[rdone], rwlen);
2459 			rdone += rwlen;
2460 
2461 			/*
2462 			 * Allow for short reads, by reading the length
2463 			 * value from the response header and shrinking our
2464 			 * idea of size, if required.
2465 			 * This deals with the growth of diskinfo struct from
2466 			 * 128 to 132 bytes.
2467 			 */
2468 			if (sreadok && rdone >= sizeof(struct arc_fw_bufhdr) &&
2469 			    rlenhdr == 0) {
2470 				bufhdr = (struct arc_fw_bufhdr *)rbuf;
2471 				rlenhdr = letoh16(bufhdr->len);
2472 				if (rlenhdr < rbuflen) {
2473 					rbuflen = rlenhdr;
2474 					rlen = sizeof(struct arc_fw_bufhdr) +
2475 					    rbuflen + 1; /* 1 for cksum */
2476 				}
2477 			}
2478 		}
2479 	} while (rdone != rlen);
2480 
2481 	bufhdr = (struct arc_fw_bufhdr *)rbuf;
2482 	if (memcmp(&bufhdr->hdr, &arc_fw_hdr, sizeof(bufhdr->hdr)) != 0) {
2483 		DNPRINTF(ARC_D_DB, "%s:  rbuf hdr is wrong\n", DEVNAME(sc));
2484 		error = EIO;
2485 		goto out;
2486 	}
2487 
2488 	if (bufhdr->len != htole16(rbuflen)) {
2489 		DNPRINTF(ARC_D_DB, "%s:  get_len: 0x%x, req_len: 0x%x\n",
2490 			DEVNAME(sc), bufhdr->len, rbuflen);
2491 	}
2492 
2493 	bcopy(rbuf + sizeof(struct arc_fw_bufhdr), rptr, bufhdr->len);
2494 	cksum = arc_msg_cksum(rptr, bufhdr->len);
2495 	if (rbuf[rlen - 1] != cksum) {
2496 		DNPRINTF(ARC_D_DB, "%s:  invalid cksum, got :0x%x, calculated:"
2497 			" 0x%x\n", DEVNAME(sc), rbuf[rlen-1], cksum);
2498 		error = EIO;
2499 		goto out;
2500 	}
2501 
2502 out:
2503 	free(wbuf, M_TEMP);
2504 	free(rbuf, M_TEMP);
2505 
2506 	return (error);
2507 }
2508 
2509 void
2510 arc_lock(struct arc_softc *sc)
2511 {
2512 	int				s;
2513 	u_int32_t int_mask;
2514 
2515 	rw_enter_write(&sc->sc_lock);
2516 	s = splbio();
2517 	switch(sc->sc_adp_type) {
2518 	case ARC_HBA_TYPE_A:
2519 		int_mask = arc_read(sc, ARC_RA_INTRMASK) | ARC_RA_INTRMASK_DOORBELL;
2520 		arc_write(sc, ARC_RA_INTRMASK, int_mask);
2521 		break;
2522 	case ARC_HBA_TYPE_C:
2523 		int_mask = arc_read(sc, ARC_RC_INTR_MASK) | ARC_RC_INTR_MASK_DOORBELL;
2524 		arc_write(sc, ARC_RC_INTR_MASK, int_mask);
2525 		break;
2526 	case ARC_HBA_TYPE_D:
2527 		int_mask = arc_read(sc, ARC_RD_INTR_ENABLE) & ~ARC_RD_INTR_ENABLE_DOORBELL;
2528 		arc_write(sc, ARC_RD_INTR_ENABLE, int_mask);
2529 		break;
2530 	}
2531 	sc->sc_talking = 1;
2532 	splx(s);
2533 }
2534 
2535 void
2536 arc_unlock(struct arc_softc *sc)
2537 {
2538 	int				s;
2539 	u_int32_t int_mask;
2540 
2541 	s = splbio();
2542 	sc->sc_talking = 0;
2543 	switch(sc->sc_adp_type) {
2544 	case ARC_HBA_TYPE_A:
2545 		int_mask = arc_read(sc, ARC_RA_INTRMASK) & ~ARC_RA_INTRMASK_DOORBELL;
2546 		arc_write(sc, ARC_RA_INTRMASK, int_mask);
2547 		break;
2548 	case ARC_HBA_TYPE_C:
2549 		int_mask = arc_read(sc, ARC_RC_INTR_MASK) & ~ARC_RC_INTR_MASK_DOORBELL;
2550 		arc_write(sc, ARC_RC_INTR_MASK, int_mask);
2551 		break;
2552 	case ARC_HBA_TYPE_D:
2553 		int_mask = arc_read(sc, ARC_RD_INTR_ENABLE) | ARC_RD_INTR_ENABLE_DOORBELL;
2554 		arc_write(sc, ARC_RD_INTR_ENABLE, int_mask);
2555 		break;
2556 	}
2557 	splx(s);
2558 	rw_exit_write(&sc->sc_lock);
2559 }
2560 
2561 void
2562 arc_wait(struct arc_softc *sc)
2563 {
2564 	int				s;
2565 	u_int32_t int_mask;
2566 
2567 	s = splbio();
2568 	switch(sc->sc_adp_type) {
2569 	case ARC_HBA_TYPE_A:
2570 		int_mask = arc_read(sc, ARC_RA_INTRMASK) & ~ARC_RA_INTRMASK_DOORBELL;
2571 		arc_write(sc, ARC_RA_INTRMASK, int_mask);
2572 		if (tsleep(sc, PWAIT, "arcdb", hz) == EWOULDBLOCK) {
2573 			int_mask = arc_read(sc, ARC_RA_INTRMASK) | ARC_RA_INTRMASK_DOORBELL;
2574 			arc_write(sc, ARC_RA_INTRMASK, int_mask);
2575 		}
2576 		break;
2577 	case ARC_HBA_TYPE_C:
2578 		int_mask = arc_read(sc, ARC_RC_INTR_MASK) & ~ARC_RC_INTR_MASK_DOORBELL;
2579 		arc_write(sc, ARC_RC_INTR_MASK, int_mask);
2580 		if (tsleep(sc, PWAIT, "arcdb", hz) == EWOULDBLOCK) {
2581 			int_mask = arc_read(sc, ARC_RC_INTR_MASK) | ARC_RC_INTR_MASK_DOORBELL;
2582 			arc_write(sc, ARC_RC_INTR_MASK, int_mask);
2583 		}
2584 		break;
2585 	case ARC_HBA_TYPE_D:
2586 		int_mask = arc_read(sc, ARC_RD_INTR_ENABLE) | ARC_RD_INTR_ENABLE_DOORBELL;
2587 		arc_write(sc, ARC_RD_INTR_ENABLE, int_mask);
2588 		if (tsleep(sc, PWAIT, "arcdb", hz) == EWOULDBLOCK) {
2589 			int_mask = arc_read(sc, ARC_RD_INTR_ENABLE) & ~ARC_RD_INTR_ENABLE_DOORBELL;
2590 			arc_write(sc, ARC_RD_INTR_ENABLE, int_mask);
2591 		}
2592 		break;
2593 	}
2594 	splx(s);
2595 }
2596 
2597 #ifndef SMALL_KERNEL
2598 void
2599 arc_create_sensors(void *xsc, void *arg)
2600 {
2601 	struct arc_softc	*sc = xsc;
2602 	struct bioc_inq		bi;
2603 	struct bioc_vol		bv;
2604 	int			i;
2605 
2606 	DPRINTF("%s: arc_create_sensors\n", DEVNAME(sc));
2607 	/*
2608 	 * XXX * this is bollocks. the firmware has garbage coming out of it
2609 	 * so we have to wait a bit for it to finish spewing.
2610 	 */
2611 	tsleep(sc, PWAIT, "arcspew", 2 * hz);
2612 
2613 	bzero(&bi, sizeof(bi));
2614 	if (arc_bio_inq(sc, &bi) != 0) {
2615 		printf("%s: unable to query firmware for sensor info\n",
2616 		    DEVNAME(sc));
2617 		return;
2618 	}
2619 	sc->sc_nsensors = bi.bi_novol;
2620 
2621 	sc->sc_sensors = malloc(sizeof(struct ksensor) * sc->sc_nsensors,
2622 	    M_DEVBUF, M_WAITOK | M_ZERO);
2623 
2624 	strlcpy(sc->sc_sensordev.xname, DEVNAME(sc),
2625 	    sizeof(sc->sc_sensordev.xname));
2626 
2627 	for (i = 0; i < sc->sc_nsensors; i++) {
2628 		bzero(&bv, sizeof(bv));
2629 		bv.bv_volid = i;
2630 		if (arc_bio_vol(sc, &bv) != 0) {
2631 			DPRINTF("%s: arc_bio_vol failed!\n", DEVNAME(sc));
2632 			goto bad;
2633 		}
2634 
2635 		sc->sc_sensors[i].type = SENSOR_DRIVE;
2636 		sc->sc_sensors[i].status = SENSOR_S_UNKNOWN;
2637 
2638 		strlcpy(sc->sc_sensors[i].desc, bv.bv_dev,
2639 		    sizeof(sc->sc_sensors[i].desc));
2640 
2641 		sensor_attach(&sc->sc_sensordev, &sc->sc_sensors[i]);
2642 	}
2643 
2644 	if (sensor_task_register(sc, arc_refresh_sensors, 120) == NULL) {
2645 		DPRINTF("%s: sensor_task_register failed!\n", DEVNAME(sc));
2646 		goto bad;
2647 	}
2648 
2649 	sensordev_install(&sc->sc_sensordev);
2650 
2651 	return;
2652 
2653 bad:
2654 	free(sc->sc_sensors, M_DEVBUF);
2655 }
2656 
2657 void
2658 arc_refresh_sensors(void *arg)
2659 {
2660 	struct arc_softc	*sc = arg;
2661 	struct bioc_vol		bv;
2662 	int			i;
2663 
2664 	for (i = 0; i < sc->sc_nsensors; i++) {
2665 		bzero(&bv, sizeof(bv));
2666 		bv.bv_volid = i;
2667 		if (arc_bio_vol(sc, &bv)) {
2668 			sc->sc_sensors[i].flags = SENSOR_FINVALID;
2669 			return;
2670 		}
2671 
2672 		switch(bv.bv_status) {
2673 		case BIOC_SVOFFLINE:
2674 			sc->sc_sensors[i].value = SENSOR_DRIVE_FAIL;
2675 			sc->sc_sensors[i].status = SENSOR_S_CRIT;
2676 			break;
2677 
2678 		case BIOC_SVDEGRADED:
2679 			sc->sc_sensors[i].value = SENSOR_DRIVE_PFAIL;
2680 			sc->sc_sensors[i].status = SENSOR_S_WARN;
2681 			break;
2682 
2683 		case BIOC_SVSCRUB:
2684 		case BIOC_SVONLINE:
2685 			sc->sc_sensors[i].value = SENSOR_DRIVE_ONLINE;
2686 			sc->sc_sensors[i].status = SENSOR_S_OK;
2687 			break;
2688 
2689 		case BIOC_SVINVALID:
2690 			/* FALLTRHOUGH */
2691 		default:
2692 			sc->sc_sensors[i].value = 0; /* unknown */
2693 			sc->sc_sensors[i].status = SENSOR_S_UNKNOWN;
2694 		}
2695 
2696 	}
2697 }
2698 #endif /* SMALL_KERNEL */
2699 #endif /* NBIO > 0 */
2700 
2701 u_int32_t
2702 arc_read(struct arc_softc *sc, bus_size_t r)
2703 {
2704 	u_int32_t			v;
2705 
2706 	bus_space_barrier(sc->sc_iot, sc->sc_ioh, r, 4,
2707 	    BUS_SPACE_BARRIER_READ);
2708 	v = bus_space_read_4(sc->sc_iot, sc->sc_ioh, r);
2709 
2710 	DNPRINTF(ARC_D_RW, "%s: arc_read 0x%x 0x%08x\n", DEVNAME(sc), r, v);
2711 
2712 	return (v);
2713 }
2714 
2715 void
2716 arc_read_region(struct arc_softc *sc, bus_size_t r, void *buf, size_t len)
2717 {
2718 	bus_space_barrier(sc->sc_iot, sc->sc_ioh, r, len,
2719 	    BUS_SPACE_BARRIER_READ);
2720 	bus_space_read_raw_region_4(sc->sc_iot, sc->sc_ioh, r, buf, len);
2721 }
2722 
2723 void
2724 arc_write(struct arc_softc *sc, bus_size_t r, u_int32_t v)
2725 {
2726 	DNPRINTF(ARC_D_RW, "%s: arc_write 0x%x 0x%08x\n", DEVNAME(sc), r, v);
2727 
2728 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, r, v);
2729 	bus_space_barrier(sc->sc_iot, sc->sc_ioh, r, 4,
2730 	    BUS_SPACE_BARRIER_WRITE);
2731 }
2732 
2733 void
2734 arc_write_region(struct arc_softc *sc, bus_size_t r, void *buf, size_t len)
2735 {
2736 	bus_space_write_raw_region_4(sc->sc_iot, sc->sc_ioh, r, buf, len);
2737 	bus_space_barrier(sc->sc_iot, sc->sc_ioh, r, len,
2738 	    BUS_SPACE_BARRIER_WRITE);
2739 }
2740 
2741 int
2742 arc_wait_eq(struct arc_softc *sc, bus_size_t r, u_int32_t mask,
2743     u_int32_t target)
2744 {
2745 	int				i;
2746 
2747 	DNPRINTF(ARC_D_RW, "%s: arc_wait_eq 0x%x 0x%08x 0x%08x\n",
2748 	    DEVNAME(sc), r, mask, target);
2749 
2750 	for (i = 0; i < 10000; i++) {
2751 		if ((arc_read(sc, r) & mask) == target)
2752 			return (0);
2753 		delay(1000);
2754 	}
2755 
2756 	return (1);
2757 }
2758 
2759 int
2760 arc_wait_ne(struct arc_softc *sc, bus_size_t r, u_int32_t mask,
2761     u_int32_t target)
2762 {
2763 	int				i;
2764 
2765 	DNPRINTF(ARC_D_RW, "%s: arc_wait_ne 0x%x 0x%08x 0x%08x\n",
2766 	    DEVNAME(sc), r, mask, target);
2767 
2768 	for (i = 0; i < 10000; i++) {
2769 		if ((arc_read(sc, r) & mask) != target)
2770 			return (0);
2771 		delay(1000);
2772 	}
2773 
2774 	return (1);
2775 }
2776 
2777 int
2778 arc_msg0(struct arc_softc *sc, u_int32_t m)
2779 {
2780 	switch(sc->sc_adp_type) {
2781 		case ARC_HBA_TYPE_A:
2782 		/* post message */
2783 		arc_write(sc, ARC_RA_INB_MSG0, m);
2784 		/* wait for the fw to do it */
2785 		if (arc_wait_eq(sc, ARC_RA_INTRSTAT, ARC_RA_INTRSTAT_MSG0,
2786 	    	ARC_RA_INTRSTAT_MSG0) != 0)
2787 			return (1);
2788 
2789 		/* ack it */
2790 		arc_write(sc, ARC_RA_INTRSTAT, ARC_RA_INTRSTAT_MSG0);
2791 		break;
2792 
2793 		case ARC_HBA_TYPE_C:
2794 		/* post message */
2795 		arc_write(sc, ARC_RC_INB_MSGADDR0, m);
2796 		arc_write(sc, ARC_RC_INB_DOORBELL, ARC_RC_D2I_MSG_CMD_DONE);
2797 		/* wait for the fw to do it */
2798 		if (arc_wait_eq(sc, ARC_RC_OUTB_DOORBELL, ARC_RC_I2D_MSG_CMD_DONE,
2799 	    	ARC_RC_I2D_MSG_CMD_DONE) != 0)
2800 			return (1);
2801 
2802 		/* ack it */
2803 		arc_write(sc, ARC_RC_OUTB_DOORBELL_CLR, ARC_RC_I2D_MSG_CMD_DONE_CLR);
2804 		break;
2805 
2806 		case ARC_HBA_TYPE_D:
2807 		/* post message */
2808 		arc_write(sc, ARC_RD_INB_MSGADDR0, m);
2809 		/* wait for the fw to do it */
2810 		if (arc_wait_eq(sc, ARC_RD_OUTB_DOORBELL, ARC_RD_I2D_MSG_CMD_DONE,
2811 	    	ARC_RD_I2D_MSG_CMD_DONE) != 0)
2812 			return (1);
2813 
2814 		/* ack it */
2815 		arc_write(sc, ARC_RD_OUTB_DOORBELL_CLR, ARC_RD_I2D_MSG_CMD_DONE_CLR);
2816 		break;
2817 	}
2818 	return (0);
2819 }
2820 
2821 struct arc_dmamem *
2822 arc_dmamem_alloc(struct arc_softc *sc, size_t size)
2823 {
2824 	struct arc_dmamem		*adm;
2825 	int				nsegs;
2826 
2827 	adm = malloc(sizeof(*adm), M_DEVBUF, M_NOWAIT | M_ZERO);
2828 	if (adm == NULL)
2829 		return (NULL);
2830 
2831 	adm->adm_size = size;
2832 
2833 	if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
2834 	    BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &adm->adm_map) != 0)
2835 		goto admfree;
2836 
2837 	if (bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, &adm->adm_seg,
2838 	    1, &nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO) != 0)
2839 		goto destroy;
2840 
2841 	if (bus_dmamem_map(sc->sc_dmat, &adm->adm_seg, nsegs, size,
2842 	    &adm->adm_kva, BUS_DMA_NOWAIT) != 0)
2843 		goto free;
2844 
2845 	if (bus_dmamap_load(sc->sc_dmat, adm->adm_map, adm->adm_kva, size,
2846 	    NULL, BUS_DMA_NOWAIT) != 0)
2847 		goto unmap;
2848 
2849 	return (adm);
2850 
2851 unmap:
2852 	bus_dmamem_unmap(sc->sc_dmat, adm->adm_kva, size);
2853 free:
2854 	bus_dmamem_free(sc->sc_dmat, &adm->adm_seg, 1);
2855 destroy:
2856 	bus_dmamap_destroy(sc->sc_dmat, adm->adm_map);
2857 admfree:
2858 	free(adm, M_DEVBUF);
2859 
2860 	return (NULL);
2861 }
2862 
2863 void
2864 arc_dmamem_free(struct arc_softc *sc, struct arc_dmamem *adm)
2865 {
2866 	bus_dmamap_unload(sc->sc_dmat, adm->adm_map);
2867 	bus_dmamem_unmap(sc->sc_dmat, adm->adm_kva, adm->adm_size);
2868 	bus_dmamem_free(sc->sc_dmat, &adm->adm_seg, 1);
2869 	bus_dmamap_destroy(sc->sc_dmat, adm->adm_map);
2870 	free(adm, M_DEVBUF);
2871 }
2872 
2873 int
2874 arc_alloc_ccbs(struct arc_softc *sc)
2875 {
2876 	struct arc_ccb		*ccb;
2877 	u_int8_t			*cmd;
2878 	u_int32_t			i, size, len;
2879 
2880 	SLIST_INIT(&sc->sc_ccb_free);
2881 	mtx_init(&sc->sc_ccb_mtx, IPL_BIO);
2882 
2883 	size = sizeof(struct arc_ccb) * ARCMSR_MAX_CCB_COUNT;
2884 	sc->sc_ccbs = malloc(size, M_DEVBUF, M_WAITOK | M_ZERO);
2885 
2886 	len = ARC_IO_CMD_LEN;
2887 	size = ARCMSR_MAX_CCB_COUNT * len;
2888 	if(sc->sc_adp_type == ARC_HBA_TYPE_D)
2889 		size += sizeof(struct arc_HBD_Msgu);
2890 	sc->sc_requests = arc_dmamem_alloc(sc, size);
2891 	if (sc->sc_requests == NULL) {
2892 		printf("%s: unable to allocate ccb dmamem\n", DEVNAME(sc));
2893 		goto free_ccbs;
2894 	}
2895 	cmd = ARC_DMA_KVA(sc->sc_requests);
2896 
2897 	for (i = 0; i < ARCMSR_MAX_CCB_COUNT; i++) {
2898 		ccb = &sc->sc_ccbs[i];
2899 
2900 		if (bus_dmamap_create(sc->sc_dmat, MAXPHYS, ARC_SGL_MAXLEN,
2901 		    MAXPHYS, 0, 0, &ccb->ccb_dmamap) != 0) {
2902 			printf("%s: unable to create dmamap for ccb %d\n",
2903 			    DEVNAME(sc), i);
2904 			goto free_maps;
2905 		}
2906 
2907 		ccb->ccb_sc = sc;
2908 		ccb->cmd_dma_offset = len * i;
2909 
2910 		ccb->ccb_cmd = (struct arc_io_cmd *)&cmd[ccb->cmd_dma_offset];
2911 		ccb->ccb_cmd_post = (ARC_DMA_DVA(sc->sc_requests) +
2912 		    ccb->cmd_dma_offset);
2913 		if ((sc->sc_adp_type != ARC_HBA_TYPE_C) &&
2914 		    (sc->sc_adp_type != ARC_HBA_TYPE_D))
2915 			ccb->ccb_cmd_post = ccb->ccb_cmd_post >>
2916 				ARC_RA_POST_QUEUE_ADDR_SHIFT;
2917 		arc_put_ccb(sc, ccb);
2918 	}
2919 	sc->sc_ccb_phys_hi = (u_int64_t)ARC_DMA_DVA(sc->sc_requests) >> 32;
2920 	if(sc->sc_adp_type == ARC_HBA_TYPE_D) {
2921 		sc->postQ_buffer = ARC_DMA_DVA(sc->sc_requests) +
2922 		    (ARCMSR_MAX_CCB_COUNT * len);
2923 		sc->doneQ_buffer = sc->postQ_buffer + (sizeof(struct InBound_SRB) *
2924 		    ARCMSR_MAX_HBD_POSTQUEUE);
2925 		sc->pmu = (struct arc_HBD_Msgu *)&cmd[ARCMSR_MAX_CCB_COUNT * len];
2926 		sc->cmdQ_ptr_offset = ARCMSR_MAX_CCB_COUNT * len;
2927 	}
2928 	scsi_iopool_init(&sc->sc_iopool, sc,
2929 	    (void *(*)(void *))arc_get_ccb,
2930 	    (void (*)(void *, void *))arc_put_ccb);
2931 
2932 	return (0);
2933 
2934 free_maps:
2935 	while ((ccb = arc_get_ccb(sc)) != NULL)
2936 	    bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap);
2937 	arc_dmamem_free(sc, sc->sc_requests);
2938 
2939 free_ccbs:
2940 	free(sc->sc_ccbs, M_DEVBUF);
2941 
2942 	return (1);
2943 }
2944 
2945 void
2946 arc_free_ccb_src(struct arc_softc *sc)
2947 {
2948 	struct arc_ccb			*ccb;
2949 
2950 	while ((ccb = arc_get_ccb(sc)) != NULL)
2951 	    bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap);
2952 	arc_dmamem_free(sc, sc->sc_requests);
2953 	free(sc->sc_ccbs, M_DEVBUF);
2954 }
2955 
2956 struct arc_ccb *
2957 arc_get_ccb(struct arc_softc *sc)
2958 {
2959 	struct arc_ccb			*ccb;
2960 
2961 	mtx_enter(&sc->sc_ccb_mtx);
2962 	ccb = SLIST_FIRST(&sc->sc_ccb_free);
2963 	if (ccb != NULL)
2964 		SLIST_REMOVE_HEAD(&sc->sc_ccb_free, ccb_link);
2965 	mtx_leave(&sc->sc_ccb_mtx);
2966 
2967 	return (ccb);
2968 }
2969 
2970 void
2971 arc_put_ccb(struct arc_softc *sc, struct arc_ccb *ccb)
2972 {
2973 	ccb->ccb_xs = NULL;
2974 	bzero(ccb->ccb_cmd, ARC_IO_CMD_LEN);
2975 	mtx_enter(&sc->sc_ccb_mtx);
2976 	SLIST_INSERT_HEAD(&sc->sc_ccb_free, ccb, ccb_link);
2977 	mtx_leave(&sc->sc_ccb_mtx);
2978 }
2979