1 /* $NetBSD: ips.c,v 1.7 2024/01/08 18:38:25 chs Exp $ */
2 /* $OpenBSD: ips.c,v 1.113 2016/08/14 04:08:03 dlg Exp $ */
3
4 /*-
5 * Copyright (c) 2017 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 /*
31 * Copyright (c) 2006, 2007, 2009 Alexander Yurchenko <grange@openbsd.org>
32 *
33 * Permission to use, copy, modify, and distribute this software for any
34 * purpose with or without fee is hereby granted, provided that the above
35 * copyright notice and this permission notice appear in all copies.
36 *
37 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
38 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
39 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
40 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
41 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
42 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
43 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
44 */
45
46 /*
47 * IBM (Adaptec) ServeRAID controllers driver.
48 */
49
50 #include <sys/cdefs.h>
51 __KERNEL_RCSID(0, "$NetBSD: ips.c,v 1.7 2024/01/08 18:38:25 chs Exp $");
52
53 #include "bio.h"
54
55 #include <sys/param.h>
56 #include <sys/systm.h>
57 #include <sys/device.h>
58 #include <sys/kernel.h>
59 #include <sys/queue.h>
60 #include <sys/buf.h>
61 #include <sys/endian.h>
62 #include <sys/conf.h>
63 #include <sys/malloc.h>
64 #include <sys/ioctl.h>
65 #include <sys/kthread.h>
66
67 #include <sys/bus.h>
68 #include <sys/intr.h>
69
70 #include <dev/scsipi/scsi_all.h>
71 #include <dev/scsipi/scsipi_all.h>
72 #include <dev/scsipi/scsi_disk.h>
73 #include <dev/scsipi/scsipi_disk.h>
74 #include <dev/scsipi/scsiconf.h>
75
76 #include <dev/biovar.h>
77 #include <dev/sysmon/sysmonvar.h>
78 #include <sys/envsys.h>
79
80 #include <dev/pci/pcireg.h>
81 #include <dev/pci/pcivar.h>
82 #include <dev/pci/pcidevs.h>
83
84 /* Debug levels */
85 #define IPS_D_ERR 0x0001 /* errors */
86 #define IPS_D_INFO 0x0002 /* information */
87 #define IPS_D_XFER 0x0004 /* transfers */
88
89 #ifdef IPS_DEBUG
90 #define DPRINTF(a, b) do { if (ips_debug & (a)) printf b; } while (0)
91 int ips_debug = IPS_D_ERR;
92 #else
93 #define DPRINTF(a, b)
94 #endif
95
96 #define IPS_MAXDRIVES 8
97 #define IPS_MAXCHANS 4
98 #define IPS_MAXTARGETS 16
99 #define IPS_MAXCHUNKS 16
100 #define IPS_MAXCMDS 128
101
102 #define IPS_MAXFER (64 * 1024)
103 #define IPS_MAXSGS 16
104 #define IPS_MAXCDB 12
105
106 #define IPS_SECSZ 512
107 #define IPS_NVRAMPGSZ 128
108 #define IPS_SQSZ (IPS_MAXCMDS * sizeof(u_int32_t))
109
110 #define IPS_TIMEOUT 60000 /* ms */
111
112 /* Command codes */
113 #define IPS_CMD_READ 0x02
114 #define IPS_CMD_WRITE 0x03
115 #define IPS_CMD_DCDB 0x04
116 #define IPS_CMD_GETADAPTERINFO 0x05
117 #define IPS_CMD_FLUSH 0x0a
118 #define IPS_CMD_REBUILDSTATUS 0x0c
119 #define IPS_CMD_SETSTATE 0x10
120 #define IPS_CMD_REBUILD 0x16
121 #define IPS_CMD_ERRORTABLE 0x17
122 #define IPS_CMD_GETDRIVEINFO 0x19
123 #define IPS_CMD_RESETCHAN 0x1a
124 #define IPS_CMD_DOWNLOAD 0x20
125 #define IPS_CMD_RWBIOSFW 0x22
126 #define IPS_CMD_READCONF 0x38
127 #define IPS_CMD_GETSUBSYS 0x40
128 #define IPS_CMD_CONFIGSYNC 0x58
129 #define IPS_CMD_READ_SG 0x82
130 #define IPS_CMD_WRITE_SG 0x83
131 #define IPS_CMD_DCDB_SG 0x84
132 #define IPS_CMD_EDCDB 0x95
133 #define IPS_CMD_EDCDB_SG 0x96
134 #define IPS_CMD_RWNVRAMPAGE 0xbc
135 #define IPS_CMD_GETVERINFO 0xc6
136 #define IPS_CMD_FFDC 0xd7
137 #define IPS_CMD_SG 0x80
138 #define IPS_CMD_RWNVRAM 0xbc
139
140 /* DCDB attributes */
141 #define IPS_DCDB_DATAIN 0x01 /* data input */
142 #define IPS_DCDB_DATAOUT 0x02 /* data output */
143 #define IPS_DCDB_XFER64K 0x08 /* 64K transfer */
144 #define IPS_DCDB_TIMO10 0x10 /* 10 secs timeout */
145 #define IPS_DCDB_TIMO60 0x20 /* 60 secs timeout */
146 #define IPS_DCDB_TIMO20M 0x30 /* 20 mins timeout */
147 #define IPS_DCDB_NOAUTOREQSEN 0x40 /* no auto request sense */
148 #define IPS_DCDB_DISCON 0x80 /* disconnect allowed */
149
150 /* Register definitions */
151 #define IPS_REG_HIS 0x08 /* host interrupt status */
152 #define IPS_REG_HIS_SCE 0x01 /* status channel enqueue */
153 #define IPS_REG_HIS_EN 0x80 /* enable interrupts */
154 #define IPS_REG_CCSA 0x10 /* command channel system address */
155 #define IPS_REG_CCC 0x14 /* command channel control */
156 #define IPS_REG_CCC_SEM 0x0008 /* semaphore */
157 #define IPS_REG_CCC_START 0x101a /* start command */
158 #define IPS_REG_SQH 0x20 /* status queue head */
159 #define IPS_REG_SQT 0x24 /* status queue tail */
160 #define IPS_REG_SQE 0x28 /* status queue end */
161 #define IPS_REG_SQS 0x2c /* status queue start */
162
163 #define IPS_REG_OIS 0x30 /* outbound interrupt status */
164 #define IPS_REG_OIS_PEND 0x0008 /* interrupt is pending */
165 #define IPS_REG_OIM 0x34 /* outbound interrupt mask */
166 #define IPS_REG_OIM_DS 0x0008 /* disable interrupts */
167 #define IPS_REG_IQP 0x40 /* inbound queue port */
168 #define IPS_REG_OQP 0x44 /* outbound queue port */
169
170 /* Status word fields */
171 #define IPS_STAT_ID(x) (((x) >> 8) & 0xff) /* command id */
172 #define IPS_STAT_BASIC(x) (((x) >> 16) & 0xff) /* basic status */
173 #define IPS_STAT_EXT(x) (((x) >> 24) & 0xff) /* ext status */
174 #define IPS_STAT_GSC(x) ((x) & 0x0f)
175
176 /* Basic status codes */
177 #define IPS_STAT_OK 0x00 /* success */
178 #define IPS_STAT_RECOV 0x01 /* recovered error */
179 #define IPS_STAT_INVOP 0x03 /* invalid opcode */
180 #define IPS_STAT_INVCMD 0x04 /* invalid command block */
181 #define IPS_STAT_INVPARM 0x05 /* invalid parameters block */
182 #define IPS_STAT_BUSY 0x08 /* busy */
183 #define IPS_STAT_CMPLERR 0x0c /* completed with error */
184 #define IPS_STAT_LDERR 0x0d /* logical drive error */
185 #define IPS_STAT_TIMO 0x0e /* timeout */
186 #define IPS_STAT_PDRVERR 0x0f /* physical drive error */
187
188 /* Extended status codes */
189 #define IPS_ESTAT_SELTIMO 0xf0 /* select timeout */
190 #define IPS_ESTAT_OURUN 0xf2 /* over/underrun */
191 #define IPS_ESTAT_HOSTRST 0xf7 /* host reset */
192 #define IPS_ESTAT_DEVRST 0xf8 /* device reset */
193 #define IPS_ESTAT_RECOV 0xfc /* recovered error */
194 #define IPS_ESTAT_CKCOND 0xff /* check condition */
195
196 #define IPS_IOSIZE 128 /* max space size to map */
197
198 /* Command frame */
199 struct ips_cmd {
200 u_int8_t code;
201 u_int8_t id;
202 u_int8_t drive;
203 u_int8_t sgcnt;
204 u_int32_t lba;
205 u_int32_t sgaddr;
206 u_int16_t seccnt;
207 u_int8_t seg4g;
208 u_int8_t esg;
209 u_int32_t ccsar;
210 u_int32_t cccr;
211 };
212
213 /* Direct CDB (SCSI pass-through) frame */
214 struct ips_dcdb {
215 u_int8_t device;
216 u_int8_t attr;
217 u_int16_t datalen;
218 u_int32_t sgaddr;
219 u_int8_t cdblen;
220 u_int8_t senselen;
221 u_int8_t sgcnt;
222 u_int8_t __reserved1;
223 u_int8_t cdb[IPS_MAXCDB];
224 u_int8_t sense[64];
225 u_int8_t status;
226 u_int8_t __reserved2[3];
227 };
228
229 /* Scatter-gather array element */
230 struct ips_sg {
231 u_int32_t addr;
232 u_int32_t size;
233 };
234
235 /* Command block */
236 struct ips_cmdb {
237 struct ips_cmd cmd;
238 struct ips_dcdb dcdb;
239 struct ips_sg sg[IPS_MAXSGS];
240 };
241
242 /* Data frames */
243 struct ips_adapterinfo {
244 u_int8_t drivecnt;
245 u_int8_t miscflag;
246 u_int8_t sltflag;
247 u_int8_t bstflag;
248 u_int8_t pwrchgcnt;
249 u_int8_t wrongaddrcnt;
250 u_int8_t unidentcnt;
251 u_int8_t nvramdevchgcnt;
252 u_int8_t firmware[8];
253 u_int8_t bios[8];
254 u_int32_t drivesize[IPS_MAXDRIVES];
255 u_int8_t cmdcnt;
256 u_int8_t maxphysdevs;
257 u_int16_t flashrepgmcnt;
258 u_int8_t defunctdiskcnt;
259 u_int8_t rebuildflag;
260 u_int8_t offdrivecnt;
261 u_int8_t critdrivecnt;
262 u_int16_t confupdcnt;
263 u_int8_t blkflag;
264 u_int8_t __reserved;
265 u_int16_t deaddisk[IPS_MAXCHANS][IPS_MAXTARGETS];
266 };
267
268 struct ips_driveinfo {
269 u_int8_t drivecnt;
270 u_int8_t __reserved[3];
271 struct ips_drive {
272 u_int8_t id;
273 u_int8_t __reserved;
274 u_int8_t raid;
275 u_int8_t state;
276 #define IPS_DS_FREE 0x00
277 #define IPS_DS_OFFLINE 0x02
278 #define IPS_DS_ONLINE 0x03
279 #define IPS_DS_DEGRADED 0x04
280 #define IPS_DS_SYS 0x06
281 #define IPS_DS_CRS 0x24
282
283 u_int32_t seccnt;
284 } drive[IPS_MAXDRIVES];
285 };
286
287 struct ips_conf {
288 u_int8_t ldcnt;
289 u_int8_t day;
290 u_int8_t month;
291 u_int8_t year;
292 u_int8_t initid[4];
293 u_int8_t hostid[12];
294 u_int8_t time[8];
295 u_int32_t useropt;
296 u_int16_t userfield;
297 u_int8_t rebuildrate;
298 u_int8_t __reserved1;
299
300 struct ips_hw {
301 u_int8_t board[8];
302 u_int8_t cpu[8];
303 u_int8_t nchantype;
304 u_int8_t nhostinttype;
305 u_int8_t compression;
306 u_int8_t nvramtype;
307 u_int32_t nvramsize;
308 } hw;
309
310 struct ips_ld {
311 u_int16_t userfield;
312 u_int8_t state;
313 u_int8_t raidcacheparam;
314 u_int8_t chunkcnt;
315 u_int8_t stripesize;
316 u_int8_t params;
317 u_int8_t __reserved;
318 u_int32_t size;
319
320 struct ips_chunk {
321 u_int8_t channel;
322 u_int8_t target;
323 u_int16_t __reserved;
324 u_int32_t startsec;
325 u_int32_t seccnt;
326 } chunk[IPS_MAXCHUNKS];
327 } ld[IPS_MAXDRIVES];
328
329 struct ips_dev {
330 u_int8_t initiator;
331 u_int8_t params;
332 u_int8_t miscflag;
333 u_int8_t state;
334 #define IPS_DVS_STANDBY 0x01
335 #define IPS_DVS_REBUILD 0x02
336 #define IPS_DVS_SPARE 0x04
337 #define IPS_DVS_MEMBER 0x08
338 #define IPS_DVS_ONLINE 0x80
339 #define IPS_DVS_READY (IPS_DVS_STANDBY | IPS_DVS_ONLINE)
340
341 u_int32_t seccnt;
342 u_int8_t devid[28];
343 } dev[IPS_MAXCHANS][IPS_MAXTARGETS];
344
345 u_int8_t reserved[512];
346 };
347
348 struct ips_rblstat {
349 u_int8_t __unknown[20];
350 struct {
351 u_int8_t __unknown[4];
352 u_int32_t total;
353 u_int32_t remain;
354 } ld[IPS_MAXDRIVES];
355 };
356
357 struct ips_pg5 {
358 u_int32_t signature;
359 u_int8_t __reserved1;
360 u_int8_t slot;
361 u_int16_t type;
362 u_int8_t bioshi[4];
363 u_int8_t bioslo[4];
364 u_int16_t __reserved2;
365 u_int8_t __reserved3;
366 u_int8_t os;
367 u_int8_t driverhi[4];
368 u_int8_t driverlo[4];
369 u_int8_t __reserved4[100];
370 };
371
372 struct ips_info {
373 struct ips_adapterinfo adapter;
374 struct ips_driveinfo drive;
375 struct ips_conf conf;
376 struct ips_rblstat rblstat;
377 struct ips_pg5 pg5;
378 };
379
380 /* Command control block */
381 struct ips_softc;
382 struct ips_ccb {
383 struct ips_softc * c_sc; /* driver softc */
384 int c_id; /* command id */
385 int c_flags; /* SCSI_* flags */
386 enum {
387 IPS_CCB_FREE,
388 IPS_CCB_QUEUED,
389 IPS_CCB_DONE
390 } c_state; /* command state */
391
392 void * c_cmdbva; /* command block virt addr */
393 paddr_t c_cmdbpa; /* command block phys addr */
394 bus_dmamap_t c_dmam; /* data buffer DMA map */
395
396 struct scsipi_xfer * c_xfer; /* corresponding SCSI xfer */
397
398 u_int8_t c_stat; /* status byte copy */
399 u_int8_t c_estat; /* ext status byte copy */
400 int c_error; /* completion error */
401
402 void (*c_done)(struct ips_softc *, /* cmd done */
403 struct ips_ccb *); /* callback */
404
405 SLIST_ENTRY(ips_ccb) c_link; /* queue link */
406 };
407
408 /* CCB queue */
409 SLIST_HEAD(ips_ccbq, ips_ccb);
410
411 /* DMA-able chunk of memory */
412 struct dmamem {
413 bus_dma_tag_t dm_tag;
414 bus_dmamap_t dm_map;
415 bus_dma_segment_t dm_seg;
416 bus_size_t dm_size;
417 void * dm_vaddr;
418 #define dm_paddr dm_seg.ds_addr
419 };
420
421 struct ips_softc {
422 device_t sc_dev;
423
424 /* SCSI mid-layer connection. */
425 struct scsipi_adapter sc_adapt;
426
427 struct ips_pt {
428 struct scsipi_channel pt_chan;
429 int pt_nchan;
430 struct ips_softc * pt_sc;
431
432 int pt_proctgt;
433 char pt_procdev[16];
434 } sc_pt[IPS_MAXCHANS];
435
436 bus_space_tag_t sc_iot;
437 bus_space_handle_t sc_ioh;
438 bus_dma_tag_t sc_dmat;
439
440 const struct ips_chipset *sc_chip;
441
442 struct ips_info * sc_info;
443 struct dmamem sc_infom;
444
445 int sc_nunits;
446
447 struct dmamem sc_cmdbm;
448
449 struct ips_ccb * sc_ccb;
450 int sc_nccbs;
451 struct ips_ccbq sc_ccbq_free;
452 struct kmutex sc_ccb_mtx;
453
454 struct dmamem sc_sqm;
455 paddr_t sc_sqtail;
456 u_int32_t * sc_sqbuf;
457 int sc_sqidx;
458 };
459
460 int ips_match(device_t, cfdata_t, void *);
461 void ips_attach(device_t, device_t, void *);
462
463 void ips_scsi_cmd(struct ips_ccb *);
464 void ips_scsi_pt_cmd(struct scsipi_xfer *);
465 static void ips_scsipi_request(struct scsipi_channel *,
466 scsipi_adapter_req_t, void *);
467 int ips_scsi_ioctl(struct scsipi_channel *, u_long, void *,
468 int, struct proc *);
469
470 #if NBIO > 0
471 int ips_ioctl(device_t, u_long, void *);
472 int ips_ioctl_inq(struct ips_softc *, struct bioc_inq *);
473 int ips_ioctl_vol(struct ips_softc *, struct bioc_vol *);
474 int ips_ioctl_disk(struct ips_softc *, struct bioc_disk *);
475 int ips_ioctl_setstate(struct ips_softc *, struct bioc_setstate *);
476 #endif
477
478 int ips_load_xs(struct ips_softc *, struct ips_ccb *, struct scsipi_xfer *);
479 void ips_start_xs(struct ips_softc *, struct ips_ccb *, struct scsipi_xfer *);
480
481 int ips_cmd(struct ips_softc *, struct ips_ccb *);
482 int ips_poll(struct ips_softc *, struct ips_ccb *);
483 void ips_done(struct ips_softc *, struct ips_ccb *);
484 void ips_done_xs(struct ips_softc *, struct ips_ccb *);
485 void ips_done_pt(struct ips_softc *, struct ips_ccb *);
486 void ips_done_mgmt(struct ips_softc *, struct ips_ccb *);
487 int ips_error(struct ips_softc *, struct ips_ccb *);
488 int ips_error_xs(struct ips_softc *, struct ips_ccb *);
489 int ips_intr(void *);
490 void ips_timeout(void *);
491
492 int ips_getadapterinfo(struct ips_softc *, int);
493 int ips_getdriveinfo(struct ips_softc *, int);
494 int ips_getconf(struct ips_softc *, int);
495 int ips_getpg5(struct ips_softc *, int);
496
497 #if NBIO > 0
498 int ips_getrblstat(struct ips_softc *, int);
499 int ips_setstate(struct ips_softc *, int, int, int, int);
500 int ips_rebuild(struct ips_softc *, int, int, int, int, int);
501 #endif
502
503 void ips_copperhead_exec(struct ips_softc *, struct ips_ccb *);
504 void ips_copperhead_intren(struct ips_softc *);
505 int ips_copperhead_isintr(struct ips_softc *);
506 u_int32_t ips_copperhead_status(struct ips_softc *);
507
508 void ips_morpheus_exec(struct ips_softc *, struct ips_ccb *);
509 void ips_morpheus_intren(struct ips_softc *);
510 int ips_morpheus_isintr(struct ips_softc *);
511 u_int32_t ips_morpheus_status(struct ips_softc *);
512
513 struct ips_ccb *ips_ccb_alloc(struct ips_softc *, int);
514 void ips_ccb_free(struct ips_softc *, struct ips_ccb *, int);
515 struct ips_ccb *ips_ccb_get(struct ips_softc *);
516 void ips_ccb_put(struct ips_softc *, struct ips_ccb *);
517
518 int ips_dmamem_alloc(struct dmamem *, bus_dma_tag_t, bus_size_t);
519 void ips_dmamem_free(struct dmamem *);
520
521 extern struct cfdriver ips_cd;
522
523 CFATTACH_DECL_NEW(ips, sizeof(struct ips_softc),
524 ips_match, ips_attach, NULL, NULL);
525
526 static struct ips_ident {
527 pci_vendor_id_t vendor;
528 pci_product_id_t product;
529 } const ips_ids[] = {
530 { PCI_VENDOR_IBM, PCI_PRODUCT_IBM_SERVERAID },
531 { PCI_VENDOR_IBM, PCI_PRODUCT_IBM_SERVERAID4 },
532 { PCI_VENDOR_ADP2, PCI_PRODUCT_ADP2_SERVERAID }
533 };
534
535 static const struct ips_chipset {
536 enum {
537 IPS_CHIP_COPPERHEAD = 0,
538 IPS_CHIP_MORPHEUS
539 } ic_id;
540
541 int ic_bar;
542
543 void (*ic_exec)(struct ips_softc *, struct ips_ccb *);
544 void (*ic_intren)(struct ips_softc *);
545 int (*ic_isintr)(struct ips_softc *);
546 u_int32_t (*ic_status)(struct ips_softc *);
547 } ips_chips[] = {
548 {
549 IPS_CHIP_COPPERHEAD,
550 0x14,
551 ips_copperhead_exec,
552 ips_copperhead_intren,
553 ips_copperhead_isintr,
554 ips_copperhead_status
555 },
556 {
557 IPS_CHIP_MORPHEUS,
558 0x10,
559 ips_morpheus_exec,
560 ips_morpheus_intren,
561 ips_morpheus_isintr,
562 ips_morpheus_status
563 }
564 };
565
566 #define ips_exec(s, c) (s)->sc_chip->ic_exec((s), (c))
567 #define ips_intren(s) (s)->sc_chip->ic_intren((s))
568 #define ips_isintr(s) (s)->sc_chip->ic_isintr((s))
569 #define ips_status(s) (s)->sc_chip->ic_status((s))
570
571 static const char *ips_names[] = {
572 NULL,
573 NULL,
574 "II",
575 "onboard",
576 "onboard",
577 "3H",
578 "3L",
579 "4H",
580 "4M",
581 "4L",
582 "4Mx",
583 "4Lx",
584 "5i",
585 "5i",
586 "6M",
587 "6i",
588 "7t",
589 "7k",
590 "7M"
591 };
592
593 /* Lookup supported device table */
594 static const struct ips_ident *
ips_lookup(const struct pci_attach_args * pa)595 ips_lookup(const struct pci_attach_args *pa)
596 {
597 const struct ips_ident *imp;
598 int i;
599
600 for (i = 0, imp = ips_ids; i < __arraycount(ips_ids); i++, imp++) {
601 if (PCI_VENDOR(pa->pa_id) == imp->vendor &&
602 PCI_PRODUCT(pa->pa_id) == imp->product)
603 return imp;
604 }
605 return NULL;
606 }
607
608 int
ips_match(device_t parent,cfdata_t cfdata,void * aux)609 ips_match(device_t parent, cfdata_t cfdata, void *aux)
610 {
611 struct pci_attach_args *pa = aux;
612
613 if (ips_lookup(pa) != NULL)
614 return 1;
615
616 return 0;
617 }
618
619 void
ips_attach(device_t parent,device_t self,void * aux)620 ips_attach(device_t parent, device_t self, void *aux)
621 {
622 struct ips_softc *sc = device_private(self);
623 struct pci_attach_args *pa = aux;
624 struct ips_ccb ccb0;
625 struct ips_adapterinfo *ai;
626 struct ips_driveinfo *di;
627 struct ips_pg5 *pg5;
628 pcireg_t maptype;
629 bus_size_t iosize;
630 pci_intr_handle_t ih;
631 const char *intrstr;
632 int type, i;
633 struct scsipi_adapter *adapt;
634 struct scsipi_channel *chan;
635 char intrbuf[PCI_INTRSTR_LEN];
636
637 sc->sc_dev = self;
638 sc->sc_dmat = pa->pa_dmat;
639
640 /* Identify chipset */
641 if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_IBM_SERVERAID)
642 sc->sc_chip = &ips_chips[IPS_CHIP_COPPERHEAD];
643 else
644 sc->sc_chip = &ips_chips[IPS_CHIP_MORPHEUS];
645
646 /* Map registers */
647 // XXX check IPS_IOSIZE as old code used to do?
648 maptype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, sc->sc_chip->ic_bar);
649 if (pci_mapreg_map(pa, sc->sc_chip->ic_bar, maptype, 0, &sc->sc_iot,
650 &sc->sc_ioh, NULL, &iosize)) {
651 printf(": can't map regs\n");
652 return;
653 }
654
655 /* Allocate command buffer */
656 if (ips_dmamem_alloc(&sc->sc_cmdbm, sc->sc_dmat,
657 IPS_MAXCMDS * sizeof(struct ips_cmdb))) {
658 printf(": can't alloc cmd buffer\n");
659 goto fail1;
660 }
661
662 /* Allocate info buffer */
663 if (ips_dmamem_alloc(&sc->sc_infom, sc->sc_dmat,
664 sizeof(struct ips_info))) {
665 printf(": can't alloc info buffer\n");
666 goto fail2;
667 }
668 sc->sc_info = sc->sc_infom.dm_vaddr;
669 ai = &sc->sc_info->adapter;
670 di = &sc->sc_info->drive;
671 pg5 = &sc->sc_info->pg5;
672
673 /* Allocate status queue for the Copperhead chipset */
674 if (sc->sc_chip->ic_id == IPS_CHIP_COPPERHEAD) {
675 if (ips_dmamem_alloc(&sc->sc_sqm, sc->sc_dmat, IPS_SQSZ)) {
676 printf(": can't alloc status queue\n");
677 goto fail3;
678 }
679 sc->sc_sqtail = sc->sc_sqm.dm_paddr;
680 sc->sc_sqbuf = sc->sc_sqm.dm_vaddr;
681 sc->sc_sqidx = 0;
682 bus_space_write_4(sc->sc_iot, sc->sc_ioh, IPS_REG_SQS,
683 sc->sc_sqm.dm_paddr);
684 bus_space_write_4(sc->sc_iot, sc->sc_ioh, IPS_REG_SQE,
685 sc->sc_sqm.dm_paddr + IPS_SQSZ);
686 bus_space_write_4(sc->sc_iot, sc->sc_ioh, IPS_REG_SQH,
687 sc->sc_sqm.dm_paddr + sizeof(u_int32_t));
688 bus_space_write_4(sc->sc_iot, sc->sc_ioh, IPS_REG_SQT,
689 sc->sc_sqm.dm_paddr);
690 }
691
692 /* Bootstrap CCB queue */
693 sc->sc_nccbs = 1;
694 sc->sc_ccb = &ccb0;
695 bzero(&ccb0, sizeof(ccb0));
696 ccb0.c_cmdbva = sc->sc_cmdbm.dm_vaddr;
697 ccb0.c_cmdbpa = sc->sc_cmdbm.dm_paddr;
698 SLIST_INIT(&sc->sc_ccbq_free);
699 SLIST_INSERT_HEAD(&sc->sc_ccbq_free, &ccb0, c_link);
700 mutex_init(&sc->sc_ccb_mtx, MUTEX_DEFAULT, IPL_BIO);
701
702 /* Get adapter info */
703 if (ips_getadapterinfo(sc, XS_CTL_NOSLEEP)) {
704 printf(": can't get adapter info\n");
705 goto fail4;
706 }
707
708 /* Get logical drives info */
709 if (ips_getdriveinfo(sc, XS_CTL_NOSLEEP)) {
710 printf(": can't get ld info\n");
711 goto fail4;
712 }
713 sc->sc_nunits = di->drivecnt;
714
715 /* Get configuration */
716 if (ips_getconf(sc, XS_CTL_NOSLEEP)) {
717 printf(": can't get config\n");
718 goto fail4;
719 }
720
721 /* Read NVRAM page 5 for additional info */
722 (void)ips_getpg5(sc, XS_CTL_NOSLEEP);
723
724 /* Initialize CCB queue */
725 sc->sc_nccbs = ai->cmdcnt;
726 if ((sc->sc_ccb = ips_ccb_alloc(sc, sc->sc_nccbs)) == NULL) {
727 printf(": can't alloc ccb queue\n");
728 goto fail4;
729 }
730 SLIST_INIT(&sc->sc_ccbq_free);
731 for (i = 0; i < sc->sc_nccbs; i++)
732 SLIST_INSERT_HEAD(&sc->sc_ccbq_free,
733 &sc->sc_ccb[i], c_link);
734
735 /* Install interrupt handler */
736 if (pci_intr_map(pa, &ih)) {
737 printf(": can't map interrupt\n");
738 goto fail5;
739 }
740 intrstr = pci_intr_string(pa->pa_pc, ih, intrbuf, sizeof(intrbuf));
741 if (pci_intr_establish_xname(pa->pa_pc, ih, IPL_BIO, ips_intr, sc,
742 device_xname(sc->sc_dev)) == NULL) {
743 printf(": can't establish interrupt");
744 if (intrstr != NULL)
745 printf(" at %s", intrstr);
746 printf("\n");
747 goto fail5;
748 }
749 printf(": %s\n", intrstr);
750
751 /* Display adapter info */
752 device_printf(sc->sc_dev, "ServeRAID");
753 type = htole16(pg5->type);
754 if (type < sizeof(ips_names) / sizeof(ips_names[0]) && ips_names[type])
755 printf(" %s", ips_names[type]);
756 printf(", FW %c%c%c%c%c%c%c", ai->firmware[0], ai->firmware[1],
757 ai->firmware[2], ai->firmware[3], ai->firmware[4], ai->firmware[5],
758 ai->firmware[6]);
759 printf(", BIOS %c%c%c%c%c%c%c", ai->bios[0], ai->bios[1], ai->bios[2],
760 ai->bios[3], ai->bios[4], ai->bios[5], ai->bios[6]);
761 printf(", %d cmds, %d LD%s", sc->sc_nccbs, sc->sc_nunits,
762 (sc->sc_nunits == 1 ? "" : "s"));
763 printf("\n");
764
765 /*
766 * Attach to scsipi.
767 */
768 adapt = &sc->sc_adapt;
769 memset(adapt, 0, sizeof(*adapt));
770 adapt->adapt_dev = self;
771 adapt->adapt_nchannels = IPS_MAXCHANS;
772 if (sc->sc_nunits > 0)
773 adapt->adapt_openings = sc->sc_nccbs / sc->sc_nunits;
774 adapt->adapt_max_periph = adapt->adapt_openings;
775 adapt->adapt_request = ips_scsipi_request;
776 adapt->adapt_minphys = minphys;
777 adapt->adapt_ioctl = ips_scsi_ioctl;
778
779 /* For each channel attach SCSI pass-through bus */
780 for (i = 0; i < IPS_MAXCHANS; i++) {
781 struct ips_pt *pt;
782 int target, lastarget;
783
784 pt = &sc->sc_pt[i];
785 pt->pt_sc = sc;
786 pt->pt_nchan = i;
787 pt->pt_proctgt = -1;
788
789 /* Check if channel has any devices besides disks */
790 for (target = 0, lastarget = -1; target < IPS_MAXTARGETS;
791 target++) {
792 struct ips_dev *idev;
793 int dev_type;
794
795 idev = &sc->sc_info->conf.dev[i][target];
796 dev_type = idev->params & SID_TYPE;
797 if (idev->state && dev_type != T_DIRECT) {
798 lastarget = target;
799 if (type == T_PROCESSOR ||
800 type == T_ENCLOSURE)
801 /* remember enclosure address */
802 pt->pt_proctgt = target;
803 }
804 }
805 if (lastarget == -1)
806 continue;
807
808 chan = &pt->pt_chan;
809 memset(chan, 0, sizeof(*chan));
810 chan->chan_adapter = adapt;
811 chan->chan_bustype = &scsi_bustype;
812 chan->chan_channel = i;
813 chan->chan_ntargets = IPS_MAXTARGETS;
814 chan->chan_nluns = lastarget + 1;
815 chan->chan_id = i;
816 chan->chan_flags = SCSIPI_CHAN_NOSETTLE;
817 config_found(self, chan, scsiprint, CFARGS_NONE);
818 }
819
820 /* Enable interrupts */
821 ips_intren(sc);
822
823 #if NBIO > 0
824 /* Install ioctl handler */
825 if (bio_register(sc->sc_dev, ips_ioctl))
826 device_printf(sc->sc_dev, "no ioctl support\n");
827 #endif
828
829 return;
830 fail5:
831 ips_ccb_free(sc, sc->sc_ccb, sc->sc_nccbs);
832 fail4:
833 if (sc->sc_chip->ic_id == IPS_CHIP_COPPERHEAD)
834 ips_dmamem_free(&sc->sc_sqm);
835 fail3:
836 ips_dmamem_free(&sc->sc_infom);
837 fail2:
838 ips_dmamem_free(&sc->sc_cmdbm);
839 fail1:
840 bus_space_unmap(sc->sc_iot, sc->sc_ioh, iosize);
841 }
842
843 void
ips_scsi_cmd(struct ips_ccb * ccb)844 ips_scsi_cmd(struct ips_ccb *ccb)
845 {
846 struct scsipi_xfer *xs = ccb->c_xfer;
847 struct scsipi_periph *periph = xs->xs_periph;
848 struct scsipi_channel *chan = periph->periph_channel;
849 struct ips_softc *sc = device_private(chan->chan_adapter->adapt_dev);
850 struct ips_driveinfo *di = &sc->sc_info->drive;
851 struct ips_drive *drive;
852 struct ips_cmd *cmd;
853 int target = periph->periph_target;
854 u_int32_t blkno, blkcnt;
855 int code;
856
857 DPRINTF(IPS_D_XFER, ("%s: ips_scsi_cmd: xs %p, target %d, "
858 "opcode 0x%02x, flags 0x%x\n", device_xname(sc->sc_dev), xs, target,
859 xs->cmd->opcode, xs->xs_control));
860
861 if (target >= sc->sc_nunits || periph->periph_lun != 0) {
862 DPRINTF(IPS_D_INFO, ("%s: ips_scsi_cmd: invalid params "
863 "target %d, lun %d\n", device_xname(sc->sc_dev),
864 target, periph->periph_lun));
865 xs->error = XS_DRIVER_STUFFUP;
866 ips_ccb_put(sc, ccb);
867 scsipi_done(xs);
868 return;
869 }
870
871 drive = &di->drive[target];
872 xs->error = XS_NOERROR;
873
874 /* Fake SCSI commands */
875 switch (xs->cmd->opcode) {
876 case READ_10:
877 case SCSI_READ_6_COMMAND:
878 case WRITE_10:
879 case SCSI_WRITE_6_COMMAND: {
880 struct scsi_rw_6 *rw;
881 struct scsipi_rw_10 *rwb;
882
883 if (xs->cmdlen == sizeof(struct scsi_rw_6)) {
884 rw = (void *)xs->cmd;
885 blkno = _3btol(rw->addr) &
886 (SRW_TOPADDR << 16 | 0xffff);
887 blkcnt = rw->length ? rw->length : 0x100;
888 } else {
889 rwb = (void *)xs->cmd;
890 blkno = _4btol(rwb->addr);
891 blkcnt = _2btol(rwb->length);
892 }
893
894 if (blkno >= htole32(drive->seccnt) || blkno + blkcnt >
895 htole32(drive->seccnt)) {
896 DPRINTF(IPS_D_ERR, ("%s: ips_scsi_cmd: invalid params "
897 "blkno %u, blkcnt %u\n", device_xname(sc->sc_dev),
898 blkno, blkcnt));
899 xs->error = XS_DRIVER_STUFFUP;
900 break;
901 }
902
903 if (xs->xs_control & XS_CTL_DATA_IN)
904 code = IPS_CMD_READ;
905 else
906 code = IPS_CMD_WRITE;
907
908 cmd = ccb->c_cmdbva;
909 cmd->code = code;
910 cmd->drive = target;
911 cmd->lba = htole32(blkno);
912 cmd->seccnt = htole16(blkcnt);
913
914 if (ips_load_xs(sc, ccb, xs)) {
915 DPRINTF(IPS_D_ERR, ("%s: ips_scsi_cmd: ips_load_xs "
916 "failed\n", device_xname(sc->sc_dev)));
917 xs->error = XS_DRIVER_STUFFUP;
918 ips_ccb_put(sc, ccb);
919 scsipi_done(xs);
920 return;
921 }
922
923 if (cmd->sgcnt > 0)
924 cmd->code |= IPS_CMD_SG;
925
926 ccb->c_done = ips_done_xs;
927 ips_start_xs(sc, ccb, xs);
928 return;
929 }
930 case INQUIRY: {
931 struct scsipi_inquiry_data inq;
932
933 bzero(&inq, sizeof(inq));
934 inq.device = T_DIRECT;
935 inq.version = 2;
936 inq.response_format = 2;
937 inq.additional_length = 32;
938 inq.flags3 |= SID_CmdQue;
939 strlcpy(inq.vendor, "IBM", sizeof(inq.vendor));
940 snprintf(inq.product, sizeof(inq.product),
941 "LD%d RAID%d", target, drive->raid);
942 strlcpy(inq.revision, "1.0", sizeof(inq.revision));
943 memcpy(xs->data, &inq, MIN(xs->datalen, sizeof(inq)));
944 break;
945 }
946 case READ_CAPACITY_10: {
947 struct scsipi_read_capacity_10_data rcd;
948
949 bzero(&rcd, sizeof(rcd));
950 _lto4b(htole32(drive->seccnt) - 1, rcd.addr);
951 _lto4b(IPS_SECSZ, rcd.length);
952 memcpy(xs->data, &rcd, MIN(xs->datalen, sizeof(rcd)));
953 break;
954 }
955 case SCSI_REQUEST_SENSE: {
956 struct scsi_sense_data sd;
957
958 bzero(&sd, sizeof(sd));
959 sd.response_code = SSD_RCODE_CURRENT;
960 sd.flags = SKEY_NO_SENSE;
961 memcpy(xs->data, &sd, MIN(xs->datalen, sizeof(sd)));
962 break;
963 }
964 case SCSI_SYNCHRONIZE_CACHE_10:
965 cmd = ccb->c_cmdbva;
966 cmd->code = IPS_CMD_FLUSH;
967
968 ccb->c_done = ips_done_xs;
969 ips_start_xs(sc, ccb, xs);
970 return;
971 case SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL:
972 case START_STOP:
973 case SCSI_TEST_UNIT_READY:
974 break;
975 default:
976 DPRINTF(IPS_D_INFO, ("%s: unsupported scsi command 0x%02x\n",
977 device_xname(sc->sc_dev), xs->cmd->opcode));
978 xs->error = XS_DRIVER_STUFFUP;
979 }
980
981 ips_ccb_put(sc, ccb);
982 scsipi_done(xs);
983 }
984
985 /*
986 * Start a SCSI command.
987 */
988 static void
ips_scsipi_request(struct scsipi_channel * chan,scsipi_adapter_req_t req,void * arg)989 ips_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req,
990 void *arg)
991 {
992 switch (req) {
993 case ADAPTER_REQ_RUN_XFER: {
994 struct ips_ccb *ccb;
995 struct scsipi_xfer *xs;
996 struct ips_softc *sc;
997
998 sc = device_private(chan->chan_adapter->adapt_dev);
999 xs = (struct scsipi_xfer *)arg;
1000
1001 if ((ccb = ips_ccb_get(sc)) == NULL) {
1002 xs->error = XS_RESOURCE_SHORTAGE;
1003 scsipi_done(xs);
1004 break;
1005 }
1006
1007 ccb->c_xfer = xs;
1008 ips_scsi_cmd(ccb);
1009
1010 break;
1011 }
1012
1013 case ADAPTER_REQ_SET_XFER_MODE: {
1014 struct scsipi_xfer_mode *xm = arg;
1015 xm->xm_mode = PERIPH_CAP_TQING;
1016 xm->xm_period = 0;
1017 xm->xm_offset = 0;
1018 scsipi_async_event(chan, ASYNC_EVENT_XFER_MODE, xm);
1019 return;
1020 }
1021
1022 case ADAPTER_REQ_GROW_RESOURCES:
1023 /*
1024 * Not supported.
1025 */
1026 break;
1027 }
1028 }
1029
1030 int
ips_scsi_ioctl(struct scsipi_channel * chan,u_long cmd,void * data,int flag,struct proc * p)1031 ips_scsi_ioctl(struct scsipi_channel *chan, u_long cmd, void *data,
1032 int flag, struct proc *p)
1033 {
1034 #if NBIO > 0
1035 return (ips_ioctl(chan->chan_adapter->adapt_dev, cmd, data));
1036 #else
1037 return (ENOTTY);
1038 #endif
1039 }
1040
1041 #if NBIO > 0
1042 int
ips_ioctl(device_t dev,u_long cmd,void * data)1043 ips_ioctl(device_t dev, u_long cmd, void *data)
1044 {
1045 struct ips_softc *sc = device_private(dev);
1046
1047 DPRINTF(IPS_D_INFO, ("%s: ips_ioctl: cmd %lu\n",
1048 device_xname(sc->sc_dev), cmd));
1049
1050 switch (cmd) {
1051 case BIOCINQ:
1052 return (ips_ioctl_inq(sc, (struct bioc_inq *)data));
1053 case BIOCVOL:
1054 return (ips_ioctl_vol(sc, (struct bioc_vol *)data));
1055 case BIOCDISK:
1056 return (ips_ioctl_disk(sc, (struct bioc_disk *)data));
1057 case BIOCSETSTATE:
1058 return (ips_ioctl_setstate(sc, (struct bioc_setstate *)data));
1059 default:
1060 return (ENOTTY);
1061 }
1062 }
1063
1064 int
ips_ioctl_inq(struct ips_softc * sc,struct bioc_inq * bi)1065 ips_ioctl_inq(struct ips_softc *sc, struct bioc_inq *bi)
1066 {
1067 struct ips_conf *conf = &sc->sc_info->conf;
1068 int i;
1069
1070 strlcpy(bi->bi_dev, device_xname(sc->sc_dev), sizeof(bi->bi_dev));
1071 bi->bi_novol = sc->sc_nunits;
1072 for (i = 0, bi->bi_nodisk = 0; i < sc->sc_nunits; i++)
1073 bi->bi_nodisk += conf->ld[i].chunkcnt;
1074
1075 DPRINTF(IPS_D_INFO, ("%s: ips_ioctl_inq: novol %d, nodisk %d\n",
1076 bi->bi_dev, bi->bi_novol, bi->bi_nodisk));
1077
1078 return (0);
1079 }
1080
1081 int
ips_ioctl_vol(struct ips_softc * sc,struct bioc_vol * bv)1082 ips_ioctl_vol(struct ips_softc *sc, struct bioc_vol *bv)
1083 {
1084 struct ips_driveinfo *di = &sc->sc_info->drive;
1085 struct ips_conf *conf = &sc->sc_info->conf;
1086 struct ips_rblstat *rblstat = &sc->sc_info->rblstat;
1087 struct ips_ld *ld;
1088 int vid = bv->bv_volid;
1089 device_t dv;
1090 int error, rebuild = 0;
1091 u_int32_t total = 0, done = 0;
1092
1093 if (vid >= sc->sc_nunits)
1094 return (EINVAL);
1095 if ((error = ips_getconf(sc, 0)))
1096 return (error);
1097 ld = &conf->ld[vid];
1098
1099 switch (ld->state) {
1100 case IPS_DS_ONLINE:
1101 bv->bv_status = BIOC_SVONLINE;
1102 break;
1103 case IPS_DS_DEGRADED:
1104 bv->bv_status = BIOC_SVDEGRADED;
1105 rebuild++;
1106 break;
1107 case IPS_DS_OFFLINE:
1108 bv->bv_status = BIOC_SVOFFLINE;
1109 break;
1110 default:
1111 bv->bv_status = BIOC_SVINVALID;
1112 }
1113
1114 if (rebuild && ips_getrblstat(sc, 0) == 0) {
1115 total = htole32(rblstat->ld[vid].total);
1116 done = total - htole32(rblstat->ld[vid].remain);
1117 if (total && total > done) {
1118 bv->bv_status = BIOC_SVREBUILD;
1119 bv->bv_percent = 100 * done / total;
1120 }
1121 }
1122
1123 bv->bv_size = (uint64_t)htole32(ld->size) * IPS_SECSZ;
1124 bv->bv_level = di->drive[vid].raid;
1125 bv->bv_nodisk = ld->chunkcnt;
1126
1127 /* Associate all unused and spare drives with first volume */
1128 if (vid == 0) {
1129 struct ips_dev *dev;
1130 int chan, target;
1131
1132 for (chan = 0; chan < IPS_MAXCHANS; chan++)
1133 for (target = 0; target < IPS_MAXTARGETS; target++) {
1134 dev = &conf->dev[chan][target];
1135 if (dev->state && !(dev->state &
1136 IPS_DVS_MEMBER) &&
1137 (dev->params & SID_TYPE) == T_DIRECT)
1138 bv->bv_nodisk++;
1139 }
1140 }
1141
1142 dv = sc->sc_dev;
1143 strlcpy(bv->bv_dev, device_xname(dv), sizeof(bv->bv_dev));
1144 strlcpy(bv->bv_vendor, "IBM", sizeof(bv->bv_vendor));
1145
1146 DPRINTF(IPS_D_INFO, ("%s: ips_ioctl_vol: vid %d, state 0x%02x, "
1147 "total %u, done %u, size %llu, level %d, nodisk %d, dev %s\n",
1148 device_xname(sc->sc_dev), vid, ld->state, total, done, bv->bv_size,
1149 bv->bv_level, bv->bv_nodisk, bv->bv_dev));
1150
1151 return (0);
1152 }
1153
1154 int
ips_ioctl_disk(struct ips_softc * sc,struct bioc_disk * bd)1155 ips_ioctl_disk(struct ips_softc *sc, struct bioc_disk *bd)
1156 {
1157 struct ips_conf *conf = &sc->sc_info->conf;
1158 struct ips_ld *ld;
1159 struct ips_chunk *chunk;
1160 struct ips_dev *dev;
1161 int vid = bd->bd_volid, did = bd->bd_diskid;
1162 int chan, target, error, i;
1163
1164 if (vid >= sc->sc_nunits)
1165 return (EINVAL);
1166 if ((error = ips_getconf(sc, 0)))
1167 return (error);
1168 ld = &conf->ld[vid];
1169
1170 if (did >= ld->chunkcnt) {
1171 /* Probably unused or spare drives */
1172 if (vid != 0)
1173 return (EINVAL);
1174
1175 i = ld->chunkcnt;
1176 for (chan = 0; chan < IPS_MAXCHANS; chan++)
1177 for (target = 0; target < IPS_MAXTARGETS; target++) {
1178 dev = &conf->dev[chan][target];
1179 if (dev->state && !(dev->state &
1180 IPS_DVS_MEMBER) &&
1181 (dev->params & SID_TYPE) == T_DIRECT)
1182 if (i++ == did)
1183 goto out;
1184 }
1185 } else {
1186 chunk = &ld->chunk[did];
1187 chan = chunk->channel;
1188 target = chunk->target;
1189 }
1190
1191 out:
1192 if (chan >= IPS_MAXCHANS || target >= IPS_MAXTARGETS)
1193 return (EINVAL);
1194 dev = &conf->dev[chan][target];
1195
1196 bd->bd_channel = chan;
1197 bd->bd_target = target;
1198 bd->bd_lun = 0;
1199 bd->bd_size = (uint64_t)htole32(dev->seccnt) * IPS_SECSZ;
1200
1201 bzero(bd->bd_vendor, sizeof(bd->bd_vendor));
1202 memcpy(bd->bd_vendor, dev->devid, MIN(sizeof(bd->bd_vendor),
1203 sizeof(dev->devid)));
1204 strlcpy(bd->bd_procdev, sc->sc_pt[chan].pt_procdev,
1205 sizeof(bd->bd_procdev));
1206
1207 if (dev->state & IPS_DVS_READY) {
1208 bd->bd_status = BIOC_SDUNUSED;
1209 if (dev->state & IPS_DVS_MEMBER)
1210 bd->bd_status = BIOC_SDONLINE;
1211 if (dev->state & IPS_DVS_SPARE)
1212 bd->bd_status = BIOC_SDHOTSPARE;
1213 if (dev->state & IPS_DVS_REBUILD)
1214 bd->bd_status = BIOC_SDREBUILD;
1215 } else {
1216 bd->bd_status = BIOC_SDOFFLINE;
1217 }
1218
1219 DPRINTF(IPS_D_INFO, ("%s: ips_ioctl_disk: vid %d, did %d, channel %d, "
1220 "target %d, size %llu, state 0x%02x\n", device_xname(sc->sc_dev),
1221 vid, did, bd->bd_channel, bd->bd_target, bd->bd_size, dev->state));
1222
1223 return (0);
1224 }
1225
1226 int
ips_ioctl_setstate(struct ips_softc * sc,struct bioc_setstate * bs)1227 ips_ioctl_setstate(struct ips_softc *sc, struct bioc_setstate *bs)
1228 {
1229 struct ips_conf *conf = &sc->sc_info->conf;
1230 struct ips_dev *dev;
1231 int state, error;
1232
1233 if (bs->bs_channel >= IPS_MAXCHANS || bs->bs_target >= IPS_MAXTARGETS)
1234 return (EINVAL);
1235 if ((error = ips_getconf(sc, 0)))
1236 return (error);
1237 dev = &conf->dev[bs->bs_channel][bs->bs_target];
1238 state = dev->state;
1239
1240 switch (bs->bs_status) {
1241 case BIOC_SSONLINE:
1242 state |= IPS_DVS_READY;
1243 break;
1244 case BIOC_SSOFFLINE:
1245 state &= ~IPS_DVS_READY;
1246 break;
1247 case BIOC_SSHOTSPARE:
1248 state |= IPS_DVS_SPARE;
1249 break;
1250 case BIOC_SSREBUILD:
1251 return (ips_rebuild(sc, bs->bs_channel, bs->bs_target,
1252 bs->bs_channel, bs->bs_target, 0));
1253 default:
1254 return (EINVAL);
1255 }
1256
1257 return (ips_setstate(sc, bs->bs_channel, bs->bs_target, state, 0));
1258 }
1259 #endif /* NBIO > 0 */
1260
1261 int
ips_load_xs(struct ips_softc * sc,struct ips_ccb * ccb,struct scsipi_xfer * xs)1262 ips_load_xs(struct ips_softc *sc, struct ips_ccb *ccb, struct scsipi_xfer *xs)
1263 {
1264 struct ips_cmdb *cmdb = ccb->c_cmdbva;
1265 struct ips_cmd *cmd = &cmdb->cmd;
1266 struct ips_sg *sg = cmdb->sg;
1267 int nsegs, i;
1268
1269 if (xs->datalen == 0)
1270 return (0);
1271
1272 /* Map data buffer into DMA segments */
1273 if (bus_dmamap_load(sc->sc_dmat, ccb->c_dmam, xs->data, xs->datalen,
1274 NULL, (xs->xs_control & XS_CTL_NOSLEEP ? BUS_DMA_NOWAIT : 0)))
1275 return (1);
1276 bus_dmamap_sync(sc->sc_dmat, ccb->c_dmam, 0,ccb->c_dmam->dm_mapsize,
1277 xs->xs_control & XS_CTL_DATA_IN ? BUS_DMASYNC_PREREAD :
1278 BUS_DMASYNC_PREWRITE);
1279
1280 if ((nsegs = ccb->c_dmam->dm_nsegs) > IPS_MAXSGS)
1281 return (1);
1282
1283 if (nsegs > 1) {
1284 cmd->sgcnt = nsegs;
1285 cmd->sgaddr = htole32(ccb->c_cmdbpa + offsetof(struct ips_cmdb,
1286 sg));
1287
1288 /* Fill in scatter-gather array */
1289 for (i = 0; i < nsegs; i++) {
1290 sg[i].addr = htole32(ccb->c_dmam->dm_segs[i].ds_addr);
1291 sg[i].size = htole32(ccb->c_dmam->dm_segs[i].ds_len);
1292 }
1293 } else {
1294 cmd->sgcnt = 0;
1295 cmd->sgaddr = htole32(ccb->c_dmam->dm_segs[0].ds_addr);
1296 }
1297
1298 return (0);
1299 }
1300
1301 void
ips_start_xs(struct ips_softc * sc,struct ips_ccb * ccb,struct scsipi_xfer * xs)1302 ips_start_xs(struct ips_softc *sc, struct ips_ccb *ccb, struct scsipi_xfer *xs)
1303 {
1304 ccb->c_flags = xs->xs_control;
1305 ccb->c_xfer = xs;
1306 int ispoll = xs->xs_control & XS_CTL_POLL;
1307
1308 if (!ispoll) {
1309 int timeout = mstohz(xs->timeout);
1310 if (timeout == 0)
1311 timeout = 1;
1312
1313 callout_reset(&xs->xs_callout, timeout, ips_timeout, ccb);
1314 }
1315
1316 /*
1317 * Return value not used here because ips_cmd() must complete
1318 * scsipi_xfer on any failure and SCSI layer will handle possible
1319 * errors.
1320 */
1321 ips_cmd(sc, ccb);
1322 }
1323
1324 int
ips_cmd(struct ips_softc * sc,struct ips_ccb * ccb)1325 ips_cmd(struct ips_softc *sc, struct ips_ccb *ccb)
1326 {
1327 struct ips_cmd *cmd = ccb->c_cmdbva;
1328 int s, error = 0;
1329
1330 DPRINTF(IPS_D_XFER, ("%s: ips_cmd: id 0x%02x, flags 0x%x, xs %p, "
1331 "code 0x%02x, drive %d, sgcnt %d, lba %d, sgaddr 0x%08x, "
1332 "seccnt %d\n", device_xname(sc->sc_dev), ccb->c_id, ccb->c_flags,
1333 ccb->c_xfer, cmd->code, cmd->drive, cmd->sgcnt, htole32(cmd->lba),
1334 htole32(cmd->sgaddr), htole16(cmd->seccnt)));
1335
1336 cmd->id = ccb->c_id;
1337
1338 /* Post command to controller and optionally wait for completion */
1339 s = splbio();
1340 ips_exec(sc, ccb);
1341 ccb->c_state = IPS_CCB_QUEUED;
1342 if (ccb->c_flags & XS_CTL_POLL)
1343 error = ips_poll(sc, ccb);
1344 splx(s);
1345
1346 return (error);
1347 }
1348
1349 int
ips_poll(struct ips_softc * sc,struct ips_ccb * ccb)1350 ips_poll(struct ips_softc *sc, struct ips_ccb *ccb)
1351 {
1352 struct timeval tv;
1353 int error, timo;
1354
1355 if (ccb->c_flags & XS_CTL_NOSLEEP) {
1356 /* busy-wait */
1357 DPRINTF(IPS_D_XFER, ("%s: ips_poll: busy-wait\n",
1358 device_xname(sc->sc_dev)));
1359
1360 for (timo = 10000; timo > 0; timo--) {
1361 delay(100);
1362 ips_intr(sc);
1363 if (ccb->c_state == IPS_CCB_DONE)
1364 break;
1365 }
1366 } else {
1367 /* sleep */
1368 timo = ccb->c_xfer ? ccb->c_xfer->timeout : IPS_TIMEOUT;
1369 tv.tv_sec = timo / 1000;
1370 tv.tv_usec = (timo % 1000) * 1000;
1371 timo = tvtohz(&tv);
1372
1373 DPRINTF(IPS_D_XFER, ("%s: ips_poll: sleep %d hz\n",
1374 device_xname(sc->sc_dev), timo));
1375 tsleep(ccb, PRIBIO + 1, "ipscmd", timo);
1376 }
1377 DPRINTF(IPS_D_XFER, ("%s: ips_poll: state %d\n",
1378 device_xname(sc->sc_dev),
1379 ccb->c_state));
1380
1381 if (ccb->c_state != IPS_CCB_DONE)
1382 /*
1383 * Command never completed. Fake hardware status byte
1384 * to indicate timeout.
1385 */
1386 ccb->c_stat = IPS_STAT_TIMO;
1387
1388 ips_done(sc, ccb);
1389 error = ccb->c_error;
1390
1391 return (error);
1392 }
1393
1394 void
ips_done(struct ips_softc * sc,struct ips_ccb * ccb)1395 ips_done(struct ips_softc *sc, struct ips_ccb *ccb)
1396 {
1397 DPRINTF(IPS_D_XFER, ("%s: ips_done: id 0x%02x, flags 0x%x, xs %p\n",
1398 device_xname(sc->sc_dev), ccb->c_id, ccb->c_flags, ccb->c_xfer));
1399
1400 ccb->c_error = ips_error(sc, ccb);
1401 ccb->c_done(sc, ccb);
1402 }
1403
1404 void
ips_done_xs(struct ips_softc * sc,struct ips_ccb * ccb)1405 ips_done_xs(struct ips_softc *sc, struct ips_ccb *ccb)
1406 {
1407 struct scsipi_xfer *xs = ccb->c_xfer;
1408
1409 if (!(xs->xs_control & XS_CTL_POLL))
1410 callout_stop(&xs->xs_callout);
1411
1412 if (xs->xs_control & (XS_CTL_DATA_IN | XS_CTL_DATA_OUT)) {
1413 bus_dmamap_sync(sc->sc_dmat, ccb->c_dmam, 0,
1414 ccb->c_dmam->dm_mapsize, xs->xs_control & XS_CTL_DATA_IN ?
1415 BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
1416 bus_dmamap_unload(sc->sc_dmat, ccb->c_dmam);
1417 }
1418
1419 xs->resid = 0;
1420 xs->error = ips_error_xs(sc, ccb);
1421 ips_ccb_put(sc, ccb);
1422 scsipi_done(xs);
1423 }
1424
1425 void
ips_done_pt(struct ips_softc * sc,struct ips_ccb * ccb)1426 ips_done_pt(struct ips_softc *sc, struct ips_ccb *ccb)
1427 {
1428 struct scsipi_xfer *xs = ccb->c_xfer;
1429 struct ips_cmdb *cmdb = ccb->c_cmdbva;
1430 struct ips_dcdb *dcdb = &cmdb->dcdb;
1431 int done = htole16(dcdb->datalen);
1432
1433 if (!(xs->xs_control & XS_CTL_POLL))
1434 callout_stop(&xs->xs_callout);
1435
1436 if (xs->xs_control & (XS_CTL_DATA_IN | XS_CTL_DATA_OUT)) {
1437 bus_dmamap_sync(sc->sc_dmat, ccb->c_dmam, 0,
1438 ccb->c_dmam->dm_mapsize, xs->xs_control & XS_CTL_DATA_IN ?
1439 BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
1440 bus_dmamap_unload(sc->sc_dmat, ccb->c_dmam);
1441 }
1442
1443 if (done && done < xs->datalen)
1444 xs->resid = xs->datalen - done;
1445 else
1446 xs->resid = 0;
1447 xs->error = ips_error_xs(sc, ccb);
1448 xs->status = dcdb->status;
1449
1450 if (xs->error == XS_SENSE)
1451 memcpy(&xs->sense, dcdb->sense, MIN(sizeof(xs->sense),
1452 sizeof(dcdb->sense)));
1453
1454 if (xs->cmd->opcode == INQUIRY && xs->error == XS_NOERROR) {
1455 int type = ((struct scsipi_inquiry_data *)xs->data)->device &
1456 SID_TYPE;
1457
1458 if (type == T_DIRECT)
1459 /* mask physical drives */
1460 xs->error = XS_DRIVER_STUFFUP;
1461 }
1462
1463 ips_ccb_put(sc, ccb);
1464 scsipi_done(xs);
1465 }
1466
1467 void
ips_done_mgmt(struct ips_softc * sc,struct ips_ccb * ccb)1468 ips_done_mgmt(struct ips_softc *sc, struct ips_ccb *ccb)
1469 {
1470 if (ccb->c_flags & (XS_CTL_DATA_IN | XS_CTL_DATA_OUT))
1471 bus_dmamap_sync(sc->sc_dmat, sc->sc_infom.dm_map, 0,
1472 sc->sc_infom.dm_map->dm_mapsize,
1473 ccb->c_flags & XS_CTL_DATA_IN ? BUS_DMASYNC_POSTREAD :
1474 BUS_DMASYNC_POSTWRITE);
1475
1476 ips_ccb_put(sc, ccb);
1477 }
1478
1479 int
ips_error(struct ips_softc * sc,struct ips_ccb * ccb)1480 ips_error(struct ips_softc *sc, struct ips_ccb *ccb)
1481 {
1482 struct ips_cmdb *cmdb = ccb->c_cmdbva;
1483 struct ips_cmd *cmd = &cmdb->cmd;
1484 struct ips_dcdb *dcdb = &cmdb->dcdb;
1485 struct scsipi_xfer *xs = ccb->c_xfer;
1486 u_int8_t gsc = IPS_STAT_GSC(ccb->c_stat);
1487
1488 if (gsc == IPS_STAT_OK)
1489 return (0);
1490
1491 DPRINTF(IPS_D_ERR, ("%s: ips_error: stat 0x%02x, estat 0x%02x, "
1492 "cmd code 0x%02x, drive %d, sgcnt %d, lba %u, seccnt %d",
1493 device_xname(sc->sc_dev), ccb->c_stat, ccb->c_estat, cmd->code,
1494 cmd->drive, cmd->sgcnt, htole32(cmd->lba), htole16(cmd->seccnt)));
1495 if (cmd->code == IPS_CMD_DCDB || cmd->code == IPS_CMD_DCDB_SG) {
1496 int i;
1497
1498 DPRINTF(IPS_D_ERR, (", dcdb device 0x%02x, attr 0x%02x, "
1499 "datalen %d, sgcnt %d, status 0x%02x",
1500 dcdb->device, dcdb->attr, htole16(dcdb->datalen),
1501 dcdb->sgcnt, dcdb->status));
1502
1503 DPRINTF(IPS_D_ERR, (", cdb"));
1504 for (i = 0; i < dcdb->cdblen; i++)
1505 DPRINTF(IPS_D_ERR, (" %x", dcdb->cdb[i]));
1506 if (ccb->c_estat == IPS_ESTAT_CKCOND) {
1507 DPRINTF(IPS_D_ERR, (", sense"));
1508 for (i = 0; i < dcdb->senselen; i++)
1509 DPRINTF(IPS_D_ERR, (" %x", dcdb->sense[i]));
1510 }
1511 }
1512 DPRINTF(IPS_D_ERR, ("\n"));
1513
1514 switch (gsc) {
1515 case IPS_STAT_RECOV:
1516 return (0);
1517 case IPS_STAT_INVOP:
1518 case IPS_STAT_INVCMD:
1519 case IPS_STAT_INVPARM:
1520 return (EINVAL);
1521 case IPS_STAT_BUSY:
1522 return (EBUSY);
1523 case IPS_STAT_TIMO:
1524 return (ETIMEDOUT);
1525 case IPS_STAT_PDRVERR:
1526 switch (ccb->c_estat) {
1527 case IPS_ESTAT_SELTIMO:
1528 return (ENODEV);
1529 case IPS_ESTAT_OURUN:
1530 if (xs && htole16(dcdb->datalen) < xs->datalen)
1531 /* underrun */
1532 return (0);
1533 break;
1534 case IPS_ESTAT_RECOV:
1535 return (0);
1536 }
1537 break;
1538 }
1539
1540 return (EIO);
1541 }
1542
1543 int
ips_error_xs(struct ips_softc * sc,struct ips_ccb * ccb)1544 ips_error_xs(struct ips_softc *sc, struct ips_ccb *ccb)
1545 {
1546 struct ips_cmdb *cmdb = ccb->c_cmdbva;
1547 struct ips_dcdb *dcdb = &cmdb->dcdb;
1548 struct scsipi_xfer *xs = ccb->c_xfer;
1549 u_int8_t gsc = IPS_STAT_GSC(ccb->c_stat);
1550
1551 /* Map hardware error codes to SCSI ones */
1552 switch (gsc) {
1553 case IPS_STAT_OK:
1554 case IPS_STAT_RECOV:
1555 return (XS_NOERROR);
1556 case IPS_STAT_BUSY:
1557 return (XS_BUSY);
1558 case IPS_STAT_TIMO:
1559 return (XS_TIMEOUT);
1560 case IPS_STAT_PDRVERR:
1561 switch (ccb->c_estat) {
1562 case IPS_ESTAT_SELTIMO:
1563 return (XS_SELTIMEOUT);
1564 case IPS_ESTAT_OURUN:
1565 if (xs && htole16(dcdb->datalen) < xs->datalen)
1566 /* underrun */
1567 return (XS_NOERROR);
1568 break;
1569 case IPS_ESTAT_HOSTRST:
1570 case IPS_ESTAT_DEVRST:
1571 return (XS_RESET);
1572 case IPS_ESTAT_RECOV:
1573 return (XS_NOERROR);
1574 case IPS_ESTAT_CKCOND:
1575 return (XS_SENSE);
1576 }
1577 break;
1578 }
1579
1580 return (XS_DRIVER_STUFFUP);
1581 }
1582
1583 int
ips_intr(void * arg)1584 ips_intr(void *arg)
1585 {
1586 struct ips_softc *sc = arg;
1587 struct ips_ccb *ccb;
1588 u_int32_t status;
1589 int id;
1590
1591 DPRINTF(IPS_D_XFER, ("%s: ips_intr", device_xname(sc->sc_dev)));
1592 if (!ips_isintr(sc)) {
1593 DPRINTF(IPS_D_XFER, (": not ours\n"));
1594 return (0);
1595 }
1596 DPRINTF(IPS_D_XFER, ("\n"));
1597
1598 /* Process completed commands */
1599 while ((status = ips_status(sc)) != 0xffffffff) {
1600 DPRINTF(IPS_D_XFER, ("%s: ips_intr: status 0x%08x\n",
1601 device_xname(sc->sc_dev), status));
1602
1603 id = IPS_STAT_ID(status);
1604 if (id >= sc->sc_nccbs) {
1605 DPRINTF(IPS_D_ERR, ("%s: ips_intr: invalid id %d\n",
1606 device_xname(sc->sc_dev), id));
1607 continue;
1608 }
1609
1610 ccb = &sc->sc_ccb[id];
1611 if (ccb->c_state != IPS_CCB_QUEUED) {
1612 DPRINTF(IPS_D_ERR, ("%s: ips_intr: cmd 0x%02x not "
1613 "queued, state %d, status 0x%08x\n",
1614 device_xname(sc->sc_dev), ccb->c_id, ccb->c_state,
1615 status));
1616 continue;
1617 }
1618
1619 ccb->c_state = IPS_CCB_DONE;
1620 ccb->c_stat = IPS_STAT_BASIC(status);
1621 ccb->c_estat = IPS_STAT_EXT(status);
1622
1623 if (ccb->c_flags & XS_CTL_POLL) {
1624 wakeup(ccb);
1625 } else {
1626 ips_done(sc, ccb);
1627 }
1628 }
1629
1630 return (1);
1631 }
1632
1633 void
ips_timeout(void * arg)1634 ips_timeout(void *arg)
1635 {
1636 struct ips_ccb *ccb = arg;
1637 struct ips_softc *sc = ccb->c_sc;
1638 struct scsipi_xfer *xs = ccb->c_xfer;
1639 int s;
1640
1641 s = splbio();
1642 if (xs)
1643 scsi_print_addr(xs->xs_periph);
1644 else
1645 printf("%s: ", device_xname(sc->sc_dev));
1646 printf("timeout\n");
1647
1648 /*
1649 * Command never completed. Fake hardware status byte
1650 * to indicate timeout.
1651 * XXX: need to remove command from controller.
1652 */
1653 ccb->c_stat = IPS_STAT_TIMO;
1654 ips_done(sc, ccb);
1655 splx(s);
1656 }
1657
1658 int
ips_getadapterinfo(struct ips_softc * sc,int flags)1659 ips_getadapterinfo(struct ips_softc *sc, int flags)
1660 {
1661 struct ips_ccb *ccb;
1662 struct ips_cmd *cmd;
1663
1664 ccb = ips_ccb_get(sc);
1665 if (ccb == NULL)
1666 return (1);
1667
1668 ccb->c_flags = XS_CTL_DATA_IN | XS_CTL_POLL | flags;
1669 ccb->c_done = ips_done_mgmt;
1670
1671 cmd = ccb->c_cmdbva;
1672 cmd->code = IPS_CMD_GETADAPTERINFO;
1673 cmd->sgaddr = htole32(sc->sc_infom.dm_paddr + offsetof(struct ips_info,
1674 adapter));
1675
1676 return (ips_cmd(sc, ccb));
1677 }
1678
1679 int
ips_getdriveinfo(struct ips_softc * sc,int flags)1680 ips_getdriveinfo(struct ips_softc *sc, int flags)
1681 {
1682 struct ips_ccb *ccb;
1683 struct ips_cmd *cmd;
1684
1685 ccb = ips_ccb_get(sc);
1686 if (ccb == NULL)
1687 return (1);
1688
1689 ccb->c_flags = XS_CTL_DATA_IN | XS_CTL_POLL | flags;
1690 ccb->c_done = ips_done_mgmt;
1691
1692 cmd = ccb->c_cmdbva;
1693 cmd->code = IPS_CMD_GETDRIVEINFO;
1694 cmd->sgaddr = htole32(sc->sc_infom.dm_paddr + offsetof(struct ips_info,
1695 drive));
1696
1697 return (ips_cmd(sc, ccb));
1698 }
1699
1700 int
ips_getconf(struct ips_softc * sc,int flags)1701 ips_getconf(struct ips_softc *sc, int flags)
1702 {
1703 struct ips_ccb *ccb;
1704 struct ips_cmd *cmd;
1705
1706 ccb = ips_ccb_get(sc);
1707 if (ccb == NULL)
1708 return (1);
1709
1710 ccb->c_flags = XS_CTL_DATA_IN | XS_CTL_POLL | flags;
1711 ccb->c_done = ips_done_mgmt;
1712
1713 cmd = ccb->c_cmdbva;
1714 cmd->code = IPS_CMD_READCONF;
1715 cmd->sgaddr = htole32(sc->sc_infom.dm_paddr + offsetof(struct ips_info,
1716 conf));
1717
1718 return (ips_cmd(sc, ccb));
1719 }
1720
1721 int
ips_getpg5(struct ips_softc * sc,int flags)1722 ips_getpg5(struct ips_softc *sc, int flags)
1723 {
1724 struct ips_ccb *ccb;
1725 struct ips_cmd *cmd;
1726
1727 ccb = ips_ccb_get(sc);
1728 if (ccb == NULL)
1729 return (1);
1730
1731 ccb->c_flags = XS_CTL_DATA_IN | XS_CTL_POLL | flags;
1732 ccb->c_done = ips_done_mgmt;
1733
1734 cmd = ccb->c_cmdbva;
1735 cmd->code = IPS_CMD_RWNVRAM;
1736 cmd->drive = 5;
1737 cmd->sgaddr = htole32(sc->sc_infom.dm_paddr + offsetof(struct ips_info,
1738 pg5));
1739
1740 return (ips_cmd(sc, ccb));
1741 }
1742
1743 #if NBIO > 0
1744 int
ips_getrblstat(struct ips_softc * sc,int flags)1745 ips_getrblstat(struct ips_softc *sc, int flags)
1746 {
1747 struct ips_ccb *ccb;
1748 struct ips_cmd *cmd;
1749
1750 ccb = ips_ccb_get(sc);
1751 if (ccb == NULL)
1752 return (1);
1753
1754 ccb->c_flags = XS_CTL_DATA_IN | XS_CTL_POLL | flags;
1755 ccb->c_done = ips_done_mgmt;
1756
1757 cmd = ccb->c_cmdbva;
1758 cmd->code = IPS_CMD_REBUILDSTATUS;
1759 cmd->sgaddr = htole32(sc->sc_infom.dm_paddr + offsetof(struct ips_info,
1760 rblstat));
1761
1762 return (ips_cmd(sc, ccb));
1763 }
1764
1765 int
ips_setstate(struct ips_softc * sc,int chan,int target,int state,int flags)1766 ips_setstate(struct ips_softc *sc, int chan, int target, int state, int flags)
1767 {
1768 struct ips_ccb *ccb;
1769 struct ips_cmd *cmd;
1770
1771 ccb = ips_ccb_get(sc);
1772 if (ccb == NULL)
1773 return (1);
1774
1775 ccb->c_flags = XS_CTL_POLL | flags;
1776 ccb->c_done = ips_done_mgmt;
1777
1778 cmd = ccb->c_cmdbva;
1779 cmd->code = IPS_CMD_SETSTATE;
1780 cmd->drive = chan;
1781 cmd->sgcnt = target;
1782 cmd->seg4g = state;
1783
1784 return (ips_cmd(sc, ccb));
1785 }
1786
1787 int
ips_rebuild(struct ips_softc * sc,int chan,int target,int nchan,int ntarget,int flags)1788 ips_rebuild(struct ips_softc *sc, int chan, int target, int nchan,
1789 int ntarget, int flags)
1790 {
1791 struct ips_ccb *ccb;
1792 struct ips_cmd *cmd;
1793
1794 ccb = ips_ccb_get(sc);
1795 if (ccb == NULL)
1796 return (1);
1797
1798 ccb->c_flags = XS_CTL_POLL | flags;
1799 ccb->c_done = ips_done_mgmt;
1800
1801 cmd = ccb->c_cmdbva;
1802 cmd->code = IPS_CMD_REBUILD;
1803 cmd->drive = chan;
1804 cmd->sgcnt = target;
1805 cmd->seccnt = htole16(ntarget << 8 | nchan);
1806
1807 return (ips_cmd(sc, ccb));
1808 }
1809 #endif /* NBIO > 0 */
1810
1811 void
ips_copperhead_exec(struct ips_softc * sc,struct ips_ccb * ccb)1812 ips_copperhead_exec(struct ips_softc *sc, struct ips_ccb *ccb)
1813 {
1814 u_int32_t reg;
1815 int timeout;
1816
1817 for (timeout = 100; timeout-- > 0; delay(100)) {
1818 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, IPS_REG_CCC);
1819 if ((reg & IPS_REG_CCC_SEM) == 0)
1820 break;
1821 }
1822 if (timeout < 0) {
1823 device_printf(sc->sc_dev, "semaphore timeout\n");
1824 return;
1825 }
1826
1827 bus_space_write_4(sc->sc_iot, sc->sc_ioh, IPS_REG_CCSA, ccb->c_cmdbpa);
1828 bus_space_write_2(sc->sc_iot, sc->sc_ioh, IPS_REG_CCC,
1829 IPS_REG_CCC_START);
1830 }
1831
1832 void
ips_copperhead_intren(struct ips_softc * sc)1833 ips_copperhead_intren(struct ips_softc *sc)
1834 {
1835 bus_space_write_1(sc->sc_iot, sc->sc_ioh, IPS_REG_HIS, IPS_REG_HIS_EN);
1836 }
1837
1838 int
ips_copperhead_isintr(struct ips_softc * sc)1839 ips_copperhead_isintr(struct ips_softc *sc)
1840 {
1841 u_int8_t reg;
1842
1843 reg = bus_space_read_1(sc->sc_iot, sc->sc_ioh, IPS_REG_HIS);
1844 bus_space_write_1(sc->sc_iot, sc->sc_ioh, IPS_REG_HIS, reg);
1845 if (reg != 0xff && (reg & IPS_REG_HIS_SCE))
1846 return (1);
1847
1848 return (0);
1849 }
1850
1851 u_int32_t
ips_copperhead_status(struct ips_softc * sc)1852 ips_copperhead_status(struct ips_softc *sc)
1853 {
1854 u_int32_t sqhead, sqtail, status;
1855
1856 sqhead = bus_space_read_4(sc->sc_iot, sc->sc_ioh, IPS_REG_SQH);
1857 DPRINTF(IPS_D_XFER, ("%s: sqhead 0x%08x, sqtail 0x%08x\n",
1858 device_xname(sc->sc_dev), sqhead, sc->sc_sqtail));
1859
1860 sqtail = sc->sc_sqtail + sizeof(u_int32_t);
1861 if (sqtail == sc->sc_sqm.dm_paddr + IPS_SQSZ)
1862 sqtail = sc->sc_sqm.dm_paddr;
1863 if (sqtail == sqhead)
1864 return (0xffffffff);
1865
1866 sc->sc_sqtail = sqtail;
1867 if (++sc->sc_sqidx == IPS_MAXCMDS)
1868 sc->sc_sqidx = 0;
1869 status = htole32(sc->sc_sqbuf[sc->sc_sqidx]);
1870 bus_space_write_4(sc->sc_iot, sc->sc_ioh, IPS_REG_SQT, sqtail);
1871
1872 return (status);
1873 }
1874
1875 void
ips_morpheus_exec(struct ips_softc * sc,struct ips_ccb * ccb)1876 ips_morpheus_exec(struct ips_softc *sc, struct ips_ccb *ccb)
1877 {
1878 bus_space_write_4(sc->sc_iot, sc->sc_ioh, IPS_REG_IQP, ccb->c_cmdbpa);
1879 }
1880
1881 void
ips_morpheus_intren(struct ips_softc * sc)1882 ips_morpheus_intren(struct ips_softc *sc)
1883 {
1884 u_int32_t reg;
1885
1886 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, IPS_REG_OIM);
1887 reg &= ~IPS_REG_OIM_DS;
1888 bus_space_write_4(sc->sc_iot, sc->sc_ioh, IPS_REG_OIM, reg);
1889 }
1890
1891 int
ips_morpheus_isintr(struct ips_softc * sc)1892 ips_morpheus_isintr(struct ips_softc *sc)
1893 {
1894 return (bus_space_read_4(sc->sc_iot, sc->sc_ioh, IPS_REG_OIS) &
1895 IPS_REG_OIS_PEND);
1896 }
1897
1898 u_int32_t
ips_morpheus_status(struct ips_softc * sc)1899 ips_morpheus_status(struct ips_softc *sc)
1900 {
1901 u_int32_t reg;
1902
1903 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, IPS_REG_OQP);
1904 DPRINTF(IPS_D_XFER, ("%s: status 0x%08x\n", device_xname(sc->sc_dev),
1905 reg));
1906
1907 return (reg);
1908 }
1909
1910 struct ips_ccb *
ips_ccb_alloc(struct ips_softc * sc,int n)1911 ips_ccb_alloc(struct ips_softc *sc, int n)
1912 {
1913 struct ips_ccb *ccb;
1914 int i;
1915
1916 ccb = malloc(n * sizeof(*ccb), M_DEVBUF, M_WAITOK | M_ZERO);
1917 for (i = 0; i < n; i++) {
1918 ccb[i].c_sc = sc;
1919 ccb[i].c_id = i;
1920 ccb[i].c_cmdbva = (char *)sc->sc_cmdbm.dm_vaddr +
1921 i * sizeof(struct ips_cmdb);
1922 ccb[i].c_cmdbpa = sc->sc_cmdbm.dm_paddr +
1923 i * sizeof(struct ips_cmdb);
1924 if (bus_dmamap_create(sc->sc_dmat, IPS_MAXFER, IPS_MAXSGS,
1925 IPS_MAXFER, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
1926 &ccb[i].c_dmam))
1927 goto fail;
1928 }
1929
1930 return (ccb);
1931 fail:
1932 for (; i > 0; i--)
1933 bus_dmamap_destroy(sc->sc_dmat, ccb[i - 1].c_dmam);
1934 free(ccb, M_DEVBUF);
1935 return (NULL);
1936 }
1937
1938 void
ips_ccb_free(struct ips_softc * sc,struct ips_ccb * ccb,int n)1939 ips_ccb_free(struct ips_softc *sc, struct ips_ccb *ccb, int n)
1940 {
1941 int i;
1942
1943 for (i = 0; i < n; i++)
1944 bus_dmamap_destroy(sc->sc_dmat, ccb[i - 1].c_dmam);
1945 free(ccb, M_DEVBUF);
1946 }
1947
1948 struct ips_ccb *
ips_ccb_get(struct ips_softc * sc)1949 ips_ccb_get(struct ips_softc *sc)
1950 {
1951 struct ips_ccb *ccb;
1952
1953 mutex_enter(&sc->sc_ccb_mtx);
1954 if ((ccb = SLIST_FIRST(&sc->sc_ccbq_free)) != NULL) {
1955 SLIST_REMOVE_HEAD(&sc->sc_ccbq_free, c_link);
1956 ccb->c_flags = 0;
1957 ccb->c_xfer = NULL;
1958 bzero(ccb->c_cmdbva, sizeof(struct ips_cmdb));
1959 }
1960 mutex_exit(&sc->sc_ccb_mtx);
1961
1962 return (ccb);
1963 }
1964
1965 void
ips_ccb_put(struct ips_softc * sc,struct ips_ccb * ccb)1966 ips_ccb_put(struct ips_softc *sc, struct ips_ccb *ccb)
1967 {
1968 ccb->c_state = IPS_CCB_FREE;
1969 mutex_enter(&sc->sc_ccb_mtx);
1970 SLIST_INSERT_HEAD(&sc->sc_ccbq_free, ccb, c_link);
1971 mutex_exit(&sc->sc_ccb_mtx);
1972 }
1973
1974 int
ips_dmamem_alloc(struct dmamem * dm,bus_dma_tag_t tag,bus_size_t size)1975 ips_dmamem_alloc(struct dmamem *dm, bus_dma_tag_t tag, bus_size_t size)
1976 {
1977 int nsegs;
1978
1979 dm->dm_tag = tag;
1980 dm->dm_size = size;
1981
1982 if (bus_dmamap_create(tag, size, 1, size, 0,
1983 BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &dm->dm_map))
1984 return (1);
1985 if (bus_dmamem_alloc(tag, size, 0, 0, &dm->dm_seg, 1, &nsegs,
1986 BUS_DMA_NOWAIT))
1987 goto fail1;
1988 if (bus_dmamem_map(tag, &dm->dm_seg, 1, size, &dm->dm_vaddr,
1989 BUS_DMA_NOWAIT))
1990 goto fail2;
1991 if (bus_dmamap_load(tag, dm->dm_map, dm->dm_vaddr, size, NULL,
1992 BUS_DMA_NOWAIT))
1993 goto fail3;
1994
1995 return (0);
1996
1997 fail3:
1998 bus_dmamem_unmap(tag, dm->dm_vaddr, size);
1999 fail2:
2000 bus_dmamem_free(tag, &dm->dm_seg, 1);
2001 fail1:
2002 bus_dmamap_destroy(tag, dm->dm_map);
2003 return (1);
2004 }
2005
2006 void
ips_dmamem_free(struct dmamem * dm)2007 ips_dmamem_free(struct dmamem *dm)
2008 {
2009 bus_dmamap_unload(dm->dm_tag, dm->dm_map);
2010 bus_dmamem_unmap(dm->dm_tag, dm->dm_vaddr, dm->dm_size);
2011 bus_dmamem_free(dm->dm_tag, &dm->dm_seg, 1);
2012 bus_dmamap_destroy(dm->dm_tag, dm->dm_map);
2013 }
2014