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