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