Bug Summary

File:dev/pci/arc.c
Warning:line 2394, column 7
Branch condition evaluates to a garbage value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name arc.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -ffreestanding -mcmodel=kernel -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -target-feature -sse2 -target-feature -sse -target-feature -3dnow -target-feature -mmx -target-feature +save-args -disable-red-zone -no-implicit-float -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -nostdsysteminc -nobuiltininc -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/sys -I /usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -I /usr/src/sys/arch -I /usr/src/sys/dev/pci/drm/include -I /usr/src/sys/dev/pci/drm/include/uapi -I /usr/src/sys/dev/pci/drm/amd/include/asic_reg -I /usr/src/sys/dev/pci/drm/amd/include -I /usr/src/sys/dev/pci/drm/amd/amdgpu -I /usr/src/sys/dev/pci/drm/amd/display -I /usr/src/sys/dev/pci/drm/amd/display/include -I /usr/src/sys/dev/pci/drm/amd/display/dc -I /usr/src/sys/dev/pci/drm/amd/display/amdgpu_dm -I /usr/src/sys/dev/pci/drm/amd/pm/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu11 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu12 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/hwmgr -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/smumgr -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc/hw -I /usr/src/sys/dev/pci/drm/amd/display/dc/clk_mgr -I /usr/src/sys/dev/pci/drm/amd/display/modules/inc -I /usr/src/sys/dev/pci/drm/amd/display/modules/hdcp -I /usr/src/sys/dev/pci/drm/amd/display/dmub/inc -I /usr/src/sys/dev/pci/drm/i915 -D DDB -D DIAGNOSTIC -D KTRACE -D ACCOUNTING -D KMEMSTATS -D PTRACE -D POOL_DEBUG -D CRYPTO -D SYSVMSG -D SYSVSEM -D SYSVSHM -D UVM_SWAP_ENCRYPT -D FFS -D FFS2 -D FFS_SOFTUPDATES -D UFS_DIRHASH -D QUOTA -D EXT2FS -D MFS -D NFSCLIENT -D NFSSERVER -D CD9660 -D UDF -D MSDOSFS -D FIFO -D FUSE -D SOCKET_SPLICE -D TCP_ECN -D TCP_SIGNATURE -D INET6 -D IPSEC -D PPP_BSDCOMP -D PPP_DEFLATE -D PIPEX -D MROUTING -D MPLS -D BOOT_CONFIG -D USER_PCICONF -D APERTURE -D MTRR -D NTFS -D HIBERNATE -D PCIVERBOSE -D USBVERBOSE -D WSDISPLAY_COMPAT_USL -D WSDISPLAY_COMPAT_RAWKBD -D WSDISPLAY_DEFAULTSCREENS=6 -D X86EMU -D ONEWIREVERBOSE -D MULTIPROCESSOR -D MAXUSERS=80 -D _KERNEL -D CONFIG_DRM_AMD_DC_DCN3_0 -O2 -Wno-pointer-sign -Wno-address-of-packed-member -Wno-constant-conversion -Wno-unused-but-set-variable -Wno-gnu-folding-constant -fdebug-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -o /usr/obj/sys/arch/amd64/compile/GENERIC.MP/scan-build/2022-01-12-131800-47421-1 -x c /usr/src/sys/dev/pci/arc.c
1/* $OpenBSD: arc.c,v 1.121 2022/01/09 05:42:45 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/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 NBIO1 > 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
54int 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_A0x00000001 0x00000001
65#define ARC_HBA_TYPE_B0x00000002 0x00000002
66#define ARC_HBA_TYPE_C0x00000003 0x00000003
67#define ARC_HBA_TYPE_D0x00000004 0x00000004
68
69#define ARC_RA_PCI_BAR0x10 PCI_MAPREG_START0x10
70#define ARC_RB_DOORBELL_BAR0x10 PCI_MAPREG_START0x10
71#define ARC_RB_RWBUFFER_BAR0x18 PCI_MAPREG_PPB_END0x18
72#define ARC_RC_PCI_BAR0x14 PCI_MAPREG_PCB_END0x14
73#define ARC_RD_PCI_BAR0x10 PCI_MAPREG_START0x10
74
75#define ARCMSR_MAX_CCB_COUNT264 264
76#define ARCMSR_MAX_HBB_POSTQUEUE264 264
77#define ARCMSR_MAX_HBD_POSTQUEUE256 256
78
79/* Areca boards using the Intel IOP are Type A (RA) */
80
81#define ARC_RA_INB_MSG00x0010 0x0010
82#define ARC_RA_INB_MSG0_NOP(0x00000000) (0x00000000)
83#define ARC_RA_INB_MSG0_GET_CONFIG(0x00000001) (0x00000001)
84#define ARC_RA_INB_MSG0_SET_CONFIG(0x00000002) (0x00000002)
85#define ARC_RA_INB_MSG0_ABORT_CMD(0x00000003) (0x00000003)
86#define ARC_RA_INB_MSG0_STOP_BGRB(0x00000004) (0x00000004)
87#define ARC_RA_INB_MSG0_FLUSH_CACHE(0x00000005) (0x00000005)
88#define ARC_RA_INB_MSG0_START_BGRB(0x00000006) (0x00000006)
89#define ARC_RA_INB_MSG0_CHK331PENDING(0x00000007) (0x00000007)
90#define ARC_RA_INB_MSG0_SYNC_TIMER(0x00000008) (0x00000008)
91#define ARC_RA_INB_MSG10x0014 0x0014
92#define ARC_RA_OUTB_ADDR00x0018 0x0018
93#define ARC_RA_OUTB_ADDR10x001c 0x001c
94#define ARC_RA_OUTB_ADDR1_FIRMWARE_OK(1<<31) (1<<31)
95#define ARC_RA_INB_DOORBELL0x0020 0x0020
96#define ARC_RA_INB_DOORBELL_WRITE_OK(1<<0) (1<<0)
97#define ARC_RA_INB_DOORBELL_READ_OK(1<<1) (1<<1)
98#define ARC_RA_OUTB_DOORBELL0x002c 0x002c
99#define ARC_RA_OUTB_DOORBELL_WRITE_OK(1<<0) (1<<0)
100#define ARC_RA_OUTB_DOORBELL_READ_OK(1<<1) (1<<1)
101#define ARC_RA_INTRSTAT0x0030 0x0030
102#define ARC_RA_INTRSTAT_MSG0(1<<0) (1<<0)
103#define ARC_RA_INTRSTAT_MSG1(1<<1) (1<<1)
104#define ARC_RA_INTRSTAT_DOORBELL(1<<2) (1<<2)
105#define ARC_RA_INTRSTAT_POSTQUEUE(1<<3) (1<<3)
106#define ARC_RA_INTRSTAT_PCI(1<<4) (1<<4)
107#define ARC_RA_INTR_STAT_ALL0x1F 0x1F
108#define ARC_RA_INTRMASK0x0034 0x0034
109#define ARC_RA_INTRMASK_MSG0(1<<0) (1<<0)
110#define ARC_RA_INTRMASK_MSG1(1<<1) (1<<1)
111#define ARC_RA_INTRMASK_DOORBELL(1<<2) (1<<2)
112#define ARC_RA_INTRMASK_POSTQUEUE(1<<3) (1<<3)
113#define ARC_RA_INTRMASK_PCI(1<<4) (1<<4)
114#define ARC_RA_INTR_MASK_ALL0x1F 0x1F
115#define ARC_RA_POST_QUEUE0x0040 0x0040
116#define ARC_RA_POST_QUEUE_ADDR_SHIFT5 5
117#define ARC_RA_POST_QUEUE_IAMBIOS(1<<30) (1<<30)
118#define ARC_RA_POST_QUEUE_BIGFRAME(1<<31) (1<<31)
119#define ARC_RA_REPLY_QUEUE0x0044 0x0044
120#define ARC_RA_REPLY_QUEUE_ADDR_SHIFT5 5
121#define ARC_RA_REPLY_QUEUE_ERR(1<<28) (1<<28)
122#define ARC_RA_REPLY_QUEUE_IAMBIOS(1<<30) (1<<30)
123#define ARC_RA_MSGBUF0x0a00 0x0a00
124#define ARC_RA_MSGBUF_LEN1024 1024
125#define ARC_RA_IOC_WBUF_LEN0x0e00 0x0e00
126#define ARC_RA_IOC_WBUF0x0e04 0x0e04
127#define ARC_RA_IOC_RBUF_LEN0x0f00 0x0f00
128#define ARC_RA_IOC_RBUF0x0f04 0x0f04
129#define ARC_RA_IOC_RWBUF_MAXLEN124 124 /* for both RBUF and WBUF */
130
131/* Areca boards using the Marvel IOP0 are Type B (RB) */
132
133#define ARC_RB_DRV2IOP_DOORBELL0x00020400 0x00020400
134#define ARC_RB_DRV2IOP_DOORBELL_MASK0x00020404 0x00020404
135#define ARC_RB_IOP2DRV_DOORBELL0x00020408 0x00020408
136#define ARC_RB_IOP2DRV_DOORBELL_FIRMWARE_OK(1<<31) (1<<31)
137#define ARC_RB_IOP2DRV_DOORBELL_MASK0x0002040c 0x0002040c
138
139/* Areca boards using the LSI IOP are Type C (RC) */
140
141#define ARC_RC_INB_DOORBELL0x20 0x20
142#define ARC_RC_INTR_STAT0x30 0x30
143#define ARC_RC_INTR_MASK0x34 0x34
144#define ARC_RC_OUTB_DOORBELL0x9C 0x9C
145#define ARC_RC_OUTB_DOORBELL_CLR0xA0 0xA0
146#define ARC_RC_D2I_MSG_CMD_DONE0x08 0x08
147#define ARC_RC_I2D_MSG_CMD_DONE0x08 0x08
148#define ARC_RC_I2D_MSG_CMD_DONE_CLR0x08 0x08
149#define ARC_RC_INB_MSGADDR00xB0 0xB0
150#define ARC_RC_INB_MSGADDR10xB4 0xB4
151#define ARC_RC_OUTB_MSGADDR00xB8 0xB8
152#define ARC_RC_OUTB_MSGADDR10xBC 0xBC
153#define ARC_RC_OUTB_MSG_FIRMWARE_OK0x80000000 0x80000000
154#define ARC_RC_INB_POSTQ_LOW0xC0 0xC0
155#define ARC_RC_INB_POSTQ_HIGH0xC4 0xC4
156#define ARC_RC_OUTB_REPLYQ_LOW0xC8 0xC8
157#define ARC_RC_OUTB_REPLYQ_HIGH0xCC 0xCC
158#define ARC_RC_MSG_WBUF_LEN0x2000 0x2000
159#define ARC_RC_MSG_WBUF0x2004 0x2004
160#define ARC_RC_MSG_RBUF_LEN0x2100 0x2100
161#define ARC_RC_MSG_RBUF0x2104 0x2104
162#define ARC_RC_MSG_RWBUF0x2200 0x2200
163
164#define ARC_RC_INB_MSG0_NOP(0x00000000) (0x00000000)
165#define ARC_RC_INB_MSG0_GET_CONFIG(0x00000001) (0x00000001)
166#define ARC_RC_INB_MSG0_SET_CONFIG(0x00000002) (0x00000002)
167#define ARC_RC_INB_MSG0_ABORT_CMD(0x00000003) (0x00000003)
168#define ARC_RC_INB_MSG0_STOP_BGRB(0x00000004) (0x00000004)
169#define ARC_RC_INB_MSG0_FLUSH_CACHE(0x00000005) (0x00000005)
170#define ARC_RC_INB_MSG0_START_BGRB(0x00000006) (0x00000006)
171#define ARC_RC_INB_MSG0_CHK331PENDING(0x00000007) (0x00000007)
172#define ARC_RC_INB_MSG0_SYNC_TIMER(0x00000008) (0x00000008)
173
174#define ARC_RC_D2I_DATA_WRITE_OK0x00000002 0x00000002
175#define ARC_RC_D2I_DATA_READ_OK0x00000004 0x00000004
176#define ARC_RC_D2I_MESSAGE_CMD_DONE0x00000008 0x00000008
177#define ARC_RC_D2I_POSTQUEUE_THROTTLING0x00000010 0x00000010
178#define ARC_RC_I2D_DATA_WRITE_OK0x00000002 0x00000002
179#define ARC_RC_I2D_DATA_WRITE_OK_CLEAR0x00000002 0x00000002
180#define ARC_RC_I2D_DATA_READ_OK0x00000004 0x00000004
181#define ARC_RC_I2D_DATA_READ_OK_CLEAR0x00000004 0x00000004
182#define ARC_RC_I2D_MESSAGE_CMD_DONE0x00000008 0x00000008
183#define ARC_RC_I2D_MESSAGE_CMD_DONE_CLEAR0x00000008 0x00000008
184#define ARC_RC_MESSAGE_FIRMWARE_OK0x80000000 0x80000000
185
186#define ARC_RC_INTR_STAT_UTILITY_A(1<<0) (1<<0)
187#define ARC_RC_INTR_STAT_DOORBELL(1<<2) (1<<2)
188#define ARC_RC_INTR_STAT_POSTQUEUE(1<<3) (1<<3)
189#define ARC_RC_INTR_MASK_ALL0x0000000D 0x0000000D
190#define ARC_RC_INTR_MASK_UTILITY_A(1<<0) (1<<0)
191#define ARC_RC_INTR_MASK_DOORBELL(1<<2) (1<<2)
192#define ARC_RC_INTR_MASK_POSTQUEUE(1<<3) (1<<3)
193#define ARC_RC_REPLY_QUEUE_ERR1 1
194#define ARC_RC_THROTTLE12 12
195
196/* Areca boards using the Marvell IOP 9580 are Type D (RD) */
197
198#define ARC_RD_INTR_STAT0x200 0x200
199#define ARC_RD_HOST_INT_ENABLE0x204 0x204
200#define ARC_RD_INTR_ENABLE0x20C 0x20C
201#define ARC_RD_D2I_MSG_CMD_DONE0x08 0x08
202#define ARC_RD_I2D_MSG_CMD_DONE0x2000000 0x2000000
203#define ARC_RD_I2D_MSG_CMD_DONE_CLR0x2000000 0x2000000
204#define ARC_RD_INB_MSGADDR00x400 0x400
205#define ARC_RD_INB_MSGADDR10x404 0x404
206#define ARC_RD_OUTB_MSGADDR00x420 0x420
207#define ARC_RD_OUTB_MSGADDR10x424 0x424
208#define ARC_RD_INB_DOORBELL0x460 0x460
209#define ARC_RD_OUTB_DOORBELL0x480 0x480
210#define ARC_RD_OUTB_DOORBELL_CLR0x480 0x480
211#define ARC_RD_OUTB_DOORBELL_ENABLE0x484 0x484
212#define ARC_RD_OUTB_MSG_FIRMWARE_OK0x80000000 0x80000000
213#define ARC_RD_INB_POSTQ_LOW0x1000 0x1000
214#define ARC_RD_INB_POSTQ_HIGH0x1004 0x1004
215#define ARC_RD_OUTB_REPLYQ_LOW0x1060 0x1060
216#define ARC_RD_OUTB_REPLYQ_HIGH0x1064 0x1064
217
218#define ARC_RD_INB_WRITE_PTR0x1018 0x1018
219#define ARC_RD_INB_READ_PTR0x101C 0x101C
220#define ARC_RD_OUTB_COPY_PTR0x106C 0x106C
221#define ARC_RD_OUTB_READ_PTR0x1070 0x1070
222#define ARC_RD_OUTB_INTR_CAUSE0x1088 0x1088
223#define ARC_RD_OUTB_INT_ENABLE0x108C 0x108C
224#define ARC_RD_MSG_WBUF_LEN0x2000 0x2000
225#define ARC_RD_MSG_WBUF0x2004 0x2004
226#define ARC_RD_MSG_RBUF_LEN0x2100 0x2100
227#define ARC_RD_MSG_RBUF0x2104 0x2104
228#define ARC_RD_MSG_RWBUF0x2200 0x2200
229
230#define ARC_RD_INB_MSG0_NOP(0x00000000) (0x00000000)
231#define ARC_RD_INB_MSG0_GET_CONFIG(0x00000001) (0x00000001)
232#define ARC_RD_INB_MSG0_SET_CONFIG(0x00000002) (0x00000002)
233#define ARC_RD_INB_MSG0_ABORT_CMD(0x00000003) (0x00000003)
234#define ARC_RD_INB_MSG0_STOP_BGRB(0x00000004) (0x00000004)
235#define ARC_RD_INB_MSG0_FLUSH_CACHE(0x00000005) (0x00000005)
236#define ARC_RD_INB_MSG0_START_BGRB(0x00000006) (0x00000006)
237#define ARC_RD_INB_MSG0_CHK331PENDING(0x00000007) (0x00000007)
238#define ARC_RD_INB_MSG0_SYNC_TIMER(0x00000008) (0x00000008)
239
240#define ARC_RD_D2I_DATA_WRITE_OK0x00000001 0x00000001
241#define ARC_RD_D2I_DATA_READ_OK0x00000002 0x00000002
242#define ARC_RD_D2I_MESSAGE_CMD_DONE0x02000000 0x02000000
243#define ARC_RD_D2I_POSTQUEUE_THROTTLING0x00000010 0x00000010
244#define ARC_RD_I2D_DATA_WRITE_OK0x00000001 0x00000001
245#define ARC_RD_I2D_DATA_WRITE_CLEAR0x00000001 0x00000001
246#define ARC_RD_I2D_DATA_READ_OK0x00000002 0x00000002
247#define ARC_RD_I2D_DATA_READ_CLEAR0x00000002 0x00000002
248#define ARC_RD_I2D_MESSAGE_CMD_DONE0x02000000 0x02000000
249#define ARC_RD_I2D_MESSAGE_CMD_DONE_CLEAR0x02000000 0x02000000
250#define ARC_RD_MESSAGE_FIRMWARE_OK0x80000000 0x80000000
251
252#define ARC_RD_INTR_STAT_DOORBELL0x00001000 0x00001000
253#define ARC_RD_INTR_STAT_POSTQUEUE0x00000010 0x00000010
254#define ARC_RD_INTR_ENABLE_ALL0x00001010 0x00001010
255#define ARC_RD_INTR_DISABLE_ALL0x00000000 0x00000000
256#define ARC_RD_INTR_ENABLE_DOORBELL0x00001000 0x00001000
257#define ARC_RD_INTR_ENABLE_POSTQUEUE0x00000010 0x00000010
258#define ARC_RD_REPLY_QUEUE_ERR1 1
259#define ARC_RD_OUTB_LIST_INT_CLR1 1
260
261struct arc_msg_firmware_info {
262 u_int32_t signature;
263#define ARC_FWINFO_SIGNATURE_GET_CONFIG(0x87974060) (0x87974060)
264#define ARC_FWINFO_SIGNATURE_SET_CONFIG(0x87974063) (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__attribute__((__packed__));
277
278/* definitions of the firmware commands sent via the doorbells */
279
280struct arc_fw_hdr {
281 u_int8_t byte1;
282 u_int8_t byte2;
283 u_int8_t byte3;
284} __packed__attribute__((__packed__));
285
286/* the fw header must always equal this */
287struct arc_fw_hdr arc_fw_hdr = { 0x5e, 0x01, 0x61 };
288
289struct arc_fw_bufhdr {
290 struct arc_fw_hdr hdr;
291 u_int16_t len;
292} __packed__attribute__((__packed__));
293
294#define ARC_FW_RAIDINFO0x20 0x20 /* opcode + raid# */
295#define ARC_FW_VOLINFO0x21 0x21 /* opcode + vol# */
296#define ARC_FW_DISKINFO0x22 0x22 /* opcode + physdisk# */
297#define ARC_FW_SYSINFO0x23 0x23 /* opcode. reply is fw_sysinfo */
298#define ARC_FW_MUTE_ALARM0x30 0x30 /* opcode only */
299#define ARC_FW_SET_ALARM0x31 0x31 /* opcode + 1 byte for setting */
300#define ARC_FW_SET_ALARM_DISABLE0x00 0x00
301#define ARC_FW_SET_ALARM_ENABLE0x01 0x01
302#define ARC_FW_NOP0x38 0x38 /* opcode only */
303
304#define ARC_FW_CMD_OK0x41 0x41
305#define ARC_FW_BLINK0x43 0x43
306#define ARC_FW_BLINK_ENABLE0x00 0x00
307#define ARC_FW_BLINK_DISABLE0x01 0x01
308#define ARC_FW_CMD_PASS_REQD0x4d 0x4d
309
310struct 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__attribute__((__packed__));
317
318struct 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__attribute__((__packed__));
326
327struct 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__attribute__((__packed__));
345
346struct 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_NORMAL0x00 0x00
356#define ARC_FW_VOL_STATUS_INITTING(1<<0) (1<<0)
357#define ARC_FW_VOL_STATUS_FAILED(1<<1) (1<<1)
358#define ARC_FW_VOL_STATUS_MIGRATING(1<<2) (1<<2)
359#define ARC_FW_VOL_STATUS_REBUILDING(1<<3) (1<<3)
360#define ARC_FW_VOL_STATUS_NEED_INIT(1<<4) (1<<4)
361#define ARC_FW_VOL_STATUS_NEED_MIGRATE(1<<5) (1<<5)
362#define ARC_FW_VOL_STATUS_INIT_FLAG(1<<6) (1<<6)
363#define ARC_FW_VOL_STATUS_NEED_REGEN(1<<7) (1<<7)
364#define ARC_FW_VOL_STATUS_CHECKING(1<<8) (1<<8)
365#define ARC_FW_VOL_STATUS_NEED_CHECK(1<<9) (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_00x00 0x00
371#define ARC_FW_VOL_RAIDLEVEL_10x01 0x01
372#define ARC_FW_VOL_RAIDLEVEL_30x02 0x02
373#define ARC_FW_VOL_RAIDLEVEL_50x03 0x03
374#define ARC_FW_VOL_RAIDLEVEL_60x04 0x04
375#define ARC_FW_VOL_RAIDLEVEL_PASSTHRU0x05 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__attribute__((__packed__));
386
387struct 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__attribute__((__packed__));
402
403struct 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__attribute__((__packed__));
441
442struct arc_iop;
443struct arc_ccb;
444SLIST_HEAD(arc_ccb_list, arc_ccb)struct arc_ccb_list { struct arc_ccb *slh_first; };
445
446struct 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
453struct OutBound_SRB {
454 u_int32_t addressLow; /* pointer to SRB block */
455 u_int32_t addressHigh;
456};
457
458struct arc_HBD_Msgu {
459 struct InBound_SRB post_qbuffer[ARCMSR_MAX_HBD_POSTQUEUE256];
460 struct OutBound_SRB done_qbuffer[ARCMSR_MAX_HBD_POSTQUEUE256+1];
461 u_int16_t postq_index;
462 u_int16_t doneq_index;
463};
464
465#define ARC_MAX_CMDQ_PTR_LENsizeof(struct arc_HBD_Msgu) sizeof(struct arc_HBD_Msgu)
466
467struct 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) (1<<0)
477#define ARC_MSG_SCSICMD_FLAG_FROM_BIOS(1<<1) (1<<1)
478#define ARC_MSG_SCSICMD_FLAG_WRITE(1<<2) (1<<2)
479#define ARC_MSG_SCSICMD_FLAG_SIMPLEQ(0x00) (0x00)
480#define ARC_MSG_SCSICMD_FLAG_HEADQ(0x08) (0x08)
481#define ARC_MSG_SCSICMD_FLAG_ORDERQ(0x10) (0x10)
482 u_int8_t msgPages;
483
484 u_int32_t context;
485 u_int32_t data_len;
486
487#define ARC_MSG_CDBLEN16 16
488 u_int8_t cdb[ARC_MSG_CDBLEN16];
489
490 u_int8_t status;
491#define ARC_MSG_STATUS_SELTIMEOUT0xf0 0xf0
492#define ARC_MSG_STATUS_ABORTED0xf1 0xf1
493#define ARC_MSG_STATUS_INIT_FAIL0xf2 0xf2
494#define ARC_MSG_SENSELEN15 15
495 u_int8_t sense_data[ARC_MSG_SENSELEN15];
496
497 /* followed by an sgl */
498} __packed__attribute__((__packed__));
499
500struct arc_sge {
501 u_int32_t sg_length;
502#define ARC_SGE_64BIT(1<<24) (1<<24)
503 u_int32_t sg_lo_addr;
504 u_int32_t sg_hi_addr;
505} __packed__attribute__((__packed__));
506
507#define ARC_MAX_TARGET16 16
508#define ARC_MAX_LUN8 8
509#define ARC_MAX_IOCMDLEN512 512
510#define ARC_BLOCKSIZE512 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_MAXLEN38 38
515/* sizeof(struct arc_msg_scsicmd) + (sizeof(struct arc_sge) * 17) == 252 */
516#define ARC_SGL_256LEN17 17
517
518struct arc_io_cmd {
519 struct arc_msg_scsicmd cmd;
520 struct arc_sge sgl[ARC_SGL_MAXLEN38];
521 u_int32_t reserved1;
522 struct arc_ccb *ccb;
523 u_int32_t reserved2[6];
524} __packed__attribute__((__packed__));
525
526#define ARC_IO_CMD_LEN512+32 512+32
527
528/* stuff to manage a scsi command */
529struct 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)struct { struct arc_ccb *sle_next; } ccb_link;
540 u_int32_t arc_io_cmd_length;
541};
542
543struct 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) ((_s)->sc_dev.dv_xname)
583
584/* wrap up the bus_dma api */
585struct 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) ((_adm)->adm_map)
592#define ARC_DMA_DVA(_adm)((_adm)->adm_map->dm_segs[0].ds_addr) ((_adm)->adm_map->dm_segs[0].ds_addr)
593#define ARC_DMA_KVA(_adm)((void *)(_adm)->adm_kva) ((void *)(_adm)->adm_kva)
594
595int arc_match(struct device *, void *, void *);
596void arc_attach(struct device *, struct device *, void *);
597int arc_detach(struct device *, int);
598int arc_activate(struct device *, int);
599int arc_intr(void *);
600int arc_intr_A(void *);
601int arc_intr_C(void *);
602int arc_intr_D(void *);
603
604/* interface for scsi midlayer to talk to */
605void arc_scsi_cmd(struct scsi_xfer *);
606
607/* code to deal with getting bits in and out of the bus space */
608u_int32_t arc_read(struct arc_softc *, bus_size_t);
609void arc_read_region(struct arc_softc *, bus_size_t,
610 void *, size_t);
611void arc_write(struct arc_softc *, bus_size_t, u_int32_t);
612void arc_write_region(struct arc_softc *, bus_size_t,
613 void *, size_t);
614int arc_wait_eq(struct arc_softc *, bus_size_t,
615 u_int32_t, u_int32_t);
616int arc_wait_ne(struct arc_softc *, bus_size_t,
617 u_int32_t, u_int32_t);
618int arc_msg0(struct arc_softc *, u_int32_t);
619
620struct arc_dmamem *arc_dmamem_alloc(struct arc_softc *, size_t);
621void arc_dmamem_free(struct arc_softc *,
622 struct arc_dmamem *);
623void arc_free_ccb_src(struct arc_softc *sc);
624
625int arc_alloc_ccbs(struct arc_softc *);
626struct arc_ccb *arc_get_ccb(struct arc_softc *);
627void arc_put_ccb(struct arc_softc *, struct arc_ccb *);
628int arc_load_xs(struct arc_ccb *);
629int arc_complete(struct arc_softc *, struct arc_ccb *,
630 int);
631void arc_scsi_cmd_done(struct arc_softc *, struct arc_ccb *,
632 u_int32_t);
633
634int arc_map_pci_resources(struct arc_softc *,
635 struct pci_attach_args *);
636void arc_unmap_pci_resources(struct arc_softc *);
637int arc_chipA_firmware(struct arc_softc *);
638int arc_chipB_firmware(struct arc_softc *);
639int arc_chipC_firmware(struct arc_softc *);
640int arc_chipD_firmware(struct arc_softc *);
641void arc_enable_all_intr(struct arc_softc *);
642void arc_disable_all_intr(struct arc_softc *);
643void arc_stop_bgrb_proc(struct arc_softc *sc);
644void arc_flush_cache(struct arc_softc *sc);
645void arc_iop_set_conf(struct arc_softc *sc);
646
647#if NBIO1 > 0
648/* stuff to do messaging via the doorbells */
649void arc_lock(struct arc_softc *);
650void arc_unlock(struct arc_softc *);
651void arc_wait(struct arc_softc *);
652u_int8_t arc_msg_cksum(void *, u_int16_t);
653int arc_msgbuf(struct arc_softc *, void *, size_t,
654 void *, size_t, int);
655
656/* bioctl */
657int arc_bioctl(struct device *, u_long, caddr_t);
658int arc_bio_inq(struct arc_softc *, struct bioc_inq *);
659int arc_bio_vol(struct arc_softc *, struct bioc_vol *);
660int arc_bio_disk(struct arc_softc *, struct bioc_disk *);
661int arc_bio_alarm(struct arc_softc *, struct bioc_alarm *);
662int arc_bio_alarm_state(struct arc_softc *,
663 struct bioc_alarm *);
664int arc_bio_blink(struct arc_softc *, struct bioc_blink *);
665
666int arc_bio_getvol(struct arc_softc *, int,
667 struct arc_fw_volinfo *);
668
669#ifndef SMALL_KERNEL
670struct arc_task {
671 struct task t;
672 struct arc_softc *sc;
673};
674/* sensors */
675void arc_create_sensors(void *);
676void arc_refresh_sensors(void *);
677#endif /* SMALL_KERNEL */
678#endif
679
680struct cfattach arc_ca = {
681 sizeof(struct arc_softc), arc_match, arc_attach, arc_detach,
682 arc_activate
683};
684
685struct cfdriver arc_cd = {
686 NULL((void *)0), "arc", DV_DULL
687};
688
689struct scsi_adapter arc_switch = {
690 arc_scsi_cmd, NULL((void *)0), NULL((void *)0), NULL((void *)0), NULL((void *)0)
691};
692
693/* real stuff for dealing with the hardware */
694struct arc_iop {
695 int (*iop_query_firmware)(struct arc_softc *);
696};
697
698static const struct arc_iop arc_intel = {
699 arc_chipA_firmware
700};
701
702static const struct arc_iop arc_marvell = {
703 arc_chipB_firmware
704};
705
706static const struct arc_iop arc_lsi = {
707 arc_chipC_firmware
708};
709
710static const struct arc_iop arc_marvell2 = {
711 arc_chipD_firmware
712};
713
714struct arc_board {
715 pcireg_t ab_vendor;
716 pcireg_t ab_product;
717 const struct arc_iop *ab_iop;
718};
719const struct arc_board *arc_match_board(struct pci_attach_args *);
720
721static const struct arc_board arc_devices[] = {
722 { PCI_VENDOR_ARECA0x17d3, PCI_PRODUCT_ARECA_ARC11100x1110, &arc_intel },
723 { PCI_VENDOR_ARECA0x17d3, PCI_PRODUCT_ARECA_ARC11200x1120, &arc_intel },
724 { PCI_VENDOR_ARECA0x17d3, PCI_PRODUCT_ARECA_ARC11300x1130, &arc_intel },
725 { PCI_VENDOR_ARECA0x17d3, PCI_PRODUCT_ARECA_ARC11600x1160, &arc_intel },
726 { PCI_VENDOR_ARECA0x17d3, PCI_PRODUCT_ARECA_ARC11700x1170, &arc_intel },
727 { PCI_VENDOR_ARECA0x17d3, PCI_PRODUCT_ARECA_ARC12000x1200, &arc_intel },
728 { PCI_VENDOR_ARECA0x17d3, PCI_PRODUCT_ARECA_ARC1200_B0x1201, &arc_marvell },
729 { PCI_VENDOR_ARECA0x17d3, PCI_PRODUCT_ARECA_ARC12020x1202, &arc_intel },
730 { PCI_VENDOR_ARECA0x17d3, PCI_PRODUCT_ARECA_ARC12100x1210, &arc_intel },
731 { PCI_VENDOR_ARECA0x17d3, PCI_PRODUCT_ARECA_ARC12140x1214, &arc_marvell2 },
732 { PCI_VENDOR_ARECA0x17d3, PCI_PRODUCT_ARECA_ARC12200x1220, &arc_intel },
733 { PCI_VENDOR_ARECA0x17d3, PCI_PRODUCT_ARECA_ARC12300x1230, &arc_intel },
734 { PCI_VENDOR_ARECA0x17d3, PCI_PRODUCT_ARECA_ARC12600x1260, &arc_intel },
735 { PCI_VENDOR_ARECA0x17d3, PCI_PRODUCT_ARECA_ARC12700x1270, &arc_intel },
736 { PCI_VENDOR_ARECA0x17d3, PCI_PRODUCT_ARECA_ARC12800x1280, &arc_intel },
737 { PCI_VENDOR_ARECA0x17d3, PCI_PRODUCT_ARECA_ARC13800x1380, &arc_intel },
738 { PCI_VENDOR_ARECA0x17d3, PCI_PRODUCT_ARECA_ARC13810x1381, &arc_intel },
739 { PCI_VENDOR_ARECA0x17d3, PCI_PRODUCT_ARECA_ARC16800x1680, &arc_intel },
740 { PCI_VENDOR_ARECA0x17d3, PCI_PRODUCT_ARECA_ARC16810x1681, &arc_intel },
741 { PCI_VENDOR_ARECA0x17d3, PCI_PRODUCT_ARECA_ARC18800x1880, &arc_lsi }
742};
743
744const struct arc_board *
745arc_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)(((pa->pa_id) >> 0) & 0xffff) == ab->ab_vendor &&
754 PCI_PRODUCT(pa->pa_id)(((pa->pa_id) >> 16) & 0xffff) == ab->ab_product)
755 return (ab);
756 }
757
758 return (NULL((void *)0));
759}
760
761int
762arc_match(struct device *parent, void *match, void *aux)
763{
764 return ((arc_match_board(aux) == NULL((void *)0)) ? 0 : 1);
765}
766
767void
768arc_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")_rw_init_flags(&sc->sc_lock, "arcmsg", 0, ((void *)0));
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_A0x00000001;
780 else if(sc->sc_iop == &arc_marvell)
781 sc->sc_adp_type = ARC_HBA_TYPE_B0x00000002;
782 else if(sc->sc_iop == &arc_lsi)
783 sc->sc_adp_type = ARC_HBA_TYPE_C0x00000003;
784 else if(sc->sc_iop == &arc_marvell2)
785 sc->sc_adp_type = ARC_HBA_TYPE_D0x00000004;
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_TARGET0xffff;
806 saa.saa_adapter_buswidth = ARC_MAX_TARGET16;
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,config_found_sm((self), (&saa), (scsiprint), ((void *)0))
814 scsiprint)config_found_sm((self), (&saa), (scsiprint), ((void *)0));
815
816 /* enable interrupts */
817 arc_enable_all_intr(sc);
818
819#if NBIO1 > 0
820 if (bio_register(self, arc_bioctl) != 0)
821 panic("%s: bioctl registration failed", DEVNAME(sc)((sc)->sc_dev.dv_xname));
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_TEMP127, M_WAITOK0x0001);
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;
841unmap_pci:
842 arc_unmap_pci_resources(sc);
843}
844
845int
846arc_activate(struct device *self, int act)
847{
848 int rv = 0;
849
850 switch (act) {
851 case DVACT_POWERDOWN6:
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
862int
863arc_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
873int
874arc_intr_A(void *arg)
875{
876 struct arc_softc *sc = arg;
877 struct arc_ccb *ccb = NULL((void *)0);
878 char *kva = ARC_DMA_KVA(sc->sc_requests)((void *)(sc->sc_requests)->adm_kva);
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_INTRSTAT0x0030);
884 intrstat &= ARC_RA_INTRSTAT_POSTQUEUE(1<<3) | ARC_RA_INTRSTAT_DOORBELL(1<<2) |
885 ARC_RA_INTRSTAT_MSG0(1<<0);
886 arc_write(sc, ARC_RA_INTRSTAT0x0030, intrstat);
887
888 if (intrstat & ARC_RA_INTRSTAT_DOORBELL(1<<2)) {
889 ret = 1;
890 if (sc->sc_talking) {
891 /* if an ioctl is talking, wake it up */
892 arc_write(sc, ARC_RA_INTRMASK0x0034,
893 ~ARC_RA_INTRMASK_POSTQUEUE(1<<3));
894 wakeup(sc);
895 } else {
896 /* otherwise drop it */
897 reg = arc_read(sc, ARC_RA_OUTB_DOORBELL0x002c);
898 arc_write(sc, ARC_RA_OUTB_DOORBELL0x002c, reg);
899 if (reg & ARC_RA_OUTB_DOORBELL_WRITE_OK(1<<0))
900 arc_write(sc, ARC_RA_INB_DOORBELL0x0020,
901 ARC_RA_INB_DOORBELL_READ_OK(1<<1));
902 }
903 }
904
905 if (intrstat & ARC_RA_INTRSTAT_POSTQUEUE(1<<3)) {
906 while ((reg = arc_read(sc, ARC_RA_REPLY_QUEUE0x0044)) != 0xffffffff) {
907 ret = 1;
908 cmd = (struct arc_io_cmd *)(kva +
909 ((reg << ARC_RA_REPLY_QUEUE_ADDR_SHIFT5) -
910 (u_int32_t)ARC_DMA_DVA(sc->sc_requests)((sc->sc_requests)->adm_map->dm_segs[0].ds_addr)));
911 ccb = cmd->ccb;
912
913 bus_dmamap_sync(sc->sc_dmat, ARC_DMA_MAP(sc->sc_requests),(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (((sc->
sc_requests)->adm_map)), (ccb->cmd_dma_offset), (512), (
0x01 | 0x04))
914 ccb->cmd_dma_offset, ARC_MAX_IOCMDLEN,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (((sc->
sc_requests)->adm_map)), (ccb->cmd_dma_offset), (512), (
0x01 | 0x04))
915 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (((sc->
sc_requests)->adm_map)), (ccb->cmd_dma_offset), (512), (
0x01 | 0x04))
;
916
917 error = (reg & ARC_RA_REPLY_QUEUE_ERR(1<<28))? 1:0;
918 arc_scsi_cmd_done(sc, ccb, error);
919 }
920 }
921 return (ret);
922}
923
924int
925arc_intr_C(void *arg)
926{
927 struct arc_softc *sc = arg;
928 struct arc_ccb *ccb = NULL((void *)0);
929 char *kva = ARC_DMA_KVA(sc->sc_requests)((void *)(sc->sc_requests)->adm_kva);
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_STAT0x30);
935 if (!(intrstat & (ARC_RC_INTR_STAT_POSTQUEUE(1<<3) |
936 ARC_RC_INTR_STAT_DOORBELL(1<<2))))
937 return (ret);
938
939 if (intrstat & ARC_RC_INTR_STAT_DOORBELL(1<<2)) {
940 ret = 1;
941 if (sc->sc_talking) {
942 /* if an ioctl is talking, wake it up */
943 arc_write(sc, ARC_RC_INTR_MASK0x34,
944 ~ARC_RC_INTR_MASK_POSTQUEUE(1<<3));
945 wakeup(sc);
946 } else {
947 /* otherwise drop it */
948 reg = arc_read(sc, ARC_RC_OUTB_DOORBELL0x9C);
949 arc_write(sc, ARC_RC_OUTB_DOORBELL_CLR0xA0, reg);
950 if (reg & ARC_RC_I2D_DATA_WRITE_OK0x00000002) {
951 arc_write(sc, ARC_RC_INB_DOORBELL0x20,
952 ARC_RC_I2D_DATA_READ_OK0x00000004);
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_DONE0x00000008) {
960 arc_write(sc, ARC_RC_OUTB_DOORBELL_CLR0xA0,
961 ARC_RC_I2D_MSG_CMD_DONE_CLR0x08);
962 obmsg = arc_read(sc, ARC_RC_MSG_RWBUF0x2200);
963 if (obmsg == ARC_FWINFO_SIGNATURE_GET_CONFIG(0x87974060))
964 ; /* handle devices hot-plug */
965 }
966
967 }
968 }
969
970 if (intrstat & ARC_RC_INTR_STAT_POSTQUEUE(1<<3)) {
971 ret = 1;
972 throttling = 0;
973 while (arc_read(sc, ARC_RC_INTR_STAT0x30) &
974 ARC_RC_INTR_STAT_POSTQUEUE(1<<3)) {
975 reg = arc_read(sc, ARC_RC_OUTB_REPLYQ_LOW0xC8);
976 cmd = (struct arc_io_cmd *)(kva + ((reg & 0xFFFFFFE0) -
977 (u_int32_t)ARC_DMA_DVA(sc->sc_requests)((sc->sc_requests)->adm_map->dm_segs[0].ds_addr)));
978 ccb = cmd->ccb;
979
980 bus_dmamap_sync(sc->sc_dmat, ARC_DMA_MAP(sc->sc_requests),(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (((sc->
sc_requests)->adm_map)), (ccb->cmd_dma_offset), (512), (
0x01 | 0x04))
981 ccb->cmd_dma_offset, ARC_MAX_IOCMDLEN,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (((sc->
sc_requests)->adm_map)), (ccb->cmd_dma_offset), (512), (
0x01 | 0x04))
982 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (((sc->
sc_requests)->adm_map)), (ccb->cmd_dma_offset), (512), (
0x01 | 0x04))
;
983
984 error = (reg & ARC_RC_REPLY_QUEUE_ERR1);
985 arc_scsi_cmd_done(sc, ccb, error);
986 throttling++;
987 if(throttling == ARC_RC_THROTTLE12) {
988 arc_write(sc, ARC_RC_INB_DOORBELL0x20,
989 ARC_RC_D2I_POSTQUEUE_THROTTLING0x00000010);
990 throttling = 0;
991 }
992 }
993 }
994
995 return (ret);
996}
997
998static u_int16_t
999arcmsr_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_POSTQUEUE256;
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_POSTQUEUE256;
1014 phbdmu->doneq_index = index_stripped ?
1015 index_stripped : (index_stripped | 0x4000);
1016 }
1017 return (phbdmu->doneq_index);
1018}
1019
1020int
1021arc_intr_D(void *arg)
1022{
1023 struct arc_softc *sc = arg;
1024 struct arc_ccb *ccb = NULL((void *)0);
1025 char *kva = ARC_DMA_KVA(sc->sc_requests)((void *)(sc->sc_requests)->adm_kva);
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_STAT0x200);
1034 if (!(intrstat & (ARC_RD_INTR_STAT_POSTQUEUE0x00000010 |
1035 ARC_RD_INTR_STAT_DOORBELL0x00001000)))
1036 return (ret);
1037
1038 if (intrstat & ARC_RD_INTR_STAT_DOORBELL0x00001000) {
1039 ret = 1;
1040 if (sc->sc_talking) {
1041 /* if an ioctl is talking, wake it up */
1042 arc_write(sc, ARC_RD_INTR_ENABLE0x20C,
1043 ARC_RD_INTR_ENABLE_POSTQUEUE0x00000010);
1044 wakeup(sc);
1045 } else {
1046 /* otherwise drop it */
1047 reg = arc_read(sc, ARC_RD_OUTB_DOORBELL0x480);
1048 arc_write(sc, ARC_RD_OUTB_DOORBELL0x480, reg);
1049 if (reg & ARC_RD_I2D_DATA_WRITE_OK0x00000001) {
1050 arc_write(sc, ARC_RD_INB_DOORBELL0x460,
1051 ARC_RD_I2D_DATA_READ_OK0x00000002);
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_DONE0x02000000) {
1059 arc_write(sc, ARC_RD_OUTB_DOORBELL_CLR0x480,
1060 ARC_RD_I2D_MSG_CMD_DONE_CLR0x2000000);
1061 obmsg = arc_read(sc, ARC_RD_MSG_RWBUF0x2200);
1062 if (obmsg == ARC_FWINFO_SIGNATURE_GET_CONFIG(0x87974060))
1063 ; /* handle devices hot-plug */
1064 }
1065 }
1066 }
1067
1068 if (intrstat & ARC_RD_INTR_STAT_POSTQUEUE0x00000010) {
1069 ret = 1;
1070 arc_write(sc, ARC_RD_OUTB_INTR_CAUSE0x1088, ARC_RD_OUTB_LIST_INT_CLR1);
1071 bus_dmamap_sync(sc->sc_dmat, ARC_DMA_MAP(sc->sc_requests),(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (((sc->
sc_requests)->adm_map)), (sc->cmdQ_ptr_offset), (sizeof
(struct arc_HBD_Msgu)), (0x01 | 0x04))
1072 sc->cmdQ_ptr_offset, ARC_MAX_CMDQ_PTR_LEN,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (((sc->
sc_requests)->adm_map)), (sc->cmdQ_ptr_offset), (sizeof
(struct arc_HBD_Msgu)), (0x01 | 0x04))
1073 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (((sc->
sc_requests)->adm_map)), (sc->cmdQ_ptr_offset), (sizeof
(struct arc_HBD_Msgu)), (0x01 | 0x04))
;
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)((sc->sc_requests)->adm_map->dm_segs[0].ds_addr)));
1082 ccb = cmd->ccb;
1083 bus_dmamap_sync(sc->sc_dmat, ARC_DMA_MAP(sc->sc_requests),(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (((sc->
sc_requests)->adm_map)), (ccb->cmd_dma_offset), (512), (
0x01 | 0x04))
1084 ccb->cmd_dma_offset, ARC_MAX_IOCMDLEN,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (((sc->
sc_requests)->adm_map)), (ccb->cmd_dma_offset), (512), (
0x01 | 0x04))
1085 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (((sc->
sc_requests)->adm_map)), (ccb->cmd_dma_offset), (512), (
0x01 | 0x04))
;
1086 error = (reg & ARC_RD_REPLY_QUEUE_ERR1);
1087 arc_scsi_cmd_done(sc, ccb, error);
1088 arc_write(sc, ARC_RD_OUTB_READ_PTR0x1070, doneq_index);
1089 ob_write_ptr = pmu->done_qbuffer[0].addressLow;
1090 }
1091 }
1092
1093 return (ret);
1094}
1095
1096int
1097arc_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_A0x00000001:
1104 ret = arc_intr_A(arg);
1105 break;
1106 case ARC_HBA_TYPE_C0x00000003:
1107 ret = arc_intr_C(arg);
1108 break;
1109 case ARC_HBA_TYPE_D0x00000004:
1110 ret = arc_intr_D(arg);
1111 break;
1112 }
1113 return (ret);
1114}
1115
1116void
1117arc_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_CDBLEN16) {
1131 bzero(&xs->sense, sizeof(xs->sense))__builtin_bzero((&xs->sense), (sizeof(xs->sense)));
1132 xs->sense.error_code = SSD_ERRCODE_VALID0x80 | 0x70;
1133 xs->sense.flags = SKEY_ILLEGAL_REQUEST0x05;
1134 xs->sense.add_sense_code = 0x20;
1135 xs->error = XS_SENSE1;
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_STUFFUP2;
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_OUT0x01000)
1160 cmd->flags = ARC_MSG_SCSICMD_FLAG_WRITE(1<<2);
1161 if (ccb->ccb_dmamap->dm_nsegs > ARC_SGL_256LEN17) {
1162 cmd->flags |= ARC_MSG_SCSICMD_FLAG_SGL_BSIZE_512(1<<0);
1163/* reg |= ARC_RA_POST_QUEUE_BIGFRAME; */
1164 }
1165
1166 cmd->data_len = htole32(xs->datalen)((__uint32_t)(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),(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (((sc->
sc_requests)->adm_map)), (ccb->cmd_dma_offset), (512), (
0x01 | 0x04))
1172 ccb->cmd_dma_offset, ARC_MAX_IOCMDLEN,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (((sc->
sc_requests)->adm_map)), (ccb->cmd_dma_offset), (512), (
0x01 | 0x04))
1173 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (((sc->
sc_requests)->adm_map)), (ccb->cmd_dma_offset), (512), (
0x01 | 0x04))
;
1174
1175 s = splbio()splraise(0x6);
1176 switch(sc->sc_adp_type) {
1177 case ARC_HBA_TYPE_A0x00000001:
1178 if (cmd->flags & ARC_MSG_SCSICMD_FLAG_SGL_BSIZE_512(1<<0))
1179 reg |= ARC_RA_POST_QUEUE_BIGFRAME(1<<31);
1180 arc_write(sc, ARC_RA_POST_QUEUE0x0040, reg);
1181 break;
1182 case ARC_HBA_TYPE_C0x00000003:
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_HIGH0xC4, sc->sc_ccb_phys_hi);
1190 arc_write(sc, ARC_RC_INB_POSTQ_LOW0xC0, reg);
1191 break;
1192 case ARC_HBA_TYPE_D0x00000004:
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_POSTQUEUE256;
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_POSTQUEUE256;
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),(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (((sc->
sc_requests)->adm_map)), (sc->cmdQ_ptr_offset), (sizeof
(struct arc_HBD_Msgu)), (0x01 | 0x04))
1213 sc->cmdQ_ptr_offset, ARC_MAX_CMDQ_PTR_LEN,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (((sc->
sc_requests)->adm_map)), (sc->cmdQ_ptr_offset), (sizeof
(struct arc_HBD_Msgu)), (0x01 | 0x04))
1214 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (((sc->
sc_requests)->adm_map)), (sc->cmdQ_ptr_offset), (sizeof
(struct arc_HBD_Msgu)), (0x01 | 0x04))
;
1215 arc_write(sc, ARC_RD_INB_WRITE_PTR0x1018, postq_index);
1216 break;
1217 }
1218 if (xs->flags & SCSI_POLL0x00002) {
1219 if (arc_complete(sc, ccb, xs->timeout) != 0) {
1220 xs->error = XS_DRIVER_STUFFUP2;
1221 scsi_done(xs);
1222 }
1223 }
1224 splx(s)spllower(s);
1225}
1226
1227int
1228arc_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,(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (dmap)
, (xs->data), (xs->datalen), (((void *)0)), ((xs->flags
& 0x00001) ? 0x0001 : 0x0000))
1245 xs->data, xs->datalen, NULL,(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (dmap)
, (xs->data), (xs->datalen), (((void *)0)), ((xs->flags
& 0x00001) ? 0x0001 : 0x0000))
1246 (xs->flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK)(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (dmap)
, (xs->data), (xs->datalen), (((void *)0)), ((xs->flags
& 0x00001) ? 0x0001 : 0x0000))
;
1247 if (error != 0) {
1248 printf("%s: error %d loading dmamap\n", DEVNAME(sc)((sc)->sc_dev.dv_xname), 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)((__uint32_t)((1<<24) | 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))((__uint32_t)((u_int32_t)(addr >> 32)));
1258 sge->sg_lo_addr = htole32((u_int32_t)addr)((__uint32_t)((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,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (dmap)
, (0), (dmap->dm_mapsize), ((xs->flags & 0x00800) ?
0x01 : 0x04))
1266 (xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_PREREAD :(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (dmap)
, (0), (dmap->dm_mapsize), ((xs->flags & 0x00800) ?
0x01 : 0x04))
1267 BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (dmap)
, (0), (dmap->dm_mapsize), ((xs->flags & 0x00800) ?
0x01 : 0x04))
;
1268
1269 return (0);
1270}
1271
1272void
1273arc_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,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (ccb->
ccb_dmamap), (0), (ccb->ccb_dmamap->dm_mapsize), ((xs->
flags & 0x00800) ? 0x02 : 0x08))
1280 ccb->ccb_dmamap->dm_mapsize, (xs->flags & SCSI_DATA_IN) ?(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (ccb->
ccb_dmamap), (0), (ccb->ccb_dmamap->dm_mapsize), ((xs->
flags & 0x00800) ? 0x02 : 0x08))
1281 BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (ccb->
ccb_dmamap), (0), (ccb->ccb_dmamap->dm_mapsize), ((xs->
flags & 0x00800) ? 0x02 : 0x08))
;
1282 bus_dmamap_unload(sc->sc_dmat, ccb->ccb_dmamap)(*(sc->sc_dmat)->_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_SELTIMEOUT0xf0:
1297 case ARC_MSG_STATUS_ABORTED0xf1:
1298 case ARC_MSG_STATUS_INIT_FAIL0xf2:
1299 xs->status = SCSI_OK0x00;
1300 xs->error = XS_SELTIMEOUT3;
1301 break;
1302
1303 case SCSI_CHECK0x02:
1304 bzero(&xs->sense, sizeof(xs->sense))__builtin_bzero((&xs->sense), (sizeof(xs->sense)));
1305 bcopy(cmd->sense_data, &xs->sense,
1306 min(ARC_MSG_SENSELEN15, sizeof(xs->sense)));
1307 xs->sense.error_code = SSD_ERRCODE_VALID0x80 | 0x70;
1308 xs->status = SCSI_CHECK0x02;
1309 xs->error = XS_SENSE1;
1310 xs->resid = 0;
1311 break;
1312
1313 default:
1314 /* unknown device status */
1315 xs->error = XS_BUSY5; /* try again later? */
1316 xs->status = SCSI_BUSY0x08;
1317 break;
1318 }
1319 } else {
1320 xs->status = SCSI_OK0x00;
1321 xs->error = XS_NOERROR0;
1322 xs->resid = 0;
1323 }
1324
1325 scsi_done(xs);
1326}
1327
1328int
1329arc_complete(struct arc_softc *sc, struct arc_ccb *nccb, int timeout)
1330{
1331 struct arc_ccb *ccb = NULL((void *)0);
1332 char *kva = ARC_DMA_KVA(sc->sc_requests)((void *)(sc->sc_requests)->adm_kva);
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_A0x00000001:
1343 reg = arc_read(sc, ARC_RA_REPLY_QUEUE0x0044);
1344 error = (reg & ARC_RA_REPLY_QUEUE_ERR(1<<28))? 1:0;
1345 break;
1346 case ARC_HBA_TYPE_C0x00000003:
1347 reg = arc_read(sc, ARC_RC_OUTB_REPLYQ_LOW0xC8);
1348 error = (reg & ARC_RC_REPLY_QUEUE_ERR1);
1349 break;
1350 case ARC_HBA_TYPE_D0x00000004:
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)) {
1355Loop0:
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_PTR0x1070, doneq_index);
1364 }
1365 error = (reg & ARC_RD_REPLY_QUEUE_ERR1);
1366 break;
1367 }
1368 if (reg == 0xffffffff) {
1369 if (timeout-- == 0) {
1370 return (1);
1371 }
1372 delay(1000)(*delay_func)(1000);
1373 continue;
1374 }
1375
1376 switch(sc->sc_adp_type) {
1377 case ARC_HBA_TYPE_A0x00000001:
1378 cmd = (struct arc_io_cmd *)(kva +
1379 ((reg << ARC_RA_REPLY_QUEUE_ADDR_SHIFT5) -
1380 ARC_DMA_DVA(sc->sc_requests)((sc->sc_requests)->adm_map->dm_segs[0].ds_addr)));
1381 break;
1382 case ARC_HBA_TYPE_C0x00000003:
1383 case ARC_HBA_TYPE_D0x00000004:
1384 cmd = (struct arc_io_cmd *)(kva + ((reg & 0xFFFFFFE0) -
1385 ARC_DMA_DVA(sc->sc_requests)((sc->sc_requests)->adm_map->dm_segs[0].ds_addr)));
1386 break;
1387 }
1388 ccb = cmd->ccb;
1389
1390 bus_dmamap_sync(sc->sc_dmat, ARC_DMA_MAP(sc->sc_requests),(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (((sc->
sc_requests)->adm_map)), (ccb->cmd_dma_offset), (512), (
0x01 | 0x04))
1391 ccb->cmd_dma_offset, ARC_MAX_IOCMDLEN,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (((sc->
sc_requests)->adm_map)), (ccb->cmd_dma_offset), (512), (
0x01 | 0x04))
1392 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (((sc->
sc_requests)->adm_map)), (ccb->cmd_dma_offset), (512), (
0x01 | 0x04))
;
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
1401void
1402arc_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_A0x00000001:
1408 int_mask = arc_read(sc, ARC_RA_INTRMASK0x0034);
1409 int_mask &= ~(ARC_RA_INTRMASK_POSTQUEUE(1<<3) |
1410 ARC_RA_INTRMASK_DOORBELL(1<<2) | ARC_RA_INTRMASK_MSG0(1<<0));
1411 arc_write(sc, ARC_RA_INTRMASK0x0034, int_mask);
1412 break;
1413 case ARC_HBA_TYPE_C0x00000003:
1414 int_mask = arc_read(sc, ARC_RC_INTR_MASK0x34);
1415 int_mask &= ~(ARC_RC_INTR_MASK_POSTQUEUE(1<<3) |
1416 ARC_RC_INTR_MASK_DOORBELL(1<<2) | ARC_RC_INTR_MASK_UTILITY_A(1<<0));
1417 arc_write(sc, ARC_RC_INTR_MASK0x34, int_mask);
1418 break;
1419 case ARC_HBA_TYPE_D0x00000004:
1420 int_mask = arc_read(sc, ARC_RD_INTR_ENABLE0x20C);
1421 int_mask |= ARC_RD_INTR_ENABLE_ALL0x00001010;
1422 arc_write(sc, ARC_RD_INTR_ENABLE0x20C, int_mask);
1423 break;
1424 }
1425}
1426
1427void
1428arc_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_A0x00000001:
1434 int_mask = arc_read(sc, ARC_RA_INTRMASK0x0034);
1435 int_mask |= ARC_RA_INTR_MASK_ALL0x1F;
1436 arc_write(sc, ARC_RA_INTRMASK0x0034, int_mask);
1437 break;
1438 case ARC_HBA_TYPE_C0x00000003:
1439 int_mask = arc_read(sc, ARC_RC_INTR_MASK0x34);
1440 int_mask |= ARC_RC_INTR_MASK_ALL0x0000000D;
1441 arc_write(sc, ARC_RC_INTR_MASK0x34, int_mask);
1442 break;
1443 case ARC_HBA_TYPE_D0x00000004:
1444 int_mask = arc_read(sc, ARC_RD_INTR_ENABLE0x20C);
1445 int_mask &= ~ARC_RD_INTR_ENABLE_ALL0x00001010;
1446 arc_write(sc, ARC_RD_INTR_ENABLE0x20C, ARC_RD_INTR_DISABLE_ALL0x00000000);
1447 break;
1448 }
1449}
1450
1451int
1452arc_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_A0x00000001:
1463 memtype = pci_mapreg_type(sc->sc_pc, sc->sc_tag, ARC_RA_PCI_BAR0x10);
1464 if (pci_mapreg_map(pa, ARC_RA_PCI_BAR0x10, memtype, 0, &sc->sc_iot,
1465 &sc->sc_ioh, NULL((void *)0), &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_C0x00000003:
1472 memtype = pci_mapreg_type(sc->sc_pc, sc->sc_tag, ARC_RC_PCI_BAR0x14);
1473 if (pci_mapreg_map(pa, ARC_RC_PCI_BAR0x14, memtype, 0, &sc->sc_iot,
1474 &sc->sc_ioh, NULL((void *)0), &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_D0x00000004:
1481 memtype = pci_mapreg_type(sc->sc_pc, sc->sc_tag, ARC_RD_PCI_BAR0x10);
1482 if (pci_mapreg_map(pa, ARC_RD_PCI_BAR0x10, memtype, 0, &sc->sc_iot,
1483 &sc->sc_ioh, NULL((void *)0), &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_BIO0x6,
1498 arc_intr, sc, DEVNAME(sc)((sc)->sc_dev.dv_xname));
1499 if (sc->sc_ih == NULL((void *)0)) {
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
1507unmap:
1508 bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
1509 sc->sc_ios = 0;
1510 return (1);
1511}
1512
1513void
1514arc_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
1521int
1522arc_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_ADDR10x001c, ARC_RA_OUTB_ADDR1_FIRMWARE_OK(1<<31),
1529 ARC_RA_OUTB_ADDR1_FIRMWARE_OK(1<<31)) != 0) {
1530 printf("%s: timeout waiting for firmware ok\n", DEVNAME(sc)((sc)->sc_dev.dv_xname));
1531 return (1);
1532 }
1533
1534 if (arc_msg0(sc, ARC_RA_INB_MSG0_GET_CONFIG(0x00000001)) != 0) {
1535 printf("%s: timeout waiting for get config\n", DEVNAME(sc)((sc)->sc_dev.dv_xname));
1536 return (1);
1537 }
1538
1539 arc_read_region(sc, ARC_RA_MSGBUF0x0a00, &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)((__uint32_t)(fwinfo.signature)) != ARC_FWINFO_SIGNATURE_GET_CONFIG(0x87974060)) {
1545 printf("%s: invalid firmware info from iop\n", DEVNAME(sc)((sc)->sc_dev.dv_xname));
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)((__uint32_t)(fwinfo.request_len)) != ARC_MAX_IOCMDLEN512) {
1567 printf("%s: unexpected request frame size (%d != %d)\n",
1568 DEVNAME(sc)((sc)->sc_dev.dv_xname), letoh32(fwinfo.request_len)((__uint32_t)(fwinfo.request_len)), ARC_MAX_IOCMDLEN512);
1569 return (1);
1570 }
1571
1572 sc->sc_req_count = letoh32(fwinfo.queue_len)((__uint32_t)(fwinfo.queue_len));
1573
1574 if (arc_msg0(sc, ARC_RA_INB_MSG0_START_BGRB(0x00000006)) != 0) {
1575 printf("%s: timeout waiting to start bg rebuild\n",
1576 DEVNAME(sc)((sc)->sc_dev.dv_xname));
1577 return (1);
1578 }
1579
1580 /* clear doorbell buffer */
1581 ob_doorbell = arc_read(sc, ARC_RA_OUTB_DOORBELL0x002c);
1582 arc_write(sc, ARC_RA_OUTB_DOORBELL0x002c, ob_doorbell);
1583 arc_write(sc, ARC_RA_INB_DOORBELL0x0020, ARC_RA_INB_DOORBELL_READ_OK(1<<1));
1584
1585 printf("%s: %d ports, %dMB SDRAM, firmware %s\n",
1586 DEVNAME(sc)((sc)->sc_dev.dv_xname), letoh32(fwinfo.sata_ports)((__uint32_t)(fwinfo.sata_ports)),
1587 letoh32(fwinfo.sdram_size)((__uint32_t)(fwinfo.sdram_size)), string);
1588
1589 return (0);
1590}
1591
1592int
1593arc_chipB_firmware(struct arc_softc *sc)
1594{
1595 if (arc_wait_eq(sc, ARC_RB_IOP2DRV_DOORBELL0x00020408,
1596 ARC_RA_OUTB_ADDR1_FIRMWARE_OK(1<<31),
1597 ARC_RA_OUTB_ADDR1_FIRMWARE_OK(1<<31)) != 0) {
1598 printf("%s: timeout waiting for firmware ok\n", DEVNAME(sc)((sc)->sc_dev.dv_xname));
1599 return (1);
1600 }
1601
1602 return (1);
1603}
1604
1605int
1606arc_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_MSGADDR10xBC, ARC_RC_OUTB_MSG_FIRMWARE_OK0x80000000,
1613 ARC_RC_OUTB_MSG_FIRMWARE_OK0x80000000) != 0) {
1614 printf("%s: timeout waiting for firmware ok\n", DEVNAME(sc)((sc)->sc_dev.dv_xname));
1615 return (1);
1616 }
1617
1618 if (arc_msg0(sc, ARC_RC_INB_MSG0_GET_CONFIG(0x00000001)) != 0) {
1619 printf("%s: timeout waiting for get config\n", DEVNAME(sc)((sc)->sc_dev.dv_xname));
1620 return (1);
1621 }
1622
1623 arc_read_region(sc, ARC_RC_MSG_RWBUF0x2200, &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)((__uint32_t)(fwinfo.signature)) != ARC_FWINFO_SIGNATURE_GET_CONFIG(0x87974060)) {
1629 printf("%s: invalid firmware info from iop\n", DEVNAME(sc)((sc)->sc_dev.dv_xname));
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)((__uint32_t)(fwinfo.request_len)) != ARC_MAX_IOCMDLEN512) {
1651 printf("%s: unexpected request frame size (%d != %d)\n",
1652 DEVNAME(sc)((sc)->sc_dev.dv_xname), letoh32(fwinfo.request_len)((__uint32_t)(fwinfo.request_len)), ARC_MAX_IOCMDLEN512);
1653 return (1);
1654 }
1655
1656 sc->sc_req_count = letoh32(fwinfo.queue_len)((__uint32_t)(fwinfo.queue_len));
1657
1658 if (arc_msg0(sc, ARC_RC_INB_MSG0_START_BGRB(0x00000006)) != 0) {
1659 printf("%s: timeout waiting to start bg rebuild\n",
1660 DEVNAME(sc)((sc)->sc_dev.dv_xname));
1661 return (1);
1662 }
1663
1664 /* clear doorbell buffer */
1665 ob_doorbell = arc_read(sc, ARC_RC_OUTB_DOORBELL0x9C);
1666 arc_write(sc, ARC_RC_OUTB_DOORBELL_CLR0xA0, ob_doorbell);
1667 arc_write(sc, ARC_RC_INB_DOORBELL0x20, ARC_RC_D2I_DATA_READ_OK0x00000004);
1668
1669 printf("%s: %d ports, %dMB SDRAM, firmware %s\n",
1670 DEVNAME(sc)((sc)->sc_dev.dv_xname), letoh32(fwinfo.sata_ports)((__uint32_t)(fwinfo.sata_ports)),
1671 letoh32(fwinfo.sdram_size)((__uint32_t)(fwinfo.sdram_size)), string);
1672
1673 return (0);
1674}
1675
1676int
1677arc_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_MSGADDR10x424, ARC_RD_OUTB_MSG_FIRMWARE_OK0x80000000,
1684 ARC_RD_OUTB_MSG_FIRMWARE_OK0x80000000) != 0) {
1685 printf("%s: timeout waiting for firmware ok\n", DEVNAME(sc)((sc)->sc_dev.dv_xname));
1686 return (1);
1687 }
1688
1689 if ((arc_read(sc, ARC_RD_OUTB_DOORBELL0x480) & ARC_RD_I2D_MESSAGE_CMD_DONE0x02000000))
1690 arc_write(sc, ARC_RD_OUTB_DOORBELL0x480, ARC_RD_I2D_MESSAGE_CMD_DONE_CLEAR0x02000000);
1691
1692 if (arc_msg0(sc, ARC_RD_INB_MSG0_GET_CONFIG(0x00000001)) != 0) {
1693 printf("%s: timeout waiting for get config\n", DEVNAME(sc)((sc)->sc_dev.dv_xname));
1694 return (1);
1695 }
1696
1697 arc_read_region(sc, ARC_RD_MSG_RWBUF0x2200, &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)((__uint32_t)(fwinfo.signature)) != ARC_FWINFO_SIGNATURE_GET_CONFIG(0x87974060)) {
1703 printf("%s: invalid firmware info from iop\n", DEVNAME(sc)((sc)->sc_dev.dv_xname));
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)((__uint32_t)(fwinfo.request_len)) != ARC_MAX_IOCMDLEN512) {
1725 printf("%s: unexpected request frame size (%d != %d)\n",
1726 DEVNAME(sc)((sc)->sc_dev.dv_xname), letoh32(fwinfo.request_len)((__uint32_t)(fwinfo.request_len)), ARC_MAX_IOCMDLEN512);
1727 return (1);
1728 }
1729
1730 sc->sc_req_count = letoh32(fwinfo.queue_len)((__uint32_t)(fwinfo.queue_len)) - 1;
1731
1732 if (arc_msg0(sc, ARC_RD_INB_MSG0_START_BGRB(0x00000006)) != 0) {
1733 printf("%s: timeout waiting to start bg rebuild\n",
1734 DEVNAME(sc)((sc)->sc_dev.dv_xname));
1735 return (1);
1736 }
1737
1738 /* clear doorbell buffer */
1739 ob_doorbell = arc_read(sc, ARC_RD_OUTB_DOORBELL0x480);
1740 arc_write(sc, ARC_RD_OUTB_DOORBELL_CLR0x480, ob_doorbell);
1741 arc_write(sc, ARC_RD_INB_DOORBELL0x460, ARC_RD_D2I_DATA_READ_OK0x00000002);
1742
1743 printf("%s: %d ports, %dMB SDRAM, firmware %s\n",
1744 DEVNAME(sc)((sc)->sc_dev.dv_xname), letoh32(fwinfo.sata_ports)((__uint32_t)(fwinfo.sata_ports)),
1745 letoh32(fwinfo.sdram_size)((__uint32_t)(fwinfo.sdram_size)), string);
1746
1747 return (0);
1748}
1749
1750void
1751arc_stop_bgrb_proc(struct arc_softc *sc)
1752{
1753 switch(sc->sc_adp_type) {
1754 case ARC_HBA_TYPE_A0x00000001:
1755 if (arc_msg0(sc, ARC_RA_INB_MSG0_STOP_BGRB(0x00000004)) != 0)
1756 printf("%s: timeout waiting to stop bg rebuild\n",
1757 DEVNAME(sc)((sc)->sc_dev.dv_xname));
1758 break;
1759 case ARC_HBA_TYPE_C0x00000003:
1760 if (arc_msg0(sc, ARC_RC_INB_MSG0_STOP_BGRB(0x00000004)) != 0)
1761 printf("%s: timeout waiting to stop bg rebuild\n",
1762 DEVNAME(sc)((sc)->sc_dev.dv_xname));
1763 break;
1764 case ARC_HBA_TYPE_D0x00000004:
1765 if (arc_msg0(sc, ARC_RD_INB_MSG0_STOP_BGRB(0x00000004)) != 0)
1766 printf("%s: timeout waiting to stop bg rebuild\n",
1767 DEVNAME(sc)((sc)->sc_dev.dv_xname));
1768 break;
1769 }
1770}
1771
1772void
1773arc_flush_cache(struct arc_softc *sc)
1774{
1775 switch(sc->sc_adp_type) {
1776 case ARC_HBA_TYPE_A0x00000001:
1777 if (arc_msg0(sc, ARC_RA_INB_MSG0_FLUSH_CACHE(0x00000005)) != 0)
1778 printf("%s: timeout waiting to flush cache\n",
1779 DEVNAME(sc)((sc)->sc_dev.dv_xname));
1780 break;
1781 case ARC_HBA_TYPE_C0x00000003:
1782 if (arc_msg0(sc, ARC_RC_INB_MSG0_FLUSH_CACHE(0x00000005)) != 0)
1783 printf("%s: timeout waiting to flush cache\n",
1784 DEVNAME(sc)((sc)->sc_dev.dv_xname));
1785 break;
1786 case ARC_HBA_TYPE_D0x00000004:
1787 if (arc_msg0(sc, ARC_RD_INB_MSG0_FLUSH_CACHE(0x00000005)) != 0)
1788 printf("%s: timeout waiting to flush cache\n",
1789 DEVNAME(sc)((sc)->sc_dev.dv_xname));
1790 break;
1791 }
1792}
1793
1794void
1795arc_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_A0x00000001:
1803 arc_write(sc, ARC_RA_MSGBUF0x0a00, ARC_FWINFO_SIGNATURE_SET_CONFIG(0x87974063));
1804 arc_write(sc, ARC_RA_MSGBUF0x0a00+1, ccb_phys_hi);
1805 arc_msg0(sc, ARC_RA_INB_MSG0_SET_CONFIG(0x00000002));
1806 break;
1807 case ARC_HBA_TYPE_C0x00000003:
1808 arc_write(sc, ARC_RC_MSG_RWBUF0x2200, ARC_FWINFO_SIGNATURE_SET_CONFIG(0x87974063));
1809 arc_write(sc, ARC_RC_MSG_RWBUF0x2200+1, ccb_phys_hi);
1810 arc_msg0(sc, ARC_RC_INB_MSG0_SET_CONFIG(0x00000002));
1811 break;
1812 case ARC_HBA_TYPE_D0x00000004:
1813 phbdmu = sc->pmu;
1814 phbdmu->postq_index = 0;
1815 phbdmu->doneq_index = 0x40FF;
1816 arc_write(sc, ARC_RD_MSG_RWBUF0x2200, ARC_FWINFO_SIGNATURE_SET_CONFIG(0x87974063));
1817 arc_write(sc, ARC_RD_MSG_RWBUF0x2200+4, ccb_phys_hi);
1818 arc_write(sc, ARC_RD_MSG_RWBUF0x2200+8, sc->postQ_buffer);
1819 arc_write(sc, ARC_RD_MSG_RWBUF0x2200+12, sc->doneQ_buffer);
1820 arc_write(sc, ARC_RD_MSG_RWBUF0x2200+16, 0x100);
1821 arc_msg0(sc, ARC_RD_INB_MSG0_SET_CONFIG(0x00000002));
1822 break;
1823 }
1824}
1825
1826#if NBIO1 > 0
1827int
1828arc_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(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct bioc_inq) & 0x1fff) << 16) | ((('B')) <<
8) | ((32)))
:
1836 error = arc_bio_inq(sc, (struct bioc_inq *)addr);
1837 break;
1838
1839 case BIOCVOL(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct bioc_vol) & 0x1fff) << 16) | ((('B')) <<
8) | ((34)))
:
1840 error = arc_bio_vol(sc, (struct bioc_vol *)addr);
1841 break;
1842
1843 case BIOCDISK(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct bioc_disk) & 0x1fff) << 16) | ((('B')) <<
8) | ((33)))
:
1844 error = arc_bio_disk(sc, (struct bioc_disk *)addr);
1845 break;
1846
1847 case BIOCALARM(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct bioc_alarm) & 0x1fff) << 16) | ((('B')) <<
8) | ((35)))
:
1848 error = arc_bio_alarm(sc, (struct bioc_alarm *)addr);
1849 break;
1850
1851 case BIOCBLINK(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct bioc_blink) & 0x1fff) << 16) | ((('B')) <<
8) | ((36)))
:
1852 error = arc_bio_blink(sc, (struct bioc_blink *)addr);
1853 break;
1854
1855 default:
1856 error = ENOTTY25;
1857 break;
1858 }
1859
1860 return (error);
1861}
1862
1863int
1864arc_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_SAENABLE0x01:
1874 case BIOC_SADISABLE0x00:
1875 request[0] = ARC_FW_SET_ALARM0x31;
1876 request[1] = (ba->ba_opcode == BIOC_SAENABLE0x01) ?
1877 ARC_FW_SET_ALARM_ENABLE0x01 : ARC_FW_SET_ALARM_DISABLE0x00;
1878 len = sizeof(request);
1879
1880 break;
1881
1882 case BIOC_SASILENCE0x02:
1883 request[0] = ARC_FW_MUTE_ALARM0x30;
1884 len = 1;
1885
1886 break;
1887
1888 case BIOC_GASTATUS0x03:
1889 /* system info is too big/ugly to deal with here */
1890 return (arc_bio_alarm_state(sc, ba));
1891
1892 default:
1893 return (EOPNOTSUPP45);
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_OK0x41:
1905 return (0);
1906 case ARC_FW_CMD_PASS_REQD0x4d:
1907 return (EPERM1);
1908 default:
1909 return (EIO5);
1910 }
1911}
1912
1913int
1914arc_bio_alarm_state(struct arc_softc *sc, struct bioc_alarm *ba)
1915{
1916 u_int8_t request = ARC_FW_SYSINFO0x23;
1917 struct arc_fw_sysinfo *sysinfo;
1918 int error = 0;
1919
1920 sysinfo = malloc(sizeof(struct arc_fw_sysinfo), M_TEMP127, M_WAITOK0x0001);
1921
1922 request = ARC_FW_SYSINFO0x23;
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
1934out:
1935 free(sysinfo, M_TEMP127, sizeof *sysinfo);
1936 return (error);
1937}
1938
1939
1940int
1941arc_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_TEMP127, M_WAITOK0x0001);
1952 volinfo = malloc(sizeof(struct arc_fw_volinfo), M_TEMP127, M_WAITOK0x0001);
1953
1954 arc_lock(sc);
1955
1956 request[0] = ARC_FW_SYSINFO0x23;
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_VOLINFO0x21;
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_PASSTHRU0x05) {
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)((sc)->sc_dev.dv_xname), sizeof(bi->bi_dev));
1990 bi->bi_novol = nvols;
1991 DPRINTF("%s: volume set number = %d\n", DEVNAME(sc), nvols);
1992out:
1993 arc_unlock(sc);
1994 free(volinfo, M_TEMP127, sizeof *volinfo);
1995 free(sysinfo, M_TEMP127, sizeof *sysinfo);
1996 return (error);
1997}
1998
1999int
2000arc_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_BLINK0x43;
2008 request[1] = ARC_FW_BLINK_ENABLE0x00;
2009
2010 switch (blink->bb_status) {
2011 case BIOC_SBUNBLINK0x00:
2012 sc->sc_ledmask &= ~(1 << blink->bb_target);
2013 break;
2014 case BIOC_SBBLINK0x01:
2015 sc->sc_ledmask |= (1 << blink->bb_target);
2016 break;
2017 default:
2018 return (EINVAL22);
2019 }
2020
2021 mask = htole32(sc->sc_ledmask)((__uint32_t)(sc->sc_ledmask));
2022 bcopy(&mask, &request[2], 4);
2023
2024 arc_lock(sc);
2025 error = arc_msgbuf(sc, request, sizeof(request), NULL((void *)0), 0, 0);
2026 arc_unlock(sc);
2027 if (error)
2028 return (EIO5);
2029
2030 return (0);
2031}
2032
2033int
2034arc_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_TEMP127, M_WAITOK0x0001);
2043
2044 request[0] = ARC_FW_SYSINFO0x23;
2045 error = arc_msgbuf(sc, request, 1, sysinfo,
5
Calling 'arc_msgbuf'
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_VOLINFO0x21;
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_PASSTHRU0x05)
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_PASSTHRU0x05) {
2073 error = ENODEV19;
2074 goto out;
2075 }
2076
2077out:
2078 free(sysinfo, M_TEMP127, sizeof *sysinfo);
2079 return (error);
2080}
2081
2082int
2083arc_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_TEMP127, M_WAITOK0x0001);
2094
2095 arc_lock(sc);
2096 error = arc_bio_getvol(sc, bv->bv_volid, volinfo);
4
Calling 'arc_bio_getvol'
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)((__uint32_t)(volinfo->volume_status));
2106 if (status == 0x0) {
2107 if (letoh32(volinfo->fail_mask)((__uint32_t)(volinfo->fail_mask)) == 0x0)
2108 bv->bv_status = BIOC_SVONLINE0x00;
2109 else
2110 bv->bv_status = BIOC_SVDEGRADED0x02;
2111 } else if (status & ARC_FW_VOL_STATUS_NEED_REGEN(1<<7))
2112 bv->bv_status = BIOC_SVDEGRADED0x02;
2113 else if (status & ARC_FW_VOL_STATUS_FAILED(1<<1))
2114 bv->bv_status = BIOC_SVOFFLINE0x01;
2115 else if (status & ARC_FW_VOL_STATUS_INITTING(1<<0)) {
2116 bv->bv_status = BIOC_SVBUILDING0x03;
2117 bv->bv_percent = letoh32(volinfo->progress)((__uint32_t)(volinfo->progress)) / 10;
2118 } else if (status & ARC_FW_VOL_STATUS_REBUILDING(1<<3)) {
2119 bv->bv_status = BIOC_SVREBUILD0x05;
2120 bv->bv_percent = letoh32(volinfo->progress)((__uint32_t)(volinfo->progress)) / 10;
2121 }
2122
2123 blocks = (u_int64_t)letoh32(volinfo->capacity2)((__uint32_t)(volinfo->capacity2)) << 32;
2124 blocks += (u_int64_t)letoh32(volinfo->capacity)((__uint32_t)(volinfo->capacity));
2125 bv->bv_size = blocks * ARC_BLOCKSIZE512; /* XXX */
2126
2127 switch (volinfo->raid_level) {
2128 case ARC_FW_VOL_RAIDLEVEL_00x00:
2129 bv->bv_level = 0;
2130 break;
2131 case ARC_FW_VOL_RAIDLEVEL_10x01:
2132 bv->bv_level = 1;
2133 break;
2134 case ARC_FW_VOL_RAIDLEVEL_30x02:
2135 bv->bv_level = 3;
2136 break;
2137 case ARC_FW_VOL_RAIDLEVEL_50x03:
2138 bv->bv_level = 5;
2139 break;
2140 case ARC_FW_VOL_RAIDLEVEL_60x04:
2141 bv->bv_level = 6;
2142 break;
2143 case ARC_FW_VOL_RAIDLEVEL_PASSTHRU0x05:
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((void *)0)) {
2153 dev = sc_link->device_softc;
2154 strlcpy(bv->bv_dev, dev->dv_xname, sizeof(bv->bv_dev));
2155 }
2156
2157out:
2158 free(volinfo, M_TEMP127, sizeof *volinfo);
2159 return (error);
2160}
2161
2162int
2163arc_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_TEMP127, M_WAITOK0x0001);
2177 raidinfo = malloc(sizeof(struct arc_fw_raidinfo), M_TEMP127, M_WAITOK0x0001);
2178 diskinfo = malloc(sizeof(struct arc_fw_diskinfo), M_TEMP127, M_WAITOK0x0001);
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_RAIDINFO0x20;
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 = ENODEV19;
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_SDOFFLINE0x01;
2207 strlcpy(bd->bd_vendor, "disk missing", sizeof(bd->bd_vendor));
2208 goto out;
2209 }
2210
2211 request[0] = ARC_FW_DISKINFO0x22;
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 firmware 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_SDONLINE0x00;
2232 blocks = (u_int64_t)letoh32(diskinfo->capacity2)((__uint32_t)(diskinfo->capacity2)) << 32;
2233 blocks += (u_int64_t)letoh32(diskinfo->capacity)((__uint32_t)(diskinfo->capacity));
2234 bd->bd_size = blocks * ARC_BLOCKSIZE512; /* 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
2245out:
2246 arc_unlock(sc);
2247 free(diskinfo, M_TEMP127, sizeof *diskinfo);
2248 free(raidinfo, M_TEMP127, sizeof *raidinfo);
2249 free(volinfo, M_TEMP127, sizeof *volinfo);
2250 return (error);
2251}
2252
2253u_int8_t
2254arc_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
2267int
2268arc_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_MAXLEN124];
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;
6
'write_ok' declared without an initial value
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) {
7
'Default' branch taken. Execution continues on line 2299
2286 case ARC_HBA_TYPE_A0x00000001:
2287 reg = arc_read(sc, ARC_RA_OUTB_DOORBELL0x002c);
2288 break;
2289 case ARC_HBA_TYPE_C0x00000003:
2290 reg = arc_read(sc, ARC_RC_OUTB_DOORBELL0x9C);
2291 break;
2292 case ARC_HBA_TYPE_D0x00000004:
2293 reg = arc_read(sc, ARC_RD_OUTB_DOORBELL0x480);
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_TEMP127, M_WAITOK0x0001);
2301
2302 rlen = sizeof(struct arc_fw_bufhdr) + rbuflen + 1; /* 1 for cksum */
2303 rbuf = malloc(rlen, M_TEMP127, M_WAITOK0x0001);
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)((__uint16_t)(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
7.1
'read_ok' is 1
) && wdone
7.2
'wdone' is < 'wlen'
< wlen) {
8
Taking true branch
2318 bzero(rwbuf, sizeof(rwbuf))__builtin_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)((sc)->sc_dev.dv_xname), 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) {
9
'Default' branch taken. Execution continues on line 2363
2332 case ARC_HBA_TYPE_A0x00000001:
2333 /* copy the chunk to the hw */
2334 arc_write(sc, ARC_RA_IOC_WBUF_LEN0x0e00, rwlen);
2335 arc_write_region(sc, ARC_RA_IOC_WBUF0x0e04, rwbuf,
2336 sizeof(rwbuf));
2337
2338 /* say we have a buffer for the hw */
2339 arc_write(sc, ARC_RA_INB_DOORBELL0x0020,
2340 ARC_RA_INB_DOORBELL_WRITE_OK(1<<0));
2341 break;
2342 case ARC_HBA_TYPE_C0x00000003:
2343 /* copy the chunk to the hw */
2344 arc_write(sc, ARC_RC_MSG_WBUF_LEN0x2000, rwlen);
2345 arc_write_region(sc, ARC_RC_MSG_WBUF0x2004, rwbuf,
2346 sizeof(rwbuf));
2347
2348 /* say we have a buffer for the hw */
2349 arc_write(sc, ARC_RC_INB_DOORBELL0x20,
2350 ARC_RC_D2I_DATA_WRITE_OK0x00000002);
2351 break;
2352 case ARC_HBA_TYPE_D0x00000004:
2353 /* copy the chunk to the hw */
2354 arc_write(sc, ARC_RD_MSG_WBUF_LEN0x2000, rwlen);
2355 arc_write_region(sc, ARC_RD_MSG_WBUF0x2004, rwbuf,
2356 sizeof(rwbuf));
2357
2358 /* say we have a buffer for the hw */
2359 arc_write(sc, ARC_RD_INB_DOORBELL0x460,
2360 ARC_RD_D2I_DATA_WRITE_OK0x00000001);
2361 break;
2362 }
2363 wdone += rwlen;
2364 }
2365
2366 if (rptr == NULL((void *)0))
10
Assuming 'rptr' is not equal to NULL
11
Taking false branch
2367 goto out;
2368
2369 switch(sc->sc_adp_type) {
12
'Default' branch taken. Execution continues on line 2394
2370 case ARC_HBA_TYPE_A0x00000001:
2371 while ((reg = arc_read(sc, ARC_RA_OUTB_DOORBELL0x002c)) == 0)
2372 arc_wait(sc);
2373 arc_write(sc, ARC_RA_OUTB_DOORBELL0x002c, reg);
2374 write_ok = reg & ARC_RA_OUTB_DOORBELL_WRITE_OK(1<<0);
2375 read_ok = reg & ARC_RA_OUTB_DOORBELL_READ_OK(1<<1);
2376 break;
2377 case ARC_HBA_TYPE_C0x00000003:
2378 while ((reg = arc_read(sc, ARC_RC_OUTB_DOORBELL0x9C)) == 0)
2379 arc_wait(sc);
2380 arc_write(sc, ARC_RC_OUTB_DOORBELL_CLR0xA0, reg);
2381 write_ok = reg & ARC_RC_I2D_DATA_WRITE_OK0x00000002;
2382 read_ok = reg & ARC_RC_I2D_DATA_READ_OK0x00000004;
2383 break;
2384 case ARC_HBA_TYPE_D0x00000004:
2385 while ((reg = arc_read(sc, ARC_RD_OUTB_DOORBELL0x480)) == 0)
2386 arc_wait(sc);
2387 arc_write(sc, ARC_RD_OUTB_DOORBELL_CLR0x480, reg);
2388 write_ok = reg & ARC_RD_I2D_DATA_WRITE_OK0x00000001;
2389 read_ok = reg & ARC_RD_I2D_DATA_READ_OK0x00000002;
2390 break;
2391 }
2392 DNPRINTF(ARC_D_DB, "%s: reg: 0x%08x\n", DEVNAME(sc), reg);
2393
2394 if ((write_ok) && rdone < rlen) {
13
Branch condition evaluates to a garbage value
2395 switch(sc->sc_adp_type) {
2396 case ARC_HBA_TYPE_A0x00000001:
2397 rwlen = arc_read(sc, ARC_RA_IOC_RBUF_LEN0x0f00);
2398 break;
2399 case ARC_HBA_TYPE_C0x00000003:
2400 rwlen = arc_read(sc, ARC_RC_MSG_RBUF_LEN0x2100);
2401 break;
2402 case ARC_HBA_TYPE_D0x00000004:
2403 rwlen = arc_read(sc, ARC_RD_MSG_RBUF_LEN0x2100);
2404 break;
2405 }
2406 if (rwlen > sizeof(rwbuf)) {
2407 DNPRINTF(ARC_D_DB, "%s: rwlen too big\n",
2408 DEVNAME(sc));
2409 error = EIO5;
2410 goto out;
2411 }
2412
2413 switch(sc->sc_adp_type) {
2414 case ARC_HBA_TYPE_A0x00000001:
2415 arc_read_region(sc, ARC_RA_IOC_RBUF0x0f04, rwbuf,
2416 sizeof(rwbuf));
2417 arc_write(sc, ARC_RA_INB_DOORBELL0x0020,
2418 ARC_RA_INB_DOORBELL_READ_OK(1<<1));
2419 break;
2420 case ARC_HBA_TYPE_C0x00000003:
2421 arc_read_region(sc, ARC_RC_MSG_RBUF0x2104, rwbuf,
2422 sizeof(rwbuf));
2423 arc_write(sc, ARC_RC_INB_DOORBELL0x20,
2424 ARC_RC_I2D_DATA_READ_OK0x00000004);
2425 break;
2426 case ARC_HBA_TYPE_D0x00000004:
2427 arc_read_region(sc, ARC_RD_MSG_RBUF0x2104, rwbuf,
2428 sizeof(rwbuf));
2429 arc_write(sc, ARC_RD_INB_DOORBELL0x460,
2430 ARC_RD_I2D_DATA_READ_OK0x00000002);
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)((sc)->sc_dev.dv_xname),
2439 rwlen, rdone, rwlen + rdone, rlen);
2440 if (arcdebug & ARC_D_DB) {
2441 printf("%s: read:", DEVNAME(sc)((sc)->sc_dev.dv_xname));
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 = EIO5;
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)((__uint16_t)(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))__builtin_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 = EIO5;
2482 goto out;
2483 }
2484
2485 if (bufhdr->len != htole16(rbuflen)((__uint16_t)(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 = EIO5;
2496 goto out;
2497 }
2498
2499out:
2500 free(wbuf, M_TEMP127, 0);
2501 free(rbuf, M_TEMP127, 0);
2502
2503 return (error);
2504}
2505
2506void
2507arc_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()splraise(0x6);
2514 switch(sc->sc_adp_type) {
2515 case ARC_HBA_TYPE_A0x00000001:
2516 int_mask = arc_read(sc, ARC_RA_INTRMASK0x0034) | ARC_RA_INTRMASK_DOORBELL(1<<2);
2517 arc_write(sc, ARC_RA_INTRMASK0x0034, int_mask);
2518 break;
2519 case ARC_HBA_TYPE_C0x00000003:
2520 int_mask = arc_read(sc, ARC_RC_INTR_MASK0x34) | ARC_RC_INTR_MASK_DOORBELL(1<<2);
2521 arc_write(sc, ARC_RC_INTR_MASK0x34, int_mask);
2522 break;
2523 case ARC_HBA_TYPE_D0x00000004:
2524 int_mask = arc_read(sc, ARC_RD_INTR_ENABLE0x20C) & ~ARC_RD_INTR_ENABLE_DOORBELL0x00001000;
2525 arc_write(sc, ARC_RD_INTR_ENABLE0x20C, int_mask);
2526 break;
2527 }
2528 sc->sc_talking = 1;
2529 splx(s)spllower(s);
2530}
2531
2532void
2533arc_unlock(struct arc_softc *sc)
2534{
2535 int s;
2536 u_int32_t int_mask;
2537
2538 s = splbio()splraise(0x6);
2539 sc->sc_talking = 0;
2540 switch(sc->sc_adp_type) {
2541 case ARC_HBA_TYPE_A0x00000001:
2542 int_mask = arc_read(sc, ARC_RA_INTRMASK0x0034) & ~ARC_RA_INTRMASK_DOORBELL(1<<2);
2543 arc_write(sc, ARC_RA_INTRMASK0x0034, int_mask);
2544 break;
2545 case ARC_HBA_TYPE_C0x00000003:
2546 int_mask = arc_read(sc, ARC_RC_INTR_MASK0x34) & ~ARC_RC_INTR_MASK_DOORBELL(1<<2);
2547 arc_write(sc, ARC_RC_INTR_MASK0x34, int_mask);
2548 break;
2549 case ARC_HBA_TYPE_D0x00000004:
2550 int_mask = arc_read(sc, ARC_RD_INTR_ENABLE0x20C) | ARC_RD_INTR_ENABLE_DOORBELL0x00001000;
2551 arc_write(sc, ARC_RD_INTR_ENABLE0x20C, int_mask);
2552 break;
2553 }
2554 splx(s)spllower(s);
2555 rw_exit_write(&sc->sc_lock);
2556}
2557
2558void
2559arc_wait(struct arc_softc *sc)
2560{
2561 int error, s;
2562 u_int32_t int_mask;
2563
2564 s = splbio()splraise(0x6);
2565 switch(sc->sc_adp_type) {
2566 case ARC_HBA_TYPE_A0x00000001:
2567 int_mask = arc_read(sc, ARC_RA_INTRMASK0x0034) & ~ARC_RA_INTRMASK_DOORBELL(1<<2);
2568 arc_write(sc, ARC_RA_INTRMASK0x0034, int_mask);
2569 error = tsleep_nsec(sc, PWAIT32, "arcdb", SEC_TO_NSEC(1));
2570 if (error == EWOULDBLOCK35) {
2571 int_mask = arc_read(sc, ARC_RA_INTRMASK0x0034) | ARC_RA_INTRMASK_DOORBELL(1<<2);
2572 arc_write(sc, ARC_RA_INTRMASK0x0034, int_mask);
2573 }
2574 break;
2575 case ARC_HBA_TYPE_C0x00000003:
2576 int_mask = arc_read(sc, ARC_RC_INTR_MASK0x34) & ~ARC_RC_INTR_MASK_DOORBELL(1<<2);
2577 arc_write(sc, ARC_RC_INTR_MASK0x34, int_mask);
2578 error = tsleep_nsec(sc, PWAIT32, "arcdb", SEC_TO_NSEC(1));
2579 if (error == EWOULDBLOCK35) {
2580 int_mask = arc_read(sc, ARC_RC_INTR_MASK0x34) | ARC_RC_INTR_MASK_DOORBELL(1<<2);
2581 arc_write(sc, ARC_RC_INTR_MASK0x34, int_mask);
2582 }
2583 break;
2584 case ARC_HBA_TYPE_D0x00000004:
2585 int_mask = arc_read(sc, ARC_RD_INTR_ENABLE0x20C) | ARC_RD_INTR_ENABLE_DOORBELL0x00001000;
2586 arc_write(sc, ARC_RD_INTR_ENABLE0x20C, int_mask);
2587 error = tsleep_nsec(sc, PWAIT32, "arcdb", SEC_TO_NSEC(1));
2588 if (error == EWOULDBLOCK35) {
2589 int_mask = arc_read(sc, ARC_RD_INTR_ENABLE0x20C) & ~ARC_RD_INTR_ENABLE_DOORBELL0x00001000;
2590 arc_write(sc, ARC_RD_INTR_ENABLE0x20C, int_mask);
2591 }
2592 break;
2593 }
2594 splx(s)spllower(s);
2595}
2596
2597#ifndef SMALL_KERNEL
2598void
2599arc_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_TEMP127, 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, PWAIT32, "arcspew", SEC_TO_NSEC(2));
2615
2616 bzero(&bi, sizeof(bi))__builtin_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)((sc)->sc_dev.dv_xname));
2620 return;
2621 }
2622 sc->sc_nsensors = bi.bi_novol;
2623
2624 sc->sc_sensors = mallocarray(sc->sc_nsensors, sizeof(struct ksensor),
2625 M_DEVBUF2, M_WAITOK0x0001 | M_ZERO0x0008);
2626
2627 strlcpy(sc->sc_sensordev.xname, DEVNAME(sc)((sc)->sc_dev.dv_xname),
2628 sizeof(sc->sc_sensordev.xname));
2629
2630 for (i = 0; i < sc->sc_nsensors; i++) {
2631 bzero(&bv, sizeof(bv))__builtin_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((void *)0)) {
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
2656bad:
2657 free(sc->sc_sensors, M_DEVBUF2,
2658 sc->sc_nsensors * sizeof(struct ksensor));
2659}
2660
2661void
2662arc_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++) {
1
Assuming 'i' is < field 'sc_nsensors'
2
Loop condition is true. Entering loop body
2669 bzero(&bv, sizeof(bv))__builtin_bzero((&bv), (sizeof(bv)));
2670 bv.bv_volid = i;
2671 if (arc_bio_vol(sc, &bv)) {
3
Calling 'arc_bio_vol'
2672 sc->sc_sensors[i].flags = SENSOR_FINVALID0x0001;
2673 return;
2674 }
2675
2676 switch(bv.bv_status) {
2677 case BIOC_SVOFFLINE0x01:
2678 sc->sc_sensors[i].value = SENSOR_DRIVE_FAIL9;
2679 sc->sc_sensors[i].status = SENSOR_S_CRIT;
2680 break;
2681
2682 case BIOC_SVDEGRADED0x02:
2683 sc->sc_sensors[i].value = SENSOR_DRIVE_PFAIL10;
2684 sc->sc_sensors[i].status = SENSOR_S_WARN;
2685 break;
2686
2687 case BIOC_SVSCRUB0x04:
2688 case BIOC_SVONLINE0x00:
2689 sc->sc_sensors[i].value = SENSOR_DRIVE_ONLINE4;
2690 sc->sc_sensors[i].status = SENSOR_S_OK;
2691 break;
2692
2693 case BIOC_SVINVALID0xff:
2694 /* FALLTHROUGH */
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
2705u_int32_t
2706arc_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_READ0x01);
2712 v = bus_space_read_4(sc->sc_iot, sc->sc_ioh, r)((sc->sc_iot)->read_4((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
2719void
2720arc_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_READ0x01);
2724 bus_space_read_raw_region_4(sc->sc_iot, sc->sc_ioh, r, buf, len)((sc->sc_iot)->read_region_4((sc->sc_ioh), (r), (u_int32_t
*)(buf), (len) >> 2))
;
2725}
2726
2727void
2728arc_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)((sc->sc_iot)->write_4((sc->sc_ioh), (r), (v)));
2733 bus_space_barrier(sc->sc_iot, sc->sc_ioh, r, 4,
2734 BUS_SPACE_BARRIER_WRITE0x02);
2735}
2736
2737void
2738arc_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)((sc->sc_iot)->write_region_4((sc->sc_ioh), (r), (const
u_int32_t *)(buf), (len) >> 2))
;
2741 bus_space_barrier(sc->sc_iot, sc->sc_ioh, r, len,
2742 BUS_SPACE_BARRIER_WRITE0x02);
2743}
2744
2745int
2746arc_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)(*delay_func)(1000);
2758 }
2759
2760 return (1);
2761}
2762
2763int
2764arc_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)(*delay_func)(1000);
2776 }
2777
2778 return (1);
2779}
2780
2781int
2782arc_msg0(struct arc_softc *sc, u_int32_t m)
2783{
2784 switch(sc->sc_adp_type) {
2785 case ARC_HBA_TYPE_A0x00000001:
2786 /* post message */
2787 arc_write(sc, ARC_RA_INB_MSG00x0010, m);
2788 /* wait for the fw to do it */
2789 if (arc_wait_eq(sc, ARC_RA_INTRSTAT0x0030, ARC_RA_INTRSTAT_MSG0(1<<0),
2790 ARC_RA_INTRSTAT_MSG0(1<<0)) != 0)
2791 return (1);
2792
2793 /* ack it */
2794 arc_write(sc, ARC_RA_INTRSTAT0x0030, ARC_RA_INTRSTAT_MSG0(1<<0));
2795 break;
2796
2797 case ARC_HBA_TYPE_C0x00000003:
2798 /* post message */
2799 arc_write(sc, ARC_RC_INB_MSGADDR00xB0, m);
2800 arc_write(sc, ARC_RC_INB_DOORBELL0x20, ARC_RC_D2I_MSG_CMD_DONE0x08);
2801 /* wait for the fw to do it */
2802 if (arc_wait_eq(sc, ARC_RC_OUTB_DOORBELL0x9C, ARC_RC_I2D_MSG_CMD_DONE0x08,
2803 ARC_RC_I2D_MSG_CMD_DONE0x08) != 0)
2804 return (1);
2805
2806 /* ack it */
2807 arc_write(sc, ARC_RC_OUTB_DOORBELL_CLR0xA0, ARC_RC_I2D_MSG_CMD_DONE_CLR0x08);
2808 break;
2809
2810 case ARC_HBA_TYPE_D0x00000004:
2811 /* post message */
2812 arc_write(sc, ARC_RD_INB_MSGADDR00x400, m);
2813 /* wait for the fw to do it */
2814 if (arc_wait_eq(sc, ARC_RD_OUTB_DOORBELL0x480, ARC_RD_I2D_MSG_CMD_DONE0x2000000,
2815 ARC_RD_I2D_MSG_CMD_DONE0x2000000) != 0)
2816 return (1);
2817
2818 /* ack it */
2819 arc_write(sc, ARC_RD_OUTB_DOORBELL_CLR0x480, ARC_RD_I2D_MSG_CMD_DONE_CLR0x2000000);
2820 break;
2821 }
2822 return (0);
2823}
2824
2825struct arc_dmamem *
2826arc_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_DEVBUF2, M_NOWAIT0x0002 | M_ZERO0x0008);
2832 if (adm == NULL((void *)0))
2833 return (NULL((void *)0));
2834
2835 adm->adm_size = size;
2836
2837 if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), (size
), (1), (size), (0), (0x0001 | 0x0002), (&adm->adm_map
))
2838 BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &adm->adm_map)(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), (size
), (1), (size), (0), (0x0001 | 0x0002), (&adm->adm_map
))
!= 0)
2839 goto admfree;
2840
2841 if (bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, &adm->adm_seg,(*(sc->sc_dmat)->_dmamem_alloc)((sc->sc_dmat), (size
), ((1 << 12)), (0), (&adm->adm_seg), (1), (&
nsegs), (0x0001 | 0x1000))
2842 1, &nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO)(*(sc->sc_dmat)->_dmamem_alloc)((sc->sc_dmat), (size
), ((1 << 12)), (0), (&adm->adm_seg), (1), (&
nsegs), (0x0001 | 0x1000))
!= 0)
2843 goto destroy;
2844
2845 if (bus_dmamem_map(sc->sc_dmat, &adm->adm_seg, nsegs, size,(*(sc->sc_dmat)->_dmamem_map)((sc->sc_dmat), (&adm
->adm_seg), (nsegs), (size), (&adm->adm_kva), (0x0001
))
2846 &adm->adm_kva, BUS_DMA_NOWAIT)(*(sc->sc_dmat)->_dmamem_map)((sc->sc_dmat), (&adm
->adm_seg), (nsegs), (size), (&adm->adm_kva), (0x0001
))
!= 0)
2847 goto free;
2848
2849 if (bus_dmamap_load(sc->sc_dmat, adm->adm_map, adm->adm_kva, size,(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (adm->
adm_map), (adm->adm_kva), (size), (((void *)0)), (0x0001))
2850 NULL, BUS_DMA_NOWAIT)(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (adm->
adm_map), (adm->adm_kva), (size), (((void *)0)), (0x0001))
!= 0)
2851 goto unmap;
2852
2853 return (adm);
2854
2855unmap:
2856 bus_dmamem_unmap(sc->sc_dmat, adm->adm_kva, size)(*(sc->sc_dmat)->_dmamem_unmap)((sc->sc_dmat), (adm->
adm_kva), (size))
;
2857free:
2858 bus_dmamem_free(sc->sc_dmat, &adm->adm_seg, 1)(*(sc->sc_dmat)->_dmamem_free)((sc->sc_dmat), (&
adm->adm_seg), (1))
;
2859destroy:
2860 bus_dmamap_destroy(sc->sc_dmat, adm->adm_map)(*(sc->sc_dmat)->_dmamap_destroy)((sc->sc_dmat), (adm
->adm_map))
;
2861admfree:
2862 free(adm, M_DEVBUF2, sizeof *adm);
2863
2864 return (NULL((void *)0));
2865}
2866
2867void
2868arc_dmamem_free(struct arc_softc *sc, struct arc_dmamem *adm)
2869{
2870 bus_dmamap_unload(sc->sc_dmat, adm->adm_map)(*(sc->sc_dmat)->_dmamap_unload)((sc->sc_dmat), (adm
->adm_map))
;
2871 bus_dmamem_unmap(sc->sc_dmat, adm->adm_kva, adm->adm_size)(*(sc->sc_dmat)->_dmamem_unmap)((sc->sc_dmat), (adm->
adm_kva), (adm->adm_size))
;
2872 bus_dmamem_free(sc->sc_dmat, &adm->adm_seg, 1)(*(sc->sc_dmat)->_dmamem_free)((sc->sc_dmat), (&
adm->adm_seg), (1))
;
2873 bus_dmamap_destroy(sc->sc_dmat, adm->adm_map)(*(sc->sc_dmat)->_dmamap_destroy)((sc->sc_dmat), (adm
->adm_map))
;
2874 free(adm, M_DEVBUF2, sizeof *adm);
2875}
2876
2877int
2878arc_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){ ((&sc->sc_ccb_free)->slh_first) = ((void *)0); };
2885 mtx_init(&sc->sc_ccb_mtx, IPL_BIO)do { (void)(((void *)0)); (void)(0); __mtx_init((&sc->
sc_ccb_mtx), ((((0x6)) > 0x0 && ((0x6)) < 0x9) ?
0x9 : ((0x6)))); } while (0)
;
2886
2887 size = sizeof(struct arc_ccb) * ARCMSR_MAX_CCB_COUNT264;
2888 sc->sc_ccbs = malloc(size, M_DEVBUF2, M_WAITOK0x0001 | M_ZERO0x0008);
2889
2890 len = ARC_IO_CMD_LEN512+32;
2891 size = ARCMSR_MAX_CCB_COUNT264 * len;
2892 if(sc->sc_adp_type == ARC_HBA_TYPE_D0x00000004)
2893 size += sizeof(struct arc_HBD_Msgu);
2894 sc->sc_requests = arc_dmamem_alloc(sc, size);
2895 if (sc->sc_requests == NULL((void *)0)) {
2896 printf("%s: unable to allocate ccb dmamem\n", DEVNAME(sc)((sc)->sc_dev.dv_xname));
2897 goto free_ccbs;
2898 }
2899 cmd = ARC_DMA_KVA(sc->sc_requests)((void *)(sc->sc_requests)->adm_kva);
2900
2901 for (i = 0; i < ARCMSR_MAX_CCB_COUNT264; i++) {
2902 ccb = &sc->sc_ccbs[i];
2903
2904 if (bus_dmamap_create(sc->sc_dmat, MAXPHYS, ARC_SGL_MAXLEN,(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), ((64
* 1024)), (38), ((64 * 1024)), (0), (0), (&ccb->ccb_dmamap
))
2905 MAXPHYS, 0, 0, &ccb->ccb_dmamap)(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), ((64
* 1024)), (38), ((64 * 1024)), (0), (0), (&ccb->ccb_dmamap
))
!= 0) {
2906 printf("%s: unable to create dmamap for ccb %d\n",
2907 DEVNAME(sc)((sc)->sc_dev.dv_xname), 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)((sc->sc_requests)->adm_map->dm_segs[0].ds_addr) +
2916 ccb->cmd_dma_offset);
2917 if ((sc->sc_adp_type != ARC_HBA_TYPE_C0x00000003) &&
2918 (sc->sc_adp_type != ARC_HBA_TYPE_D0x00000004))
2919 ccb->ccb_cmd_post = ccb->ccb_cmd_post >>
2920 ARC_RA_POST_QUEUE_ADDR_SHIFT5;
2921 arc_put_ccb(sc, ccb);
2922 }
2923 sc->sc_ccb_phys_hi = (u_int64_t)ARC_DMA_DVA(sc->sc_requests)((sc->sc_requests)->adm_map->dm_segs[0].ds_addr) >> 32;
2924 if(sc->sc_adp_type == ARC_HBA_TYPE_D0x00000004) {
2925 sc->postQ_buffer = ARC_DMA_DVA(sc->sc_requests)((sc->sc_requests)->adm_map->dm_segs[0].ds_addr) +
2926 (ARCMSR_MAX_CCB_COUNT264 * len);
2927 sc->doneQ_buffer = sc->postQ_buffer + (sizeof(struct InBound_SRB) *
2928 ARCMSR_MAX_HBD_POSTQUEUE256);
2929 sc->pmu = (struct arc_HBD_Msgu *)&cmd[ARCMSR_MAX_CCB_COUNT264 * len];
2930 sc->cmdQ_ptr_offset = ARCMSR_MAX_CCB_COUNT264 * 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
2938free_maps:
2939 while ((ccb = arc_get_ccb(sc)) != NULL((void *)0))
2940 bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap)(*(sc->sc_dmat)->_dmamap_destroy)((sc->sc_dmat), (ccb
->ccb_dmamap))
;
2941 arc_dmamem_free(sc, sc->sc_requests);
2942
2943free_ccbs:
2944 free(sc->sc_ccbs, M_DEVBUF2, sizeof(struct arc_ccb) * ARCMSR_MAX_CCB_COUNT264);
2945
2946 return (1);
2947}
2948
2949void
2950arc_free_ccb_src(struct arc_softc *sc)
2951{
2952 struct arc_ccb *ccb;
2953
2954 while ((ccb = arc_get_ccb(sc)) != NULL((void *)0))
2955 bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap)(*(sc->sc_dmat)->_dmamap_destroy)((sc->sc_dmat), (ccb
->ccb_dmamap))
;
2956 arc_dmamem_free(sc, sc->sc_requests);
2957 free(sc->sc_ccbs, M_DEVBUF2, 0);
2958}
2959
2960struct arc_ccb *
2961arc_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)((&sc->sc_ccb_free)->slh_first);
2967 if (ccb != NULL((void *)0))
2968 SLIST_REMOVE_HEAD(&sc->sc_ccb_free, ccb_link)do { (&sc->sc_ccb_free)->slh_first = (&sc->sc_ccb_free
)->slh_first->ccb_link.sle_next; } while (0)
;
2969 mtx_leave(&sc->sc_ccb_mtx);
2970
2971 return (ccb);
2972}
2973
2974void
2975arc_put_ccb(struct arc_softc *sc, struct arc_ccb *ccb)
2976{
2977 ccb->ccb_xs = NULL((void *)0);
2978 bzero(ccb->ccb_cmd, ARC_IO_CMD_LEN)__builtin_bzero((ccb->ccb_cmd), (512+32));
2979 mtx_enter(&sc->sc_ccb_mtx);
2980 SLIST_INSERT_HEAD(&sc->sc_ccb_free, ccb, ccb_link)do { (ccb)->ccb_link.sle_next = (&sc->sc_ccb_free)->
slh_first; (&sc->sc_ccb_free)->slh_first = (ccb); }
while (0)
;
2981 mtx_leave(&sc->sc_ccb_mtx);
2982}