This source file includes following definitions.
- ips_match
- ips_attach
- ips_scsi_cmd
- ips_cmd
- ips_poll
- ips_done
- ips_intr
- ips_getadapterinfo
- ips_getdriveinfo
- ips_flush
- ips_copperhead_exec
- ips_copperhead_init
- ips_copperhead_intren
- ips_copperhead_isintr
- ips_copperhead_reset
- ips_copperhead_status
- ips_morpheus_exec
- ips_morpheus_init
- ips_morpheus_intren
- ips_morpheus_isintr
- ips_morpheus_reset
- ips_morpheus_status
- ips_ccb_alloc
- ips_ccb_free
- ips_ccb_get
- ips_ccb_put
- ips_dmamem_alloc
- ips_dmamem_free
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 #include <sys/param.h>
24 #include <sys/systm.h>
25 #include <sys/buf.h>
26 #include <sys/device.h>
27 #include <sys/kernel.h>
28 #include <sys/malloc.h>
29 #include <sys/timeout.h>
30 #include <sys/queue.h>
31
32 #include <machine/bus.h>
33
34 #include <scsi/scsi_all.h>
35 #include <scsi/scsi_disk.h>
36 #include <scsi/scsiconf.h>
37
38 #include <dev/pci/pcidevs.h>
39 #include <dev/pci/pcireg.h>
40 #include <dev/pci/pcivar.h>
41
42 #define IPS_DEBUG
43
44
45 #define IPS_D_ERR 0x0001
46 #define IPS_D_INFO 0x0002
47 #define IPS_D_XFER 0x0004
48
49 #ifdef IPS_DEBUG
50 #define DPRINTF(a, b) do { if (ips_debug & (a)) printf b; } while (0)
51 int ips_debug = IPS_D_ERR;
52 #else
53 #define DPRINTF(a, b)
54 #endif
55
56 #define IPS_MAXDRIVES 8
57 #define IPS_MAXCHANS 4
58 #define IPS_MAXTARGETS 15
59 #define IPS_MAXCMDS 128
60
61 #define IPS_MAXFER (64 * 1024)
62 #define IPS_MAXSGS 16
63 #define IPS_MAXCMDSZ (IPS_CMDSZ + IPS_MAXSGS * IPS_SGSZ)
64
65 #define IPS_CMDSZ sizeof(struct ips_cmd)
66 #define IPS_SGSZ sizeof(struct ips_sg)
67 #define IPS_SECSZ 512
68
69
70 #define IPS_CMD_READ 0x02
71 #define IPS_CMD_WRITE 0x03
72 #define IPS_CMD_DCDB 0x04
73 #define IPS_CMD_GETADAPTERINFO 0x05
74 #define IPS_CMD_FLUSH 0x0a
75 #define IPS_CMD_ERRORTABLE 0x17
76 #define IPS_CMD_GETDRIVEINFO 0x19
77 #define IPS_CMD_RESETCHAN 0x1a
78 #define IPS_CMD_DOWNLOAD 0x20
79 #define IPS_CMD_RWBIOSFW 0x22
80 #define IPS_CMD_READCONF 0x38
81 #define IPS_CMD_GETSUBSYS 0x40
82 #define IPS_CMD_CONFIGSYNC 0x58
83 #define IPS_CMD_READ_SG 0x82
84 #define IPS_CMD_WRITE_SG 0x83
85 #define IPS_CMD_DCDB_SG 0x84
86 #define IPS_CMD_EXT_DCDB 0x95
87 #define IPS_CMD_EXT_DCDB_SG 0x96
88 #define IPS_CMD_RWNVRAMPAGE 0xbc
89 #define IPS_CMD_GETVERINFO 0xc6
90 #define IPS_CMD_FFDC 0xd7
91 #define IPS_CMD_SG 0x80
92
93
94 #define IPS_REG_HIS 0x08
95 #define IPS_REG_HIS_SCE 0x01
96 #define IPS_REG_HIS_EN 0x80
97 #define IPS_REG_CCSA 0x10
98 #define IPS_REG_CCC 0x14
99 #define IPS_REG_CCC_SEM 0x0008
100 #define IPS_REG_CCC_START 0x101a
101 #define IPS_REG_OIS 0x30
102 #define IPS_REG_OIS_PEND 0x0008
103 #define IPS_REG_OIM 0x34
104 #define IPS_REG_OIM_DS 0x0008
105 #define IPS_REG_IQP 0x40
106 #define IPS_REG_OQP 0x44
107
108 #define IPS_REG_STAT_ID(x) (((x) >> 8) & 0xff)
109 #define IPS_REG_STAT_BASIC(x) (((x) >> 16) & 0xff)
110 #define IPS_REG_STAT_GSC(x) (((x) >> 16) & 0x0f)
111 #define IPS_REG_STAT_EXT(x) (((x) >> 24) & 0xff)
112
113
114 struct ips_cmd {
115 u_int8_t code;
116 u_int8_t id;
117 u_int8_t drive;
118 u_int8_t sgcnt;
119 u_int32_t lba;
120 u_int32_t sgaddr;
121 u_int16_t seccnt;
122 u_int8_t seg4g;
123 u_int8_t esg;
124 u_int32_t ccsar;
125 u_int32_t cccr;
126 };
127
128
129 struct ips_sg {
130 u_int32_t addr;
131 u_int32_t size;
132 };
133
134
135 struct ips_adapterinfo {
136 u_int8_t drivecnt;
137 u_int8_t miscflag;
138 u_int8_t sltflag;
139 u_int8_t bstflag;
140 u_int8_t pwrchgcnt;
141 u_int8_t wrongaddrcnt;
142 u_int8_t unidentcnt;
143 u_int8_t nvramdevchgcnt;
144 u_int8_t codeblkver[8];
145 u_int8_t bootblkver[8];
146 u_int32_t drivesize[IPS_MAXDRIVES];
147 u_int8_t cmdcnt;
148 u_int8_t maxphysdevs;
149 u_int16_t flashrepgmcnt;
150 u_int8_t defunctdiskcnt;
151 u_int8_t rebuildflag;
152 u_int8_t offdrivecnt;
153 u_int8_t critdrivecnt;
154 u_int16_t confupdcnt;
155 u_int8_t blkflag;
156 u_int8_t __reserved;
157 u_int16_t deaddisk[IPS_MAXCHANS * (IPS_MAXTARGETS + 1)];
158 };
159
160 struct ips_driveinfo {
161 u_int8_t drivecnt;
162 u_int8_t __reserved[3];
163 struct ips_drive {
164 u_int8_t id;
165 u_int8_t __reserved;
166 u_int8_t raid;
167 u_int8_t state;
168 u_int32_t seccnt;
169 } drive[IPS_MAXDRIVES];
170 };
171
172
173 struct ips_ccb {
174 int c_id;
175 int c_flags;
176 #define IPS_CCB_READ 0x0001
177 #define IPS_CCB_WRITE 0x0002
178 #define IPS_CCB_POLL 0x0004
179 #define IPS_CCB_RUN 0x0008
180
181 void * c_cmdva;
182 paddr_t c_cmdpa;
183 bus_dmamap_t c_dmam;
184 struct scsi_xfer * c_xfer;
185 int c_stat;
186 int c_estat;
187
188 TAILQ_ENTRY(ips_ccb) c_link;
189 };
190
191
192 TAILQ_HEAD(ips_ccbq, ips_ccb);
193
194
195 struct dmamem {
196 bus_dma_tag_t dm_tag;
197 bus_dmamap_t dm_map;
198 bus_dma_segment_t dm_seg;
199 bus_size_t dm_size;
200 void * dm_vaddr;
201 #define dm_paddr dm_seg.ds_addr
202 };
203
204 struct ips_softc {
205 struct device sc_dev;
206
207 struct scsi_link sc_scsi_link;
208
209 bus_space_tag_t sc_iot;
210 bus_space_handle_t sc_ioh;
211 bus_dma_tag_t sc_dmat;
212
213 const struct ips_chipset *sc_chip;
214
215 struct ips_driveinfo sc_di;
216 int sc_nunits;
217
218 struct dmamem sc_cmdm;
219
220 struct ips_ccb * sc_ccb;
221 int sc_nccbs;
222 struct ips_ccbq sc_ccbq_free;
223 struct ips_ccbq sc_ccbq_run;
224 };
225
226 int ips_match(struct device *, void *, void *);
227 void ips_attach(struct device *, struct device *, void *);
228
229 int ips_scsi_cmd(struct scsi_xfer *);
230
231 int ips_cmd(struct ips_softc *, int, int, u_int32_t, void *, size_t, int,
232 struct scsi_xfer *);
233 int ips_poll(struct ips_softc *, struct ips_ccb *);
234 void ips_done(struct ips_softc *, struct ips_ccb *);
235 int ips_intr(void *);
236
237 int ips_getadapterinfo(struct ips_softc *, struct ips_adapterinfo *);
238 int ips_getdriveinfo(struct ips_softc *, struct ips_driveinfo *);
239 int ips_flush(struct ips_softc *);
240
241 void ips_copperhead_exec(struct ips_softc *, struct ips_ccb *);
242 void ips_copperhead_init(struct ips_softc *);
243 void ips_copperhead_intren(struct ips_softc *);
244 int ips_copperhead_isintr(struct ips_softc *);
245 int ips_copperhead_reset(struct ips_softc *);
246 u_int32_t ips_copperhead_status(struct ips_softc *);
247
248 void ips_morpheus_exec(struct ips_softc *, struct ips_ccb *);
249 void ips_morpheus_init(struct ips_softc *);
250 void ips_morpheus_intren(struct ips_softc *);
251 int ips_morpheus_isintr(struct ips_softc *);
252 int ips_morpheus_reset(struct ips_softc *);
253 u_int32_t ips_morpheus_status(struct ips_softc *);
254
255 struct ips_ccb *ips_ccb_alloc(struct ips_softc *, int);
256 void ips_ccb_free(struct ips_softc *, struct ips_ccb *, int);
257 struct ips_ccb *ips_ccb_get(struct ips_softc *);
258 void ips_ccb_put(struct ips_softc *, struct ips_ccb *);
259
260 int ips_dmamem_alloc(struct dmamem *, bus_dma_tag_t, bus_size_t);
261 void ips_dmamem_free(struct dmamem *);
262
263 struct cfattach ips_ca = {
264 sizeof(struct ips_softc),
265 ips_match,
266 ips_attach
267 };
268
269 struct cfdriver ips_cd = {
270 NULL, "ips", DV_DULL
271 };
272
273 static struct scsi_adapter ips_scsi_adapter = {
274 ips_scsi_cmd,
275 minphys,
276 NULL,
277 NULL,
278 NULL
279 };
280
281 static struct scsi_device ips_scsi_device = {
282 NULL,
283 NULL,
284 NULL,
285 NULL
286 };
287
288 static const struct pci_matchid ips_ids[] = {
289 { PCI_VENDOR_IBM, PCI_PRODUCT_IBM_SERVERAID },
290 { PCI_VENDOR_IBM, PCI_PRODUCT_IBM_SERVERAID2 },
291 { PCI_VENDOR_ADP2, PCI_PRODUCT_ADP2_SERVERAID }
292 };
293
294 static const struct ips_chipset {
295 const char * ic_name;
296 int ic_bar;
297
298 void (*ic_exec)(struct ips_softc *, struct ips_ccb *);
299 void (*ic_init)(struct ips_softc *);
300 void (*ic_intren)(struct ips_softc *);
301 int (*ic_isintr)(struct ips_softc *);
302 int (*ic_reset)(struct ips_softc *);
303 u_int32_t (*ic_status)(struct ips_softc *);
304 } ips_chips[] = {
305 {
306 "Copperhead",
307 0x14,
308 ips_copperhead_exec,
309 ips_copperhead_init,
310 ips_copperhead_intren,
311 ips_copperhead_isintr,
312 ips_copperhead_reset,
313 ips_copperhead_status
314 },
315 {
316 "Morpheus",
317 0x10,
318 ips_morpheus_exec,
319 ips_morpheus_init,
320 ips_morpheus_intren,
321 ips_morpheus_isintr,
322 ips_morpheus_reset,
323 ips_morpheus_status
324 }
325 };
326
327 enum {
328 IPS_CHIP_COPPERHEAD = 0,
329 IPS_CHIP_MORPHEUS
330 };
331
332 #define ips_exec(s, c) (s)->sc_chip->ic_exec((s), (c))
333 #define ips_init(s) (s)->sc_chip->ic_init((s))
334 #define ips_intren(s) (s)->sc_chip->ic_intren((s))
335 #define ips_isintr(s) (s)->sc_chip->ic_isintr((s))
336 #define ips_reset(s) (s)->sc_chip->ic_reset((s))
337 #define ips_status(s) (s)->sc_chip->ic_status((s))
338
339 int
340 ips_match(struct device *parent, void *match, void *aux)
341 {
342 return (pci_matchbyid(aux, ips_ids,
343 sizeof(ips_ids) / sizeof(ips_ids[0])));
344 }
345
346 void
347 ips_attach(struct device *parent, struct device *self, void *aux)
348 {
349 struct ips_softc *sc = (struct ips_softc *)self;
350 struct pci_attach_args *pa = aux;
351 struct ips_ccb ccb0;
352 struct scsibus_attach_args saa;
353 struct ips_adapterinfo ai;
354 pcireg_t maptype;
355 bus_size_t iosize;
356 pci_intr_handle_t ih;
357 const char *intrstr;
358 int i;
359
360 sc->sc_dmat = pa->pa_dmat;
361
362
363 switch (PCI_PRODUCT(pa->pa_id)) {
364 case PCI_PRODUCT_IBM_SERVERAID:
365 sc->sc_chip = &ips_chips[IPS_CHIP_COPPERHEAD];
366 break;
367 case PCI_PRODUCT_IBM_SERVERAID2:
368 case PCI_PRODUCT_ADP2_SERVERAID:
369 sc->sc_chip = &ips_chips[IPS_CHIP_MORPHEUS];
370 break;
371 default:
372 printf(": unsupported chipset\n");
373 return;
374 }
375
376
377 maptype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, sc->sc_chip->ic_bar);
378 if (pci_mapreg_map(pa, sc->sc_chip->ic_bar, maptype, 0, &sc->sc_iot,
379 &sc->sc_ioh, NULL, &iosize, 0)) {
380 printf(": can't map registers\n");
381 return;
382 }
383
384
385 ips_init(sc);
386
387
388 if (ips_dmamem_alloc(&sc->sc_cmdm, sc->sc_dmat,
389 IPS_MAXCMDS * IPS_MAXCMDSZ)) {
390 printf(": can't allocate command buffer\n");
391 goto fail1;
392 }
393
394
395 sc->sc_nccbs = 1;
396 sc->sc_ccb = &ccb0;
397 bzero(&ccb0, sizeof(ccb0));
398 ccb0.c_cmdva = sc->sc_cmdm.dm_vaddr;
399 ccb0.c_cmdpa = sc->sc_cmdm.dm_paddr;
400 if (bus_dmamap_create(sc->sc_dmat, IPS_MAXFER, IPS_MAXSGS,
401 IPS_MAXFER, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
402 &ccb0.c_dmam)) {
403 printf(": can't bootstrap CCB queue\n");
404 goto fail2;
405 }
406 TAILQ_INIT(&sc->sc_ccbq_free);
407 TAILQ_INIT(&sc->sc_ccbq_run);
408 TAILQ_INSERT_TAIL(&sc->sc_ccbq_free, &ccb0, c_link);
409
410
411 if (ips_getadapterinfo(sc, &ai)) {
412 printf(": can't get adapter info\n");
413 bus_dmamap_destroy(sc->sc_dmat, ccb0.c_dmam);
414 goto fail2;
415 }
416
417
418 if (ips_getdriveinfo(sc, &sc->sc_di)) {
419 printf(": can't get logical drives info\n");
420 bus_dmamap_destroy(sc->sc_dmat, ccb0.c_dmam);
421 goto fail2;
422 }
423 sc->sc_nunits = sc->sc_di.drivecnt;
424
425 bus_dmamap_destroy(sc->sc_dmat, ccb0.c_dmam);
426
427
428 sc->sc_nccbs = ai.cmdcnt;
429 if ((sc->sc_ccb = ips_ccb_alloc(sc, sc->sc_nccbs)) == NULL) {
430 printf(": can't allocate CCB queue\n");
431 goto fail2;
432 }
433 TAILQ_INIT(&sc->sc_ccbq_free);
434 TAILQ_INIT(&sc->sc_ccbq_run);
435 for (i = 0; i < sc->sc_nccbs; i++)
436 TAILQ_INSERT_TAIL(&sc->sc_ccbq_free,
437 &sc->sc_ccb[i], c_link);
438
439
440 if (pci_intr_map(pa, &ih)) {
441 printf(": can't map interrupt\n");
442 goto fail3;
443 }
444 intrstr = pci_intr_string(pa->pa_pc, ih);
445 if (pci_intr_establish(pa->pa_pc, ih, IPL_BIO, ips_intr, sc,
446 sc->sc_dev.dv_xname) == NULL) {
447 printf(": can't establish interrupt");
448 if (intrstr != NULL)
449 printf(" at %s", intrstr);
450 printf("\n");
451 goto fail3;
452 }
453 printf(": %s\n", intrstr);
454
455
456 printf("%s", sc->sc_dev.dv_xname);
457 printf(": %s", sc->sc_chip->ic_name);
458 printf(", firmware %c%c%c%c%c%c%c",
459 ai.codeblkver[0], ai.codeblkver[1], ai.codeblkver[2],
460 ai.codeblkver[3], ai.codeblkver[4], ai.codeblkver[5],
461 ai.codeblkver[6]);
462 printf(", bootblock %c%c%c%c%c%c%c",
463 ai.bootblkver[0], ai.bootblkver[1], ai.bootblkver[2],
464 ai.bootblkver[3], ai.bootblkver[4], ai.bootblkver[5],
465 ai.bootblkver[6]);
466 printf(", %d CCBs, %d units", sc->sc_nccbs, sc->sc_nunits);
467 printf("\n");
468
469
470 if (sc->sc_nunits > 0)
471 sc->sc_scsi_link.openings = sc->sc_nccbs / sc->sc_nunits;
472 sc->sc_scsi_link.adapter_target = sc->sc_nunits;
473 sc->sc_scsi_link.adapter_buswidth = sc->sc_nunits;
474 sc->sc_scsi_link.device = &ips_scsi_device;
475 sc->sc_scsi_link.adapter = &ips_scsi_adapter;
476 sc->sc_scsi_link.adapter_softc = sc;
477
478 bzero(&saa, sizeof(saa));
479 saa.saa_sc_link = &sc->sc_scsi_link;
480 config_found(self, &saa, scsiprint);
481
482
483 ips_intren(sc);
484
485 return;
486 fail3:
487 ips_ccb_free(sc, sc->sc_ccb, sc->sc_nccbs);
488 fail2:
489 ips_dmamem_free(&sc->sc_cmdm);
490 fail1:
491 bus_space_unmap(sc->sc_iot, sc->sc_ioh, iosize);
492 }
493
494 int
495 ips_scsi_cmd(struct scsi_xfer *xs)
496 {
497 struct scsi_link *link = xs->sc_link;
498 struct ips_softc *sc = link->adapter_softc;
499 struct ips_drive *drive;
500 struct scsi_inquiry_data *id;
501 struct scsi_read_cap_data *rcd;
502 struct scsi_sense_data *sd;
503 struct scsi_rw *rw;
504 struct scsi_rw_big *rwb;
505 int target = link->target;
506 u_int32_t blkno, blkcnt;
507 int cmd, error, flags, s;
508
509 if (target >= sc->sc_nunits || link->lun != 0) {
510 DPRINTF(IPS_D_INFO, ("%s: invalid scsi command, "
511 "target %d, lun %d\n", sc->sc_dev.dv_xname,
512 target, link->lun));
513 xs->error = XS_DRIVER_STUFFUP;
514 s = splbio();
515 scsi_done(xs);
516 splx(s);
517 return (COMPLETE);
518 }
519
520 s = splbio();
521 drive = &sc->sc_di.drive[target];
522 xs->error = XS_NOERROR;
523
524
525 switch (xs->cmd->opcode) {
526 case READ_BIG:
527 case READ_COMMAND:
528 case WRITE_BIG:
529 case WRITE_COMMAND:
530 if (xs->cmdlen == sizeof(struct scsi_rw)) {
531 rw = (void *)xs->cmd;
532 blkno = _3btol(rw->addr) &
533 (SRW_TOPADDR << 16 | 0xffff);
534 blkcnt = rw->length ? rw->length : 0x100;
535 } else {
536 rwb = (void *)xs->cmd;
537 blkno = _4btol(rwb->addr);
538 blkcnt = _2btol(rwb->length);
539 }
540
541 if (blkno >= letoh32(drive->seccnt) || blkno + blkcnt >
542 letoh32(drive->seccnt)) {
543 DPRINTF(IPS_D_ERR, ("%s: invalid scsi command, "
544 "blkno %u, blkcnt %u\n", sc->sc_dev.dv_xname,
545 blkno, blkcnt));
546 xs->error = XS_DRIVER_STUFFUP;
547 scsi_done(xs);
548 break;
549 }
550
551 if (xs->flags & SCSI_DATA_IN) {
552 cmd = IPS_CMD_READ;
553 flags = IPS_CCB_READ;
554 } else {
555 cmd = IPS_CMD_WRITE;
556 flags = IPS_CCB_WRITE;
557 }
558 if (xs->flags & SCSI_POLL)
559 flags |= IPS_CCB_POLL;
560
561 if ((error = ips_cmd(sc, cmd, target, blkno, xs->data,
562 blkcnt * IPS_SECSZ, flags, xs))) {
563 if (error == ENOMEM) {
564 splx(s);
565 return (NO_CCB);
566 } else if (flags & IPS_CCB_POLL) {
567 splx(s);
568 return (TRY_AGAIN_LATER);
569 } else {
570 xs->error = XS_DRIVER_STUFFUP;
571 scsi_done(xs);
572 break;
573 }
574 }
575
576 splx(s);
577 if (flags & IPS_CCB_POLL)
578 return (COMPLETE);
579 else
580 return (SUCCESSFULLY_QUEUED);
581 case INQUIRY:
582 id = (void *)xs->data;
583 bzero(id, sizeof(*id));
584 id->device = T_DIRECT;
585 id->version = 2;
586 id->response_format = 2;
587 id->additional_length = 32;
588 strlcpy(id->vendor, "IBM ", sizeof(id->vendor));
589 snprintf(id->product, sizeof(id->product),
590 "ServeRAID RAID%d #%02d", drive->raid, target);
591 strlcpy(id->revision, " ", sizeof(id->revision));
592 break;
593 case READ_CAPACITY:
594 rcd = (void *)xs->data;
595 bzero(rcd, sizeof(*rcd));
596 _lto4b(letoh32(drive->seccnt) - 1, rcd->addr);
597 _lto4b(IPS_SECSZ, rcd->length);
598 break;
599 case REQUEST_SENSE:
600 sd = (void *)xs->data;
601 bzero(sd, sizeof(*sd));
602 sd->error_code = SSD_ERRCODE_CURRENT;
603 sd->flags = SKEY_NO_SENSE;
604 break;
605 case SYNCHRONIZE_CACHE:
606 if (ips_flush(sc))
607 xs->error = XS_DRIVER_STUFFUP;
608 break;
609 case PREVENT_ALLOW:
610 case START_STOP:
611 case TEST_UNIT_READY:
612 break;
613 default:
614 DPRINTF(IPS_D_INFO, ("%s: unsupported scsi command 0x%02x\n",
615 sc->sc_dev.dv_xname, xs->cmd->opcode));
616 xs->error = XS_DRIVER_STUFFUP;
617 }
618 scsi_done(xs);
619 splx(s);
620
621 return (COMPLETE);
622 }
623
624 int
625 ips_cmd(struct ips_softc *sc, int code, int drive, u_int32_t lba, void *data,
626 size_t size, int flags, struct scsi_xfer *xs)
627 {
628 struct ips_cmd *cmd;
629 struct ips_sg *sg;
630 struct ips_ccb *ccb;
631 int nsegs, i, error = 0;
632
633 DPRINTF(IPS_D_XFER, ("%s: cmd code 0x%02x, drive %d, lba %u, "
634 "size %lu, flags 0x%02x\n", sc->sc_dev.dv_xname, code, drive, lba,
635 (u_long)size, flags));
636
637
638 if ((ccb = ips_ccb_get(sc)) == NULL) {
639 DPRINTF(IPS_D_ERR, ("%s: no free CCB\n", sc->sc_dev.dv_xname));
640 return (ENOMEM);
641 }
642
643 ccb->c_flags = flags;
644 ccb->c_xfer = xs;
645
646
647 cmd = ccb->c_cmdva;
648 cmd->code = code;
649 cmd->id = ccb->c_id;
650 cmd->drive = drive;
651 cmd->lba = htole32(lba);
652 cmd->seccnt = htole16(howmany(size, IPS_SECSZ));
653
654 if (size > 0) {
655
656 if (bus_dmamap_load(sc->sc_dmat, ccb->c_dmam, data, size,
657 NULL, BUS_DMA_NOWAIT)) {
658 printf("%s: can't load DMA map\n",
659 sc->sc_dev.dv_xname);
660 return (1);
661 }
662 bus_dmamap_sync(sc->sc_dmat, ccb->c_dmam, 0,
663 ccb->c_dmam->dm_mapsize,
664 flags & IPS_CCB_READ ? BUS_DMASYNC_PREREAD :
665 BUS_DMASYNC_PREWRITE);
666
667 if ((nsegs = ccb->c_dmam->dm_nsegs) > IPS_MAXSGS) {
668 printf("%s: too many DMA segments\n",
669 sc->sc_dev.dv_xname);
670 return (1);
671 }
672
673 if (nsegs > 1) {
674 cmd->code |= IPS_CMD_SG;
675 cmd->sgcnt = nsegs;
676 cmd->sgaddr = htole32(ccb->c_cmdpa + IPS_CMDSZ);
677
678
679 sg = (void *)(cmd + 1);
680 for (i = 0; i < nsegs; i++) {
681 sg[i].addr =
682 htole32(ccb->c_dmam->dm_segs[i].ds_addr);
683 sg[i].size =
684 htole32(ccb->c_dmam->dm_segs[i].ds_len);
685 }
686 } else {
687 cmd->sgcnt = 0;
688 cmd->sgaddr = htole32(ccb->c_dmam->dm_segs[0].ds_addr);
689 }
690 }
691
692
693 DPRINTF(IPS_D_XFER, ("%s: run command 0x%02x\n", sc->sc_dev.dv_xname,
694 ccb->c_id));
695 ccb->c_flags |= IPS_CCB_RUN;
696 TAILQ_INSERT_TAIL(&sc->sc_ccbq_run, ccb, c_link);
697 ips_exec(sc, ccb);
698
699 if (flags & IPS_CCB_POLL)
700
701 error = ips_poll(sc, ccb);
702
703 return (error);
704 }
705
706 int
707 ips_poll(struct ips_softc *sc, struct ips_ccb *c)
708 {
709 struct ips_ccb *ccb = NULL;
710 u_int32_t status;
711 int id, timeout;
712
713 while (ccb != c) {
714 for (timeout = 100; timeout-- > 0; delay(100)) {
715 if ((status = ips_status(sc)) == 0xffffffff)
716 continue;
717 id = IPS_REG_STAT_ID(status);
718 if (id >= sc->sc_nccbs) {
719 DPRINTF(IPS_D_ERR, ("%s: invalid command "
720 "0x%02x\n", sc->sc_dev.dv_xname, id));
721 continue;
722 }
723 break;
724 }
725 if (timeout < 0) {
726 printf("%s: poll timeout\n", sc->sc_dev.dv_xname);
727 return (EBUSY);
728 }
729 ccb = &sc->sc_ccb[id];
730 ccb->c_stat = IPS_REG_STAT_GSC(status);
731 ccb->c_estat = IPS_REG_STAT_EXT(status);
732 ips_done(sc, ccb);
733 }
734
735 return (0);
736 }
737
738 void
739 ips_done(struct ips_softc *sc, struct ips_ccb *ccb)
740 {
741 struct scsi_xfer *xs = ccb->c_xfer;
742 int flags = ccb->c_flags;
743 int error = 0;
744
745 if ((flags & IPS_CCB_RUN) == 0) {
746 printf("%s: command 0x%02x not run\n", sc->sc_dev.dv_xname,
747 ccb->c_id);
748 if (xs != NULL) {
749 xs->error = XS_DRIVER_STUFFUP;
750 scsi_done(xs);
751 }
752 return;
753 }
754
755 if (flags & (IPS_CCB_READ | IPS_CCB_WRITE)) {
756 bus_dmamap_sync(sc->sc_dmat, ccb->c_dmam, 0,
757 ccb->c_dmam->dm_mapsize, flags & IPS_CCB_READ ?
758 BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
759 bus_dmamap_unload(sc->sc_dmat, ccb->c_dmam);
760 }
761
762 if (ccb->c_stat) {
763 printf("%s: ", sc->sc_dev.dv_xname);
764 if (ccb->c_stat == 1) {
765 printf("recovered error\n");
766 } else {
767 printf("error\n");
768 error = 1;
769 }
770 }
771
772
773 TAILQ_REMOVE(&sc->sc_ccbq_run, ccb, c_link);
774 ips_ccb_put(sc, ccb);
775
776 if (xs != NULL) {
777 if (error)
778 xs->error = XS_DRIVER_STUFFUP;
779 else
780 xs->resid = 0;
781 xs->flags |= ITSDONE;
782 scsi_done(xs);
783 }
784 }
785
786 int
787 ips_intr(void *arg)
788 {
789 struct ips_softc *sc = arg;
790 struct ips_ccb *ccb;
791 u_int32_t status;
792 int id;
793
794 if (!ips_isintr(sc))
795 return (0);
796
797
798 while ((status = ips_status(sc)) != 0xffffffff) {
799 DPRINTF(IPS_D_XFER, ("%s: intr status 0x%08x\n",
800 sc->sc_dev.dv_xname, status));
801
802 id = IPS_REG_STAT_ID(status);
803 if (id >= sc->sc_nccbs) {
804 DPRINTF(IPS_D_ERR, ("%s: invalid command %d\n",
805 sc->sc_dev.dv_xname, id));
806 continue;
807 }
808 ccb = &sc->sc_ccb[id];
809 ccb->c_stat = IPS_REG_STAT_GSC(status);
810 ccb->c_estat = IPS_REG_STAT_EXT(status);
811 ips_done(sc, ccb);
812 }
813
814 return (1);
815 }
816
817 int
818 ips_getadapterinfo(struct ips_softc *sc, struct ips_adapterinfo *ai)
819 {
820 return (ips_cmd(sc, IPS_CMD_GETADAPTERINFO, 0, 0, ai, sizeof(*ai),
821 IPS_CCB_READ | IPS_CCB_POLL, NULL));
822 }
823
824 int
825 ips_getdriveinfo(struct ips_softc *sc, struct ips_driveinfo *di)
826 {
827 return (ips_cmd(sc, IPS_CMD_GETDRIVEINFO, 0, 0, di, sizeof(*di),
828 IPS_CCB_READ | IPS_CCB_POLL, NULL));
829 }
830
831 int
832 ips_flush(struct ips_softc *sc)
833 {
834 return (ips_cmd(sc, IPS_CMD_FLUSH, 0, 0, NULL, 0, IPS_CCB_POLL, NULL));
835 }
836
837 void
838 ips_copperhead_exec(struct ips_softc *sc, struct ips_ccb *ccb)
839 {
840 u_int32_t reg;
841 int timeout;
842
843 for (timeout = 100; timeout-- > 0; delay(100)) {
844 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, IPS_REG_CCC);
845 if ((reg & IPS_REG_CCC_SEM) == 0)
846 break;
847 }
848 if (timeout < 0) {
849 printf("%s: semaphore timeout\n", sc->sc_dev.dv_xname);
850 return;
851 }
852
853 bus_space_write_4(sc->sc_iot, sc->sc_ioh, IPS_REG_CCSA, ccb->c_cmdpa);
854 bus_space_write_2(sc->sc_iot, sc->sc_ioh, IPS_REG_CCC,
855 IPS_REG_CCC_START);
856 }
857
858 void
859 ips_copperhead_init(struct ips_softc *sc)
860 {
861
862 }
863
864 void
865 ips_copperhead_intren(struct ips_softc *sc)
866 {
867 bus_space_write_1(sc->sc_iot, sc->sc_ioh, IPS_REG_HIS, IPS_REG_HIS_EN);
868 }
869
870 int
871 ips_copperhead_isintr(struct ips_softc *sc)
872 {
873 u_int8_t reg;
874
875 reg = bus_space_read_1(sc->sc_iot, sc->sc_ioh, IPS_REG_HIS);
876 bus_space_write_1(sc->sc_iot, sc->sc_ioh, IPS_REG_HIS, reg);
877 if (reg != 0xff && (reg & IPS_REG_HIS_SCE))
878 return (1);
879
880 return (0);
881 }
882
883 int
884 ips_copperhead_reset(struct ips_softc *sc)
885 {
886
887 return (0);
888 }
889
890 u_int32_t
891 ips_copperhead_status(struct ips_softc *sc)
892 {
893
894 return (0);
895 }
896
897 void
898 ips_morpheus_exec(struct ips_softc *sc, struct ips_ccb *ccb)
899 {
900 bus_space_write_4(sc->sc_iot, sc->sc_ioh, IPS_REG_IQP, ccb->c_cmdpa);
901 }
902
903 void
904 ips_morpheus_init(struct ips_softc *sc)
905 {
906
907 }
908
909 void
910 ips_morpheus_intren(struct ips_softc *sc)
911 {
912 u_int32_t reg;
913
914 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, IPS_REG_OIM);
915 reg &= ~IPS_REG_OIM_DS;
916 bus_space_write_4(sc->sc_iot, sc->sc_ioh, IPS_REG_OIM, reg);
917 }
918
919 int
920 ips_morpheus_isintr(struct ips_softc *sc)
921 {
922 u_int32_t reg;
923
924 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, IPS_REG_OIS);
925 DPRINTF(IPS_D_XFER, ("%s: isintr 0x%08x\n", sc->sc_dev.dv_xname, reg));
926
927 return (reg & IPS_REG_OIS_PEND);
928 }
929
930 int
931 ips_morpheus_reset(struct ips_softc *sc)
932 {
933
934 return (0);
935 }
936
937 u_int32_t
938 ips_morpheus_status(struct ips_softc *sc)
939 {
940 u_int32_t reg;
941
942 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, IPS_REG_OQP);
943 DPRINTF(IPS_D_XFER, ("%s: status 0x%08x\n", sc->sc_dev.dv_xname, reg));
944
945 return (reg);
946 }
947
948 struct ips_ccb *
949 ips_ccb_alloc(struct ips_softc *sc, int n)
950 {
951 struct ips_ccb *ccb;
952 int i;
953
954 if ((ccb = malloc(n * sizeof(*ccb), M_DEVBUF, M_NOWAIT)) == NULL)
955 return (NULL);
956 bzero(ccb, n * sizeof(*ccb));
957
958 for (i = 0; i < n; i++) {
959 ccb[i].c_id = i;
960 ccb[i].c_cmdva = (char *)sc->sc_cmdm.dm_vaddr +
961 i * IPS_MAXCMDSZ;
962 ccb[i].c_cmdpa = sc->sc_cmdm.dm_paddr + i * IPS_MAXCMDSZ;
963 if (bus_dmamap_create(sc->sc_dmat, IPS_MAXFER, IPS_MAXSGS,
964 IPS_MAXFER, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
965 &ccb[i].c_dmam))
966 goto fail;
967 }
968
969 return (ccb);
970 fail:
971 for (; i > 0; i--)
972 bus_dmamap_destroy(sc->sc_dmat, ccb[i - 1].c_dmam);
973 free(ccb, M_DEVBUF);
974 return (NULL);
975 }
976
977 void
978 ips_ccb_free(struct ips_softc *sc, struct ips_ccb *ccb, int n)
979 {
980 int i;
981
982 for (i = 0; i < n; i++)
983 bus_dmamap_destroy(sc->sc_dmat, ccb[i - 1].c_dmam);
984 free(ccb, M_DEVBUF);
985 }
986
987 struct ips_ccb *
988 ips_ccb_get(struct ips_softc *sc)
989 {
990 struct ips_ccb *ccb;
991
992 if ((ccb = TAILQ_FIRST(&sc->sc_ccbq_free)) != NULL)
993 TAILQ_REMOVE(&sc->sc_ccbq_free, ccb, c_link);
994
995 return (ccb);
996 }
997
998 void
999 ips_ccb_put(struct ips_softc *sc, struct ips_ccb *ccb)
1000 {
1001 ccb->c_flags = 0;
1002 ccb->c_xfer = NULL;
1003 TAILQ_INSERT_TAIL(&sc->sc_ccbq_free, ccb, c_link);
1004 }
1005
1006 int
1007 ips_dmamem_alloc(struct dmamem *dm, bus_dma_tag_t tag, bus_size_t size)
1008 {
1009 int nsegs;
1010
1011 dm->dm_tag = tag;
1012 dm->dm_size = size;
1013
1014 if (bus_dmamap_create(tag, size, 1, size, 0,
1015 BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &dm->dm_map))
1016 return (1);
1017 if (bus_dmamem_alloc(tag, size, 0, 0, &dm->dm_seg, 1, &nsegs,
1018 BUS_DMA_NOWAIT))
1019 goto fail1;
1020 if (bus_dmamem_map(tag, &dm->dm_seg, 1, size, (caddr_t *)&dm->dm_vaddr,
1021 BUS_DMA_NOWAIT))
1022 goto fail2;
1023 if (bus_dmamap_load(tag, dm->dm_map, dm->dm_vaddr, size, NULL,
1024 BUS_DMA_NOWAIT))
1025 goto fail3;
1026
1027 return (0);
1028
1029 fail3:
1030 bus_dmamem_unmap(tag, dm->dm_vaddr, size);
1031 fail2:
1032 bus_dmamem_free(tag, &dm->dm_seg, 1);
1033 fail1:
1034 bus_dmamap_destroy(tag, dm->dm_map);
1035 return (1);
1036 }
1037
1038 void
1039 ips_dmamem_free(struct dmamem *dm)
1040 {
1041 bus_dmamap_unload(dm->dm_tag, dm->dm_map);
1042 bus_dmamem_unmap(dm->dm_tag, dm->dm_vaddr, dm->dm_size);
1043 bus_dmamem_free(dm->dm_tag, &dm->dm_seg, 1);
1044 bus_dmamap_destroy(dm->dm_tag, dm->dm_map);
1045 }