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