This source file includes following definitions.
- sr_match
- sr_attach
- sr_detach
- sr_activate
- sr_minphys
- sr_copy_internal_data
- sr_alloc_ccb
- sr_free_ccb
- sr_get_ccb
- sr_put_ccb
- sr_alloc_wu
- sr_free_wu
- sr_put_wu
- sr_get_wu
- sr_scsi_cmd
- sr_scsi_ioctl
- sr_ioctl
- sr_ioctl_inq
- sr_ioctl_vol
- sr_ioctl_disk
- sr_ioctl_setstate
- sr_ioctl_createraid
- sr_open_chunks
- sr_read_meta
- sr_create_chunk_meta
- sr_unwind_chunks
- sr_free_discipline
- sr_shutdown_discipline
- sr_raid_inquiry
- sr_raid_read_cap
- sr_raid_tur
- sr_raid_request_sense
- sr_raid_start_stop
- sr_raid_sync
- sr_raid_startwu
- sr_raid_set_chunk_state
- sr_raid_set_vol_state
- sr_checksum
- sr_get_uuid
- sr_print_uuid
- sr_clear_metadata
- sr_already_assembled
- sr_save_metadata_callback
- sr_save_metadata
- sr_boot_assembly
- sr_validate_metadata
- sr_shutdown
- sr_create_sensors
- sr_delete_sensors
- sr_refresh_sensors
- sr_print_stats
- sr_print_metadata
- sr_raid1_alloc_resources
- sr_raid1_free_resources
- sr_raid1_rw
- sr_raid1_intr
- sr_raid1_recreate_wu
- sr_raidc_getcryptop
- sr_raidc_putcryptop
- sr_raidc_alloc_resources
- sr_raidc_free_resources
- sr_raidc_rw
- sr_raidc_rw2
- sr_raidc_intr
- sr_raidc_intr2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 #include "bio.h"
19
20 #include <sys/param.h>
21 #include <sys/systm.h>
22 #include <sys/buf.h>
23 #include <sys/device.h>
24 #include <sys/ioctl.h>
25 #include <sys/proc.h>
26 #include <sys/malloc.h>
27 #include <sys/kernel.h>
28 #include <sys/disk.h>
29 #include <sys/rwlock.h>
30 #include <sys/queue.h>
31 #include <sys/fcntl.h>
32 #include <sys/disklabel.h>
33 #include <sys/mount.h>
34 #include <sys/sensors.h>
35 #include <sys/stat.h>
36 #include <sys/conf.h>
37 #include <sys/uio.h>
38
39 #include <crypto/cryptodev.h>
40
41 #include <scsi/scsi_all.h>
42 #include <scsi/scsiconf.h>
43 #include <scsi/scsi_disk.h>
44
45 #include <dev/softraidvar.h>
46 #include <dev/rndvar.h>
47
48
49
50 #ifdef SR_DEBUG
51 #define SR_FANCY_STATS
52 uint32_t sr_debug = 0
53
54
55
56
57
58
59
60
61
62 ;
63 #endif
64
65 int sr_match(struct device *, void *, void *);
66 void sr_attach(struct device *, struct device *, void *);
67 int sr_detach(struct device *, int);
68 int sr_activate(struct device *, enum devact);
69
70 struct cfattach softraid_ca = {
71 sizeof(struct sr_softc), sr_match, sr_attach, sr_detach,
72 sr_activate
73 };
74
75 struct cfdriver softraid_cd = {
76 NULL, "softraid", DV_DULL
77 };
78
79 int sr_scsi_cmd(struct scsi_xfer *);
80 void sr_minphys(struct buf *bp);
81 void sr_copy_internal_data(struct scsi_xfer *,
82 void *, size_t);
83 int sr_scsi_ioctl(struct scsi_link *, u_long,
84 caddr_t, int, struct proc *);
85 int sr_ioctl(struct device *, u_long, caddr_t);
86 int sr_ioctl_inq(struct sr_softc *, struct bioc_inq *);
87 int sr_ioctl_vol(struct sr_softc *, struct bioc_vol *);
88 int sr_ioctl_disk(struct sr_softc *, struct bioc_disk *);
89 int sr_ioctl_setstate(struct sr_softc *,
90 struct bioc_setstate *);
91 int sr_ioctl_createraid(struct sr_softc *,
92 struct bioc_createraid *, int);
93 int sr_open_chunks(struct sr_softc *,
94 struct sr_chunk_head *, dev_t *, int);
95 int sr_read_meta(struct sr_discipline *);
96 int sr_create_chunk_meta(struct sr_softc *,
97 struct sr_chunk_head *);
98 void sr_unwind_chunks(struct sr_softc *,
99 struct sr_chunk_head *);
100 void sr_free_discipline(struct sr_discipline *);
101 void sr_shutdown_discipline(struct sr_discipline *);
102
103
104 int sr_alloc_ccb(struct sr_discipline *);
105 void sr_free_ccb(struct sr_discipline *);
106 struct sr_ccb *sr_get_ccb(struct sr_discipline *);
107 void sr_put_ccb(struct sr_ccb *);
108 int sr_alloc_wu(struct sr_discipline *);
109 void sr_free_wu(struct sr_discipline *);
110 struct sr_workunit *sr_get_wu(struct sr_discipline *);
111 void sr_put_wu(struct sr_workunit *);
112
113
114 int sr_raid_inquiry(struct sr_workunit *);
115 int sr_raid_read_cap(struct sr_workunit *);
116 int sr_raid_tur(struct sr_workunit *);
117 int sr_raid_request_sense( struct sr_workunit *);
118 int sr_raid_start_stop(struct sr_workunit *);
119 int sr_raid_sync(struct sr_workunit *);
120 void sr_raid_set_chunk_state(struct sr_discipline *,
121 int, int);
122 void sr_raid_set_vol_state(struct sr_discipline *);
123 void sr_raid_startwu(struct sr_workunit *);
124
125 int sr_raid1_alloc_resources(struct sr_discipline *);
126 int sr_raid1_free_resources(struct sr_discipline *);
127 int sr_raid1_rw(struct sr_workunit *);
128 void sr_raid1_intr(struct buf *);
129 void sr_raid1_recreate_wu(struct sr_workunit *);
130
131 struct cryptop * sr_raidc_getcryptop(struct sr_workunit *, int);
132 void * sr_raidc_putcryptop(struct cryptop *);
133 int sr_raidc_alloc_resources(struct sr_discipline *);
134 int sr_raidc_free_resources(struct sr_discipline *);
135 int sr_raidc_rw(struct sr_workunit *);
136 int sr_raidc_rw2(struct cryptop *);
137 void sr_raidc_intr(struct buf *);
138 int sr_raidc_intr2(struct cryptop *);
139
140
141 void sr_shutdown(void *);
142 void sr_get_uuid(struct sr_uuid *);
143 void sr_print_uuid(struct sr_uuid *, int);
144 u_int32_t sr_checksum(char *, u_int32_t *, u_int32_t);
145 int sr_clear_metadata(struct sr_discipline *);
146 int sr_save_metadata(struct sr_discipline *, u_int32_t);
147 void sr_save_metadata_callback(void *, void *);
148 int sr_boot_assembly(struct sr_softc *);
149 int sr_already_assembled(struct sr_discipline *);
150 int sr_validate_metadata(struct sr_softc *, dev_t,
151 struct sr_metadata *);
152
153
154 #ifndef SMALL_KERNEL
155 void sr_refresh_sensors(void *);
156 int sr_create_sensors(struct sr_discipline *);
157 void sr_delete_sensors(struct sr_discipline *);
158 #endif
159
160 #ifdef SR_DEBUG
161 void sr_print_metadata(struct sr_metadata *);
162 #else
163 #define sr_print_metadata(m)
164 #endif
165
166 struct scsi_adapter sr_switch = {
167 sr_scsi_cmd, sr_minphys, NULL, NULL, sr_scsi_ioctl
168 };
169
170 struct scsi_device sr_dev = {
171 NULL, NULL, NULL, NULL
172 };
173
174 int
175 sr_match(struct device *parent, void *match, void *aux)
176 {
177 return (1);
178 }
179
180 void
181 sr_attach(struct device *parent, struct device *self, void *aux)
182 {
183 struct sr_softc *sc = (void *)self;
184
185 DNPRINTF(SR_D_MISC, "\n%s: sr_attach", DEVNAME(sc));
186
187 rw_init(&sc->sc_lock, "sr_lock");
188
189 if (bio_register(&sc->sc_dev, sr_ioctl) != 0)
190 printf("%s: controller registration failed", DEVNAME(sc));
191 else
192 sc->sc_ioctl = sr_ioctl;
193
194 printf("\n");
195
196 sr_boot_assembly(sc);
197 }
198
199 int
200 sr_detach(struct device *self, int flags)
201 {
202 return (0);
203 }
204
205 int
206 sr_activate(struct device *self, enum devact act)
207 {
208 return (1);
209 }
210
211 void
212 sr_minphys(struct buf *bp)
213 {
214 DNPRINTF(SR_D_MISC, "sr_minphys: %d\n", bp->b_bcount);
215
216
217 if (bp->b_bcount > SR_MAXFER)
218 bp->b_bcount = SR_MAXFER;
219 minphys(bp);
220 }
221
222 void
223 sr_copy_internal_data(struct scsi_xfer *xs, void *v, size_t size)
224 {
225 size_t copy_cnt;
226
227 DNPRINTF(SR_D_MISC, "sr_copy_internal_data xs: %p size: %d\n",
228 xs, size);
229
230 if (xs->datalen) {
231 copy_cnt = MIN(size, xs->datalen);
232 bcopy(v, xs->data, copy_cnt);
233 }
234 }
235
236 int
237 sr_alloc_ccb(struct sr_discipline *sd)
238 {
239 struct sr_ccb *ccb;
240 int i;
241
242 if (!sd)
243 return (1);
244
245 DNPRINTF(SR_D_CCB, "%s: sr_alloc_ccb\n", DEVNAME(sd->sd_sc));
246
247 if (sd->sd_ccb)
248 return (1);
249
250 sd->sd_ccb = malloc(sizeof(struct sr_ccb) *
251 sd->sd_max_wu * sd->sd_max_ccb_per_wu, M_DEVBUF, M_WAITOK);
252 memset(sd->sd_ccb, 0, sizeof(struct sr_ccb) *
253 sd->sd_max_wu * sd->sd_max_ccb_per_wu);
254 TAILQ_INIT(&sd->sd_ccb_freeq);
255 for (i = 0; i < sd->sd_max_wu * sd->sd_max_ccb_per_wu; i++) {
256 ccb = &sd->sd_ccb[i];
257 ccb->ccb_dis = sd;
258 sr_put_ccb(ccb);
259 }
260
261 DNPRINTF(SR_D_CCB, "%s: sr_alloc_ccb ccb: %d\n",
262 DEVNAME(sd->sd_sc), sd->sd_max_wu * sd->sd_max_ccb_per_wu);
263
264 return (0);
265 }
266
267 void
268 sr_free_ccb(struct sr_discipline *sd)
269 {
270 struct sr_ccb *ccb;
271
272 if (!sd)
273 return;
274
275 DNPRINTF(SR_D_CCB, "%s: sr_free_ccb %p\n", DEVNAME(sd->sd_sc), sd);
276
277 while ((ccb = TAILQ_FIRST(&sd->sd_ccb_freeq)) != NULL)
278 TAILQ_REMOVE(&sd->sd_ccb_freeq, ccb, ccb_link);
279
280 if (sd->sd_ccb)
281 free(sd->sd_ccb, M_DEVBUF);
282 }
283
284 struct sr_ccb *
285 sr_get_ccb(struct sr_discipline *sd)
286 {
287 struct sr_ccb *ccb;
288 int s;
289
290 s = splbio();
291
292 ccb = TAILQ_FIRST(&sd->sd_ccb_freeq);
293 if (ccb) {
294 TAILQ_REMOVE(&sd->sd_ccb_freeq, ccb, ccb_link);
295 ccb->ccb_state = SR_CCB_INPROGRESS;
296 }
297
298 splx(s);
299
300 DNPRINTF(SR_D_CCB, "%s: sr_get_ccb: %p\n", DEVNAME(sd->sd_sc),
301 ccb);
302
303 return (ccb);
304 }
305
306 void
307 sr_put_ccb(struct sr_ccb *ccb)
308 {
309 struct sr_discipline *sd = ccb->ccb_dis;
310 int s;
311
312 DNPRINTF(SR_D_CCB, "%s: sr_put_ccb: %p\n", DEVNAME(sd->sd_sc),
313 ccb);
314
315 s = splbio();
316
317 ccb->ccb_wu = NULL;
318 ccb->ccb_state = SR_CCB_FREE;
319 ccb->ccb_target = -1;
320
321 TAILQ_INSERT_TAIL(&sd->sd_ccb_freeq, ccb, ccb_link);
322
323 splx(s);
324 }
325
326 int
327 sr_alloc_wu(struct sr_discipline *sd)
328 {
329 struct sr_workunit *wu;
330 int i, no_wu;
331
332 if (!sd)
333 return (1);
334
335 DNPRINTF(SR_D_WU, "%s: sr_alloc_wu %p %d\n", DEVNAME(sd->sd_sc),
336 sd, sd->sd_max_wu);
337
338 if (sd->sd_wu)
339 return (1);
340
341 no_wu = sd->sd_max_wu;
342 sd->sd_wu_pending = no_wu;
343
344 sd->sd_wu = malloc(sizeof(struct sr_workunit) * no_wu,
345 M_DEVBUF, M_WAITOK);
346 memset(sd->sd_wu, 0, sizeof(struct sr_workunit) * no_wu);
347 TAILQ_INIT(&sd->sd_wu_freeq);
348 TAILQ_INIT(&sd->sd_wu_pendq);
349 TAILQ_INIT(&sd->sd_wu_defq);
350 for (i = 0; i < no_wu; i++) {
351 wu = &sd->sd_wu[i];
352 wu->swu_dis = sd;
353 sr_put_wu(wu);
354 }
355
356 return (0);
357 }
358
359 void
360 sr_free_wu(struct sr_discipline *sd)
361 {
362 struct sr_workunit *wu;
363
364 if (!sd)
365 return;
366
367 DNPRINTF(SR_D_WU, "%s: sr_free_wu %p\n", DEVNAME(sd->sd_sc), sd);
368
369 while ((wu = TAILQ_FIRST(&sd->sd_wu_freeq)) != NULL)
370 TAILQ_REMOVE(&sd->sd_wu_freeq, wu, swu_link);
371 while ((wu = TAILQ_FIRST(&sd->sd_wu_pendq)) != NULL)
372 TAILQ_REMOVE(&sd->sd_wu_pendq, wu, swu_link);
373 while ((wu = TAILQ_FIRST(&sd->sd_wu_defq)) != NULL)
374 TAILQ_REMOVE(&sd->sd_wu_defq, wu, swu_link);
375
376 if (sd->sd_wu)
377 free(sd->sd_wu, M_DEVBUF);
378 }
379
380 void
381 sr_put_wu(struct sr_workunit *wu)
382 {
383 struct sr_discipline *sd = wu->swu_dis;
384 struct sr_ccb *ccb;
385
386 int s;
387
388 DNPRINTF(SR_D_WU, "%s: sr_put_wu: %p\n", DEVNAME(sd->sd_sc), wu);
389
390 s = splbio();
391
392 wu->swu_xs = NULL;
393 wu->swu_state = SR_WU_FREE;
394 wu->swu_ios_complete = 0;
395 wu->swu_ios_failed = 0;
396 wu->swu_ios_succeeded = 0;
397 wu->swu_io_count = 0;
398 wu->swu_blk_start = 0;
399 wu->swu_blk_end = 0;
400 wu->swu_collider = NULL;
401 wu->swu_fake = 0;
402
403 while ((ccb = TAILQ_FIRST(&wu->swu_ccb)) != NULL) {
404 TAILQ_REMOVE(&wu->swu_ccb, ccb, ccb_link);
405 sr_put_ccb(ccb);
406 }
407 TAILQ_INIT(&wu->swu_ccb);
408
409 TAILQ_INSERT_TAIL(&sd->sd_wu_freeq, wu, swu_link);
410 sd->sd_wu_pending--;
411
412 splx(s);
413 }
414
415 struct sr_workunit *
416 sr_get_wu(struct sr_discipline *sd)
417 {
418 struct sr_workunit *wu;
419 int s;
420
421 s = splbio();
422
423 wu = TAILQ_FIRST(&sd->sd_wu_freeq);
424 if (wu) {
425 TAILQ_REMOVE(&sd->sd_wu_freeq, wu, swu_link);
426 wu->swu_state = SR_WU_INPROGRESS;
427 }
428 sd->sd_wu_pending++;
429
430 splx(s);
431
432 DNPRINTF(SR_D_WU, "%s: sr_get_wu: %p\n", DEVNAME(sd->sd_sc), wu);
433
434 return (wu);
435 }
436
437 int
438 sr_scsi_cmd(struct scsi_xfer *xs)
439 {
440 int s;
441 struct scsi_link *link = xs->sc_link;
442 struct sr_softc *sc = link->adapter_softc;
443 struct sr_workunit *wu;
444 struct sr_discipline *sd;
445
446 DNPRINTF(SR_D_CMD, "%s: sr_scsi_cmd: scsibus%d xs: %p "
447 "flags: %#x\n", DEVNAME(sc), link->scsibus, xs, xs->flags);
448
449 sd = sc->sc_dis[link->scsibus];
450 if (sd == NULL) {
451 s = splhigh();
452 sd = sc->sc_attach_dis;
453 splx(s);
454
455 DNPRINTF(SR_D_CMD, "%s: sr_scsi_cmd: attaching %p\n",
456 DEVNAME(sc), sd);
457 if (sd == NULL) {
458 wu = NULL;
459 printf("%s: sr_scsi_cmd NULL discipline\n",
460 DEVNAME(sc));
461 goto stuffup;
462 }
463 }
464
465 if ((wu = sr_get_wu(sd)) == NULL) {
466 DNPRINTF(SR_D_CMD, "%s: sr_scsi_cmd no wu\n", DEVNAME(sc));
467 return (TRY_AGAIN_LATER);
468 }
469
470 xs->error = XS_NOERROR;
471 wu->swu_xs = xs;
472
473 switch (xs->cmd->opcode) {
474 case READ_COMMAND:
475 case READ_BIG:
476 case WRITE_COMMAND:
477 case WRITE_BIG:
478 DNPRINTF(SR_D_CMD, "%s: sr_scsi_cmd: READ/WRITE %02x\n",
479 DEVNAME(sc), xs->cmd->opcode);
480 if (sd->sd_scsi_rw(wu))
481 goto stuffup;
482 break;
483
484 case SYNCHRONIZE_CACHE:
485 DNPRINTF(SR_D_CMD, "%s: sr_scsi_cmd: SYNCHRONIZE_CACHE\n",
486 DEVNAME(sc));
487 if (sd->sd_scsi_sync(wu))
488 goto stuffup;
489 goto complete;
490
491 case TEST_UNIT_READY:
492 DNPRINTF(SR_D_CMD, "%s: sr_scsi_cmd: TEST_UNIT_READY\n",
493 DEVNAME(sc));
494 if (sd->sd_scsi_tur(wu))
495 goto stuffup;
496 goto complete;
497
498 case START_STOP:
499 DNPRINTF(SR_D_CMD, "%s: sr_scsi_cmd: START_STOP\n",
500 DEVNAME(sc));
501 if (sd->sd_scsi_start_stop(wu))
502 goto stuffup;
503 goto complete;
504
505 case INQUIRY:
506 DNPRINTF(SR_D_CMD, "%s: sr_scsi_cmd: INQUIRY\n",
507 DEVNAME(sc));
508 if (sd->sd_scsi_inquiry(wu))
509 goto stuffup;
510 goto complete;
511
512 case READ_CAPACITY:
513 DNPRINTF(SR_D_CMD, "%s: sr_scsi_cmd READ CAPACITY\n",
514 DEVNAME(sc));
515 if (sd->sd_scsi_read_cap(wu))
516 goto stuffup;
517 goto complete;
518
519 case REQUEST_SENSE:
520 DNPRINTF(SR_D_CMD, "%s: sr_scsi_cmd REQUEST SENSE\n",
521 DEVNAME(sc));
522 if (sd->sd_scsi_req_sense(wu))
523 goto stuffup;
524 goto complete;
525
526 default:
527 DNPRINTF(SR_D_CMD, "%s: unsupported scsi command %x\n",
528 DEVNAME(sc), xs->cmd->opcode);
529
530 goto stuffup;
531 }
532
533 return (SUCCESSFULLY_QUEUED);
534 stuffup:
535 if (sd->sd_scsi_sense.error_code) {
536 xs->error = XS_SENSE;
537 bcopy(&sd->sd_scsi_sense, &xs->sense, sizeof(xs->sense));
538 bzero(&sd->sd_scsi_sense, sizeof(sd->sd_scsi_sense));
539 } else {
540 xs->error = XS_DRIVER_STUFFUP;
541 xs->flags |= ITSDONE;
542 }
543 complete:
544 s = splbio();
545 scsi_done(xs);
546 splx(s);
547 if (wu)
548 sr_put_wu(wu);
549 return (COMPLETE);
550 }
551 int
552 sr_scsi_ioctl(struct scsi_link *link, u_long cmd, caddr_t addr, int flag,
553 struct proc *p)
554 {
555 DNPRINTF(SR_D_IOCTL, "%s: sr_scsi_ioctl cmd: %#x\n",
556 DEVNAME((struct sr_softc *)link->adapter_softc), cmd);
557
558 return (sr_ioctl(link->adapter_softc, cmd, addr));
559 }
560
561 int
562 sr_ioctl(struct device *dev, u_long cmd, caddr_t addr)
563 {
564 struct sr_softc *sc = (struct sr_softc *)dev;
565 int rv = 0;
566
567 DNPRINTF(SR_D_IOCTL, "%s: sr_ioctl ", DEVNAME(sc));
568
569 rw_enter_write(&sc->sc_lock);
570
571 switch (cmd) {
572 case BIOCINQ:
573 DNPRINTF(SR_D_IOCTL, "inq\n");
574 rv = sr_ioctl_inq(sc, (struct bioc_inq *)addr);
575 break;
576
577 case BIOCVOL:
578 DNPRINTF(SR_D_IOCTL, "vol\n");
579 rv = sr_ioctl_vol(sc, (struct bioc_vol *)addr);
580 break;
581
582 case BIOCDISK:
583 DNPRINTF(SR_D_IOCTL, "disk\n");
584 rv = sr_ioctl_disk(sc, (struct bioc_disk *)addr);
585 break;
586
587 case BIOCALARM:
588 DNPRINTF(SR_D_IOCTL, "alarm\n");
589
590 break;
591
592 case BIOCBLINK:
593 DNPRINTF(SR_D_IOCTL, "blink\n");
594
595 break;
596
597 case BIOCSETSTATE:
598 DNPRINTF(SR_D_IOCTL, "setstate\n");
599 rv = sr_ioctl_setstate(sc, (struct bioc_setstate *)addr);
600 break;
601
602 case BIOCCREATERAID:
603 DNPRINTF(SR_D_IOCTL, "createraid\n");
604 rv = sr_ioctl_createraid(sc, (struct bioc_createraid *)addr, 1);
605 break;
606
607 default:
608 DNPRINTF(SR_D_IOCTL, "invalid ioctl\n");
609 rv = EINVAL;
610 }
611
612 rw_exit_write(&sc->sc_lock);
613
614 return (rv);
615 }
616
617 int
618 sr_ioctl_inq(struct sr_softc *sc, struct bioc_inq *bi)
619 {
620 int i, vol, disk;
621
622 for (i = 0, vol = 0, disk = 0; i < SR_MAXSCSIBUS; i++)
623
624 if (sc->sc_dis[i]) {
625 vol++;
626 disk += sc->sc_dis[i]->sd_vol.sv_meta.svm_no_chunk;
627 }
628
629 strlcpy(bi->bi_dev, sc->sc_dev.dv_xname, sizeof(bi->bi_dev));
630 bi->bi_novol = vol;
631 bi->bi_nodisk = disk;
632
633 return (0);
634 }
635
636 int
637 sr_ioctl_vol(struct sr_softc *sc, struct bioc_vol *bv)
638 {
639 int i, vol, rv = EINVAL;
640 struct sr_volume *sv;
641
642 for (i = 0, vol = -1; i < SR_MAXSCSIBUS; i++) {
643
644 if (sc->sc_dis[i])
645 vol++;
646 if (vol != bv->bv_volid)
647 continue;
648
649 sv = &sc->sc_dis[i]->sd_vol;
650 bv->bv_status = sv->sv_meta.svm_status;
651 bv->bv_size = sv->sv_meta.svm_size;
652 bv->bv_level = sv->sv_meta.svm_level;
653 bv->bv_nodisk = sv->sv_meta.svm_no_chunk;
654 strlcpy(bv->bv_dev, sv->sv_meta.svm_devname,
655 sizeof(bv->bv_dev));
656 strlcpy(bv->bv_vendor, sv->sv_meta.svm_vendor,
657 sizeof(bv->bv_vendor));
658 rv = 0;
659 break;
660 }
661
662 return (rv);
663 }
664
665 int
666 sr_ioctl_disk(struct sr_softc *sc, struct bioc_disk *bd)
667 {
668 int i, vol, rv = EINVAL, id;
669 struct sr_chunk *src;
670
671 for (i = 0, vol = -1; i < SR_MAXSCSIBUS; i++) {
672
673 if (sc->sc_dis[i])
674 vol++;
675 if (vol != bd->bd_volid)
676 continue;
677
678 id = bd->bd_diskid;
679 if (id >= sc->sc_dis[i]->sd_vol.sv_meta.svm_no_chunk)
680 break;
681
682 src = sc->sc_dis[i]->sd_vol.sv_chunks[id];
683 bd->bd_status = src->src_meta.scm_status;
684 bd->bd_size = src->src_meta.scm_size;
685 bd->bd_channel = vol;
686 bd->bd_target = id;
687 strlcpy(bd->bd_vendor, src->src_meta.scm_devname,
688 sizeof(bd->bd_vendor));
689 rv = 0;
690 break;
691 }
692
693 return (rv);
694 }
695
696 int
697 sr_ioctl_setstate(struct sr_softc *sc, struct bioc_setstate *bs)
698 {
699 int rv = EINVAL;
700
701 #ifdef SR_UNIT_TEST
702 int i, vol, state;
703 struct sr_discipline *sd;
704
705 for (i = 0, vol = -1; i < SR_MAXSCSIBUS; i++) {
706
707 if (sc->sc_dis[i])
708 vol++;
709 if (vol != bs->bs_channel)
710 continue;
711
712 sd = sc->sc_dis[vol];
713 if (bs->bs_target >= sd->sd_vol.sv_meta.svm_no_chunk)
714 goto done;
715
716 switch (bs->bs_status) {
717 case BIOC_SSONLINE:
718 state = BIOC_SDONLINE;
719 break;
720 case BIOC_SSOFFLINE:
721 state = BIOC_SDOFFLINE;
722 break;
723 case BIOC_SSHOTSPARE:
724 state = BIOC_SDHOTSPARE;
725 break;
726 case BIOC_SSREBUILD:
727 state = BIOC_SDREBUILD;
728 break;
729 default:
730 printf("invalid state %d\n", bs->bs_status);
731 goto done;
732 }
733
734 printf("status change for %u:%u -> %u %u\n",
735 bs->bs_channel, bs->bs_target, bs->bs_status, state);
736
737 sd->sd_set_chunk_state(sd, bs->bs_target, bs->bs_status);
738
739 rv = 0;
740
741 break;
742 }
743
744 done:
745 #endif
746 return (rv);
747 }
748
749 int
750 sr_ioctl_createraid(struct sr_softc *sc, struct bioc_createraid *bc, int user)
751 {
752 dev_t *dt;
753 int i, s, no_chunk, rv = EINVAL, vol;
754 int no_meta, updatemeta = 0;
755 int64_t vol_size;
756 struct sr_chunk_head *cl;
757 struct sr_discipline *sd = NULL;
758 struct sr_chunk *ch_entry;
759 struct device *dev, *dev2;
760 struct scsibus_attach_args saa;
761
762 DNPRINTF(SR_D_IOCTL, "%s: sr_ioctl_createraid(%d)\n",
763 DEVNAME(sc), user);
764
765
766 if (bc->bc_dev_list_len > BIOC_CRMAXLEN)
767 goto unwind;
768
769 dt = malloc(bc->bc_dev_list_len, M_DEVBUF, M_WAITOK);
770 bzero(dt, bc->bc_dev_list_len);
771 if (user)
772 copyin(bc->bc_dev_list, dt, bc->bc_dev_list_len);
773 else
774 bcopy(bc->bc_dev_list, dt, bc->bc_dev_list_len);
775
776 sd = malloc(sizeof(struct sr_discipline), M_DEVBUF, M_WAITOK);
777 memset(sd, 0, sizeof(struct sr_discipline));
778 sd->sd_sc = sc;
779
780 no_chunk = bc->bc_dev_list_len / sizeof(dev_t);
781 cl = &sd->sd_vol.sv_chunk_list;
782 SLIST_INIT(cl);
783 if (sr_open_chunks(sc, cl, dt, no_chunk))
784 goto unwind;
785
786
787 sd->sd_meta = malloc(SR_META_SIZE * 512 , M_DEVBUF, M_WAITOK);
788 bzero(sd->sd_meta, SR_META_SIZE * 512);
789
790
791 sd->sd_vol.sv_chunks = malloc(sizeof(struct sr_chunk *) * no_chunk,
792 M_DEVBUF, M_WAITOK);
793 bzero(sd->sd_vol.sv_chunks, sizeof(struct sr_chunk *) * no_chunk);
794
795
796 if (bc->bc_flags & BIOC_SCFORCE) {
797
798 if (sr_read_meta(sd))
799 if (sr_already_assembled(sd)) {
800 printf("%s: disk ", DEVNAME(sc));
801 sr_print_uuid(&sd->sd_meta->ssd_uuid, 0);
802 printf(" is currently in use; can't force "
803 "create\n");
804 goto unwind;
805 }
806
807
808 bzero(sd->sd_vol.sv_chunks,
809 sizeof(struct sr_chunk *) * no_chunk);
810 bzero(sd->sd_meta, SR_META_SIZE * 512);
811
812 if (sr_clear_metadata(sd)) {
813 printf("%s: failed to clear metadata\n");
814 goto unwind;
815 }
816 }
817
818 if ((no_meta = sr_read_meta(sd)) == 0) {
819
820 switch (bc->bc_level) {
821 case 1:
822 if (no_chunk < 2)
823 goto unwind;
824 strlcpy(sd->sd_name, "RAID 1", sizeof(sd->sd_name));
825 break;
826 #if 0
827 case 'c':
828 if (no_chunk != 1)
829 goto unwind;
830 strlcpy(sd->sd_name, "RAID C", sizeof(sd->sd_name));
831 break;
832 #endif
833 default:
834 goto unwind;
835 }
836
837
838 i = 0;
839 SLIST_FOREACH(ch_entry, cl, src_link)
840 sd->sd_vol.sv_chunks[i++] = ch_entry;
841
842
843 sr_create_chunk_meta(sc, cl);
844
845
846 ch_entry = SLIST_FIRST(cl);
847 vol_size = ch_entry->src_meta.scm_coerced_size;
848 DNPRINTF(SR_D_IOCTL,
849 "%s: sr_ioctl_createraid: vol_size: %lld\n",
850 DEVNAME(sc), vol_size);
851 sd->sd_vol.sv_meta.svm_no_chunk = no_chunk;
852 sd->sd_vol.sv_meta.svm_size = vol_size;
853 sd->sd_vol.sv_meta.svm_status = BIOC_SVONLINE;
854 sd->sd_vol.sv_meta.svm_level = bc->bc_level;
855 strlcpy(sd->sd_vol.sv_meta.svm_vendor, "OPENBSD",
856 sizeof(sd->sd_vol.sv_meta.svm_vendor));
857 snprintf(sd->sd_vol.sv_meta.svm_product,
858 sizeof(sd->sd_vol.sv_meta.svm_product), "SR %s",
859 sd->sd_name);
860 snprintf(sd->sd_vol.sv_meta.svm_revision,
861 sizeof(sd->sd_vol.sv_meta.svm_revision), "%03d",
862 SR_META_VERSION);
863
864 sd->sd_meta_flags = bc->bc_flags & BIOC_SCNOAUTOASSEMBLE;
865 updatemeta = 1;
866 } else if (no_meta == no_chunk) {
867 if (user == 0 && sd->sd_meta_flags & BIOC_SCNOAUTOASSEMBLE) {
868 DNPRINTF(SR_D_META, "%s: disk not auto assembled from "
869 "metadata\n", DEVNAME(sc));
870 goto unwind;
871 }
872 if (sr_already_assembled(sd)) {
873 printf("%s: disk ", DEVNAME(sc));
874 sr_print_uuid(&sd->sd_meta->ssd_uuid, 0);
875 printf(" already assembled\n");
876 goto unwind;
877 }
878 DNPRINTF(SR_D_META, "%s: disk assembled from metadata\n",
879 DEVNAME(sc));
880 updatemeta = 0;
881 } else {
882 if (sr_already_assembled(sd)) {
883 printf("%s: disk ", DEVNAME(sc));
884 sr_print_uuid(&sd->sd_meta->ssd_uuid, 0);
885 printf(" already assembled; will not partial "
886 "assemble it\n");
887 goto unwind;
888 }
889 printf("%s: not yet partial bringup\n", DEVNAME(sc));
890 goto unwind;
891 }
892
893
894
895 switch (bc->bc_level) {
896 case 1:
897
898 sd->sd_type = SR_MD_RAID1;
899 sd->sd_max_ccb_per_wu = no_chunk;
900 sd->sd_max_wu = SR_RAID1_NOWU;
901
902
903 sd->sd_alloc_resources = sr_raid1_alloc_resources;
904 sd->sd_free_resources = sr_raid1_free_resources;
905 sd->sd_scsi_inquiry = sr_raid_inquiry;
906 sd->sd_scsi_read_cap = sr_raid_read_cap;
907 sd->sd_scsi_tur = sr_raid_tur;
908 sd->sd_scsi_req_sense = sr_raid_request_sense;
909 sd->sd_scsi_start_stop = sr_raid_start_stop;
910 sd->sd_scsi_sync = sr_raid_sync;
911 sd->sd_scsi_rw = sr_raid1_rw;
912 sd->sd_set_chunk_state = sr_raid_set_chunk_state;
913 sd->sd_set_vol_state = sr_raid_set_vol_state;
914 break;
915 #ifdef CRYPTO
916 case 'c':
917
918 sd->sd_type = SR_MD_RAIDC;
919 sd->sd_max_ccb_per_wu = no_chunk;
920 sd->sd_max_wu = SR_RAIDC_NOWU;
921
922
923 sd->sd_alloc_resources = sr_raidc_alloc_resources;
924 sd->sd_free_resources = sr_raidc_free_resources;
925 sd->sd_scsi_inquiry = sr_raid_inquiry;
926 sd->sd_scsi_read_cap = sr_raid_read_cap;
927 sd->sd_scsi_tur = sr_raid_tur;
928 sd->sd_scsi_req_sense = sr_raid_request_sense;
929 sd->sd_scsi_start_stop = sr_raid_start_stop;
930 sd->sd_scsi_sync = sr_raid_sync;
931 sd->sd_scsi_rw = sr_raidc_rw;
932 sd->sd_set_chunk_state = sr_raid_set_chunk_state;
933 sd->sd_set_vol_state = sr_raid_set_vol_state;
934 break;
935 #endif
936 default:
937 printf("default %d\n", bc->bc_level);
938 goto unwind;
939 }
940
941
942 if ((rv = sd->sd_alloc_resources(sd)))
943 goto unwind;
944
945
946 sd->sd_link.openings = sd->sd_max_wu;
947 sd->sd_link.device = &sr_dev;
948 sd->sd_link.device_softc = sc;
949 sd->sd_link.adapter_softc = sc;
950 sd->sd_link.adapter = &sr_switch;
951 sd->sd_link.adapter_target = SR_MAX_LD;
952 sd->sd_link.adapter_buswidth = 1;
953 bzero(&saa, sizeof(saa));
954 saa.saa_sc_link = &sd->sd_link;
955
956
957 rv = ENXIO;
958
959
960 bzero(&sd->sd_scsi_sense, sizeof(sd->sd_scsi_sense));
961
962
963 s = splhigh();
964 sc->sc_attach_dis = sd;
965 splx(s);
966 dev2 = config_found(&sc->sc_dev, &saa, scsiprint);
967 s = splhigh();
968 sc->sc_attach_dis = NULL;
969 splx(s);
970 TAILQ_FOREACH(dev, &alldevs, dv_list)
971 if (dev->dv_parent == dev2)
972 break;
973 if (dev == NULL)
974 goto unwind;
975
976 DNPRINTF(SR_D_IOCTL, "%s: sr device added: %s on scsibus%d\n",
977 DEVNAME(sc), dev->dv_xname, sd->sd_link.scsibus);
978
979 sc->sc_dis[sd->sd_link.scsibus] = sd;
980 for (i = 0, vol = -1; i <= sd->sd_link.scsibus; i++)
981 if (sc->sc_dis[i])
982 vol++;
983
984 rv = 0;
985 if (updatemeta) {
986
987 sd->sd_vol.sv_meta.svm_volid = vol;
988 strlcpy(sd->sd_vol.sv_meta.svm_devname, dev->dv_xname,
989 sizeof(sd->sd_vol.sv_meta.svm_devname));
990
991 }
992
993
994 rv = sr_save_metadata(sd, SR_VOL_DIRTY);
995
996 #ifndef SMALL_KERNEL
997 if (sr_create_sensors(sd))
998 printf("%s: unable to create sensor for %s\n", DEVNAME(sc),
999 dev->dv_xname);
1000 else
1001 sd->sd_vol.sv_sensor_valid = 1;
1002 #endif
1003
1004 sd->sd_scsibus_dev = dev2;
1005 sd->sd_shutdownhook = shutdownhook_establish(sr_shutdown, sd);
1006
1007 return (rv);
1008
1009 unwind:
1010 sr_shutdown_discipline(sd);
1011
1012 return (rv);
1013 }
1014
1015 int
1016 sr_open_chunks(struct sr_softc *sc, struct sr_chunk_head *cl, dev_t *dt,
1017 int no_chunk)
1018 {
1019 struct sr_chunk *ch_entry, *ch_prev = NULL;
1020 struct disklabel label;
1021 struct bdevsw *bdsw;
1022 char *name;
1023 int maj, unit, part, i, error;
1024 daddr64_t size;
1025 dev_t dev;
1026
1027 DNPRINTF(SR_D_IOCTL, "%s: sr_open_chunks(%d)\n", DEVNAME(sc), no_chunk);
1028
1029
1030 for (i = 0; i < no_chunk; i++) {
1031 ch_entry = malloc(sizeof(struct sr_chunk), M_DEVBUF, M_WAITOK);
1032 bzero(ch_entry, sizeof(struct sr_chunk));
1033
1034 if (ch_prev)
1035 SLIST_INSERT_AFTER(ch_prev, ch_entry, src_link);
1036 else
1037 SLIST_INSERT_HEAD(cl, ch_entry, src_link);
1038 ch_prev = ch_entry;
1039
1040 dev = dt[i];
1041 maj = major(dev);
1042 part = DISKPART(dev);
1043 unit = DISKUNIT(dev);
1044 bdsw = &bdevsw[maj];
1045
1046 name = findblkname(maj);
1047 if (name == NULL)
1048 goto unwind;
1049
1050 snprintf(ch_entry->src_devname, sizeof(ch_entry->src_devname),
1051 "%s%d%c", name, unit, part + 'a');
1052 name = ch_entry->src_devname;
1053
1054
1055 error = bdsw->d_open(dev, FREAD | FWRITE , S_IFBLK, curproc);
1056
1057
1058 error = bdsw->d_ioctl(dev, DIOCGDINFO, (void *)&label,
1059 0, NULL);
1060 if (error) {
1061 printf("%s: %s can't obtain disklabel\n",
1062 DEVNAME(sc), name);
1063 bdsw->d_close(dev, FWRITE, S_IFBLK, curproc);
1064 goto unwind;
1065 }
1066
1067
1068 if (label.d_partitions[part].p_fstype != FS_RAID) {
1069 printf("%s: %s partition not of type RAID (%d)\n",
1070 DEVNAME(sc), name,
1071 label.d_partitions[part].p_fstype);
1072 bdsw->d_close(dev, FWRITE, S_IFBLK, curproc);
1073 goto unwind;
1074 }
1075
1076
1077 ch_entry->src_size = size = DL_GETPSIZE(&label.d_partitions[part]) -
1078 SR_META_SIZE - SR_META_OFFSET;
1079 if (size <= 0) {
1080 printf("%s: %s partition too small\n",
1081 DEVNAME(sc), name);
1082 bdsw->d_close(dev, FWRITE, S_IFBLK, curproc);
1083 goto unwind;
1084 }
1085
1086
1087 ch_entry->src_dev_mm = dev;
1088
1089 DNPRINTF(SR_D_IOCTL, "%s: found %s size %d\n", DEVNAME(sc),
1090 name, size);
1091 }
1092
1093 return (0);
1094 unwind:
1095 printf("%s: invalid device: %s\n", DEVNAME(sc), name ? name : "nodev");
1096 return (1);
1097 }
1098
1099 int
1100 sr_read_meta(struct sr_discipline *sd)
1101 {
1102 struct sr_softc *sc = sd->sd_sc;
1103 struct sr_chunk_head *cl = &sd->sd_vol.sv_chunk_list;
1104 struct sr_metadata *sm = sd->sd_meta, *m;
1105 struct sr_chunk *ch_entry;
1106 struct buf b;
1107 struct sr_vol_meta *mv;
1108 struct sr_chunk_meta *mc;
1109 size_t sz = SR_META_SIZE * 512;
1110 int no_chunk = 0;
1111 u_int32_t volid, ondisk = 0, cid;
1112
1113 DNPRINTF(SR_D_META, "%s: sr_read_meta\n", DEVNAME(sc));
1114
1115 m = malloc(sz , M_DEVBUF, M_WAITOK);
1116 bzero(m, sz);
1117
1118 SLIST_FOREACH(ch_entry, cl, src_link) {
1119 bzero(&b, sizeof(b));
1120
1121 b.b_flags = B_READ;
1122 b.b_blkno = SR_META_OFFSET;
1123 b.b_bcount = sz;
1124 b.b_bufsize = sz;
1125 b.b_resid = sz;
1126 b.b_data = (void *)m;
1127 b.b_error = 0;
1128 b.b_proc = curproc;
1129 b.b_dev = ch_entry->src_dev_mm;
1130 b.b_vp = NULL;
1131 b.b_iodone = NULL;
1132 LIST_INIT(&b.b_dep);
1133 bdevsw_lookup(b.b_dev)->d_strategy(&b);
1134 biowait(&b);
1135
1136
1137 if (b.b_flags & B_ERROR) {
1138 printf("%s: %s i/o error on block %d while reading "
1139 "metadata %d\n", DEVNAME(sc),
1140 ch_entry->src_devname, b.b_blkno, b.b_error);
1141 continue;
1142 }
1143
1144 if (m->ssd_magic != SR_MAGIC)
1145 continue;
1146
1147
1148 if (sr_validate_metadata(sc, ch_entry->src_dev_mm, m)) {
1149 printf("%s: invalid metadata\n", DEVNAME(sc));
1150 no_chunk = -1;
1151 goto bad;
1152 }
1153
1154 mv = (struct sr_vol_meta *)(m + 1);
1155 mc = (struct sr_chunk_meta *)(mv + 1);
1156
1157
1158 if (no_chunk++ == 0) {
1159 bcopy(m, sm, sz);
1160 bcopy(m, sd->sd_meta, sizeof(*sd->sd_meta));
1161 bcopy(mv, &sd->sd_vol.sv_meta,
1162 sizeof(sd->sd_vol.sv_meta));
1163
1164 volid = m->ssd_vd_volid;
1165 sd->sd_meta_flags = sm->ssd_flags;
1166 }
1167
1168 if (bcmp(&sm->ssd_uuid, &sd->sd_vol.sv_meta.svm_uuid,
1169 sizeof(struct sr_uuid))) {
1170 printf("%s: %s invalid chunk uuid ",
1171 DEVNAME(sc), ch_entry->src_devname);
1172 sr_print_uuid(&sm->ssd_uuid, 0);
1173 printf(", expected ");
1174 sr_print_uuid(&sd->sd_vol.sv_meta.svm_uuid, 1);
1175 no_chunk = -1;
1176 goto bad;
1177 }
1178
1179
1180 ch_entry->src_meta_ondisk = 1;
1181
1182
1183 if (volid != m->ssd_vd_volid) {
1184 printf("%s: %s invalid volume id %d, expected %d\n",
1185 DEVNAME(sc), ch_entry->src_devname,
1186 volid, m->ssd_vd_volid);
1187 no_chunk = -1;
1188 goto bad;
1189 }
1190
1191 if (m->ssd_chunk_id > m->ssd_chunk_no) {
1192 printf("%s: %s chunk id out of range %d, expected "
1193 "lower than %d\n", DEVNAME(sc),
1194 ch_entry->src_devname,
1195 m->ssd_chunk_id, m->ssd_chunk_no);
1196 no_chunk = -1;
1197 goto bad;
1198 }
1199
1200 if (sd->sd_vol.sv_chunks[m->ssd_chunk_id]) {
1201 printf("%s: %s chunk id %d already in use\n",
1202 DEVNAME(sc), ch_entry->src_devname,
1203 m->ssd_chunk_id);
1204 no_chunk = -1;
1205 goto bad;
1206 }
1207
1208 sd->sd_vol.sv_chunks[m->ssd_chunk_id] = ch_entry;
1209 bcopy(mc + m->ssd_chunk_id, &ch_entry->src_meta,
1210 sizeof(ch_entry->src_meta));
1211
1212 if (ondisk == 0) {
1213 ondisk = m->ssd_ondisk;
1214 cid = m->ssd_chunk_id;
1215 }
1216
1217 if (m->ssd_ondisk != ondisk) {
1218 printf("%s: %s chunk id %d contains stale metadata\n",
1219 DEVNAME(sc), ch_entry->src_devname,
1220 m->ssd_ondisk < ondisk ? m->ssd_chunk_id : cid);
1221 no_chunk = -1;
1222 goto bad;
1223 }
1224 }
1225
1226 if (no_chunk != m->ssd_chunk_no) {
1227 DNPRINTF(SR_D_META, "%s: not enough chunks supplied\n",
1228 DEVNAME(sc));
1229 no_chunk = -1;
1230 goto bad;
1231 }
1232
1233 DNPRINTF(SR_D_META, "%s: sr_read_meta: found %d elements\n",
1234 DEVNAME(sc), no_chunk);
1235
1236 sr_print_metadata(m);
1237
1238 bad:
1239
1240 free(m, M_DEVBUF);
1241 return (no_chunk);
1242 }
1243
1244 int
1245 sr_create_chunk_meta(struct sr_softc *sc, struct sr_chunk_head *cl)
1246 {
1247 struct sr_chunk *ch_entry;
1248 struct sr_uuid uuid;
1249 int rv = 1, cid = 0;
1250 char *name;
1251 u_int64_t max_chunk_sz = 0, min_chunk_sz;
1252
1253 DNPRINTF(SR_D_IOCTL, "%s: sr_create_chunk_meta\n", DEVNAME(sc));
1254
1255 sr_get_uuid(&uuid);
1256
1257
1258 SLIST_FOREACH(ch_entry, cl, src_link) {
1259 name = ch_entry->src_devname;
1260 ch_entry->src_meta.scm_size = ch_entry->src_size;
1261 ch_entry->src_meta.scm_chunk_id = cid++;
1262 ch_entry->src_meta.scm_status = BIOC_SDONLINE;
1263 strlcpy(ch_entry->src_meta.scm_devname, name,
1264 sizeof(ch_entry->src_meta.scm_devname));
1265 bcopy(&uuid, &ch_entry->src_meta.scm_uuid,
1266 sizeof(ch_entry->src_meta.scm_uuid));
1267
1268 if (ch_entry->src_meta.scm_size > max_chunk_sz)
1269 max_chunk_sz = ch_entry->src_meta.scm_size;
1270 }
1271
1272
1273 min_chunk_sz = max_chunk_sz;
1274 SLIST_FOREACH(ch_entry, cl, src_link)
1275 if (ch_entry->src_meta.scm_size < min_chunk_sz)
1276 min_chunk_sz = ch_entry->src_meta.scm_size;
1277
1278
1279 SLIST_FOREACH(ch_entry, cl, src_link)
1280 ch_entry->src_meta.scm_coerced_size = min_chunk_sz;
1281
1282
1283 if (min_chunk_sz != max_chunk_sz)
1284 printf("%s: chunk sizes are not equal; up to %llu blocks "
1285 "wasted per chunk\n",
1286 DEVNAME(sc), max_chunk_sz - min_chunk_sz);
1287
1288 rv = 0;
1289
1290 return (rv);
1291 }
1292
1293 void
1294 sr_unwind_chunks(struct sr_softc *sc, struct sr_chunk_head *cl)
1295 {
1296 struct sr_chunk *ch_entry, *ch_next;
1297 dev_t dev;
1298
1299 DNPRINTF(SR_D_IOCTL, "%s: sr_unwind_chunks\n", DEVNAME(sc));
1300
1301 if (!cl)
1302 return;
1303
1304 for (ch_entry = SLIST_FIRST(cl);
1305 ch_entry != SLIST_END(cl); ch_entry = ch_next) {
1306 ch_next = SLIST_NEXT(ch_entry, src_link);
1307
1308 dev = ch_entry->src_dev_mm;
1309
1310 if (dev != NODEV)
1311 bdevsw_lookup(dev)->d_close(dev, FWRITE, S_IFBLK,
1312 curproc);
1313
1314 free(ch_entry, M_DEVBUF);
1315 }
1316 SLIST_INIT(cl);
1317 }
1318
1319 void
1320 sr_free_discipline(struct sr_discipline *sd)
1321 {
1322 #ifdef SR_DEBUG
1323 struct sr_softc *sc = sd->sd_sc;
1324 #endif
1325 if (!sd)
1326 return;
1327
1328 DNPRINTF(SR_D_DIS, "%s: sr_free_discipline %s\n",
1329 DEVNAME(sc), sd->sd_vol.sv_meta.svm_devname);
1330
1331 if (sd->sd_free_resources)
1332 sd->sd_free_resources(sd);
1333 if (sd->sd_vol.sv_chunks)
1334 free(sd->sd_vol.sv_chunks, M_DEVBUF);
1335 free(sd, M_DEVBUF);
1336 }
1337
1338 void
1339 sr_shutdown_discipline(struct sr_discipline *sd)
1340 {
1341 struct sr_softc *sc = sd->sd_sc;
1342 int s;
1343
1344 if (!sd || !sc)
1345 return;
1346
1347 DNPRINTF(SR_D_DIS, "%s: sr_shutdown_discipline %s\n",
1348 DEVNAME(sc), sd->sd_vol.sv_meta.svm_devname);
1349
1350 s = splbio();
1351
1352
1353 wakeup(sd);
1354 while (sd->sd_sync || sd->sd_must_flush)
1355 if (tsleep(&sd->sd_sync, MAXPRI, "sr_down", 60 * hz) ==
1356 EWOULDBLOCK)
1357 break;
1358
1359 #ifndef SMALL_KERNEL
1360 sr_delete_sensors(sd);
1361 #endif
1362
1363 if (sd->sd_scsibus_dev)
1364 config_detach(sd->sd_scsibus_dev, DETACH_FORCE);
1365
1366 sr_unwind_chunks(sc, &sd->sd_vol.sv_chunk_list);
1367
1368 if (sd)
1369 sr_free_discipline(sd);
1370
1371 splx(s);
1372 }
1373
1374 int
1375 sr_raid_inquiry(struct sr_workunit *wu)
1376 {
1377 struct sr_discipline *sd = wu->swu_dis;
1378 struct scsi_xfer *xs = wu->swu_xs;
1379 struct scsi_inquiry_data inq;
1380
1381 DNPRINTF(SR_D_DIS, "%s: sr_raid_inquiry\n", DEVNAME(sd->sd_sc));
1382
1383 bzero(&inq, sizeof(inq));
1384 inq.device = T_DIRECT;
1385 inq.dev_qual2 = 0;
1386 inq.version = 2;
1387 inq.response_format = 2;
1388 inq.additional_length = 32;
1389 strlcpy(inq.vendor, sd->sd_vol.sv_meta.svm_vendor,
1390 sizeof(inq.vendor));
1391 strlcpy(inq.product, sd->sd_vol.sv_meta.svm_product,
1392 sizeof(inq.product));
1393 strlcpy(inq.revision, sd->sd_vol.sv_meta.svm_revision,
1394 sizeof(inq.revision));
1395 sr_copy_internal_data(xs, &inq, sizeof(inq));
1396
1397 return (0);
1398 }
1399
1400 int
1401 sr_raid_read_cap(struct sr_workunit *wu)
1402 {
1403 struct sr_discipline *sd = wu->swu_dis;
1404 struct scsi_xfer *xs = wu->swu_xs;
1405 struct scsi_read_cap_data rcd;
1406
1407 DNPRINTF(SR_D_DIS, "%s: sr_raid_read_cap\n", DEVNAME(sd->sd_sc));
1408
1409 bzero(&rcd, sizeof(rcd));
1410 _lto4b(sd->sd_vol.sv_meta.svm_size, rcd.addr);
1411 _lto4b(512, rcd.length);
1412 sr_copy_internal_data(xs, &rcd, sizeof(rcd));
1413
1414 return (0);
1415 }
1416
1417 int
1418 sr_raid_tur(struct sr_workunit *wu)
1419 {
1420 struct sr_discipline *sd = wu->swu_dis;
1421
1422 DNPRINTF(SR_D_DIS, "%s: sr_raid_tur\n", DEVNAME(sd->sd_sc));
1423
1424 if (sd->sd_vol.sv_meta.svm_status == BIOC_SVOFFLINE) {
1425 sd->sd_scsi_sense.error_code = SSD_ERRCODE_CURRENT;
1426 sd->sd_scsi_sense.flags = SKEY_NOT_READY;
1427 sd->sd_scsi_sense.add_sense_code = 0x04;
1428 sd->sd_scsi_sense.add_sense_code_qual = 0x11;
1429 sd->sd_scsi_sense.extra_len = 4;
1430 return (1);
1431 } else if (sd->sd_vol.sv_meta.svm_status == BIOC_SVINVALID) {
1432 sd->sd_scsi_sense.error_code = SSD_ERRCODE_CURRENT;
1433 sd->sd_scsi_sense.flags = SKEY_HARDWARE_ERROR;
1434 sd->sd_scsi_sense.add_sense_code = 0x05;
1435 sd->sd_scsi_sense.add_sense_code_qual = 0x00;
1436 sd->sd_scsi_sense.extra_len = 4;
1437 return (1);
1438 }
1439
1440 return (0);
1441 }
1442
1443 int
1444 sr_raid_request_sense(struct sr_workunit *wu)
1445 {
1446 struct sr_discipline *sd = wu->swu_dis;
1447 struct scsi_xfer *xs = wu->swu_xs;
1448
1449 DNPRINTF(SR_D_DIS, "%s: sr_raid_request_sense\n",
1450 DEVNAME(sd->sd_sc));
1451
1452
1453 bcopy(&sd->sd_scsi_sense, &xs->sense, sizeof(xs->sense));
1454
1455
1456 bzero(&sd->sd_scsi_sense, sizeof(sd->sd_scsi_sense));
1457
1458 return (0);
1459 }
1460
1461 int
1462 sr_raid_start_stop(struct sr_workunit *wu)
1463 {
1464 struct sr_discipline *sd = wu->swu_dis;
1465 struct scsi_xfer *xs = wu->swu_xs;
1466 struct scsi_start_stop *ss = (struct scsi_start_stop *)xs->cmd;
1467 int rv = 1;
1468
1469 DNPRINTF(SR_D_DIS, "%s: sr_raid_start_stop\n",
1470 DEVNAME(sd->sd_sc));
1471
1472 if (!ss)
1473 return (rv);
1474
1475 if (ss->byte2 == 0x00) {
1476
1477 if (sd->sd_vol.sv_meta.svm_status == BIOC_SVOFFLINE) {
1478
1479
1480 sd->sd_vol.sv_meta.svm_status = BIOC_SVONLINE;
1481 }
1482 rv = 0;
1483 } else {
1484
1485 if (sd->sd_vol.sv_meta.svm_status == BIOC_SVONLINE) {
1486
1487 sd->sd_vol.sv_meta.svm_status = BIOC_SVOFFLINE;
1488 }
1489 rv = 0;
1490 }
1491
1492 return (rv);
1493 }
1494
1495 int
1496 sr_raid_sync(struct sr_workunit *wu)
1497 {
1498 struct sr_discipline *sd = wu->swu_dis;
1499 int s, rv = 0, ios;
1500
1501 DNPRINTF(SR_D_DIS, "%s: sr_raid_sync\n", DEVNAME(sd->sd_sc));
1502
1503
1504 ios = wu->swu_fake ? 0 : 1;
1505
1506 s = splbio();
1507 sd->sd_sync = 1;
1508
1509 while (sd->sd_wu_pending > ios)
1510 if (tsleep(sd, PRIBIO, "sr_sync", 15 * hz) == EWOULDBLOCK) {
1511 DNPRINTF(SR_D_DIS, "%s: sr_raid_sync timeout\n",
1512 DEVNAME(sd->sd_sc));
1513 rv = 1;
1514 break;
1515 }
1516
1517 sd->sd_sync = 0;
1518 splx(s);
1519
1520 wakeup(&sd->sd_sync);
1521
1522 return (rv);
1523 }
1524
1525 void
1526 sr_raid_startwu(struct sr_workunit *wu)
1527 {
1528 struct sr_discipline *sd = wu->swu_dis;
1529 struct sr_ccb *ccb;
1530
1531 splassert(IPL_BIO);
1532
1533 if (wu->swu_state == SR_WU_RESTART)
1534
1535
1536
1537
1538 ;
1539 else
1540
1541 TAILQ_INSERT_TAIL(&sd->sd_wu_pendq, wu, swu_link);
1542
1543
1544 TAILQ_FOREACH(ccb, &wu->swu_ccb, ccb_link) {
1545 bdevsw_lookup(ccb->ccb_buf.b_dev)->d_strategy(&ccb->ccb_buf);
1546 }
1547 }
1548
1549 void
1550 sr_raid_set_chunk_state(struct sr_discipline *sd, int c, int new_state)
1551 {
1552 int old_state, s;
1553
1554 DNPRINTF(SR_D_STATE, "%s: %s: %s: sr_raid_set_chunk_state %d -> %d\n",
1555 DEVNAME(sd->sd_sc), sd->sd_vol.sv_meta.svm_devname,
1556 sd->sd_vol.sv_chunks[c]->src_meta.scm_devname, c, new_state);
1557
1558
1559 s = splbio();
1560 old_state = sd->sd_vol.sv_chunks[c]->src_meta.scm_status;
1561
1562
1563 if (old_state == new_state)
1564 goto done;
1565
1566 switch (old_state) {
1567 case BIOC_SDONLINE:
1568 switch (new_state) {
1569 case BIOC_SDOFFLINE:
1570 break;
1571 case BIOC_SDSCRUB:
1572 break;
1573 default:
1574 goto die;
1575 }
1576 break;
1577
1578 case BIOC_SDOFFLINE:
1579 if (new_state == BIOC_SDREBUILD) {
1580 ;
1581 } else
1582 goto die;
1583 break;
1584
1585 case BIOC_SDSCRUB:
1586 if (new_state == BIOC_SDONLINE) {
1587 ;
1588 } else
1589 goto die;
1590 break;
1591
1592 case BIOC_SDREBUILD:
1593 if (new_state == BIOC_SDONLINE) {
1594 ;
1595 } else
1596 goto die;
1597 break;
1598
1599 case BIOC_SDHOTSPARE:
1600 if (new_state == BIOC_SDREBUILD) {
1601 ;
1602 } else
1603 goto die;
1604 break;
1605
1606 default:
1607 die:
1608 splx(s);
1609 panic("%s: %s: %s: invalid chunk state transition "
1610 "%d -> %d\n", DEVNAME(sd->sd_sc),
1611 sd->sd_vol.sv_meta.svm_devname,
1612 sd->sd_vol.sv_chunks[c]->src_meta.scm_devname,
1613 old_state, new_state);
1614
1615 }
1616
1617 sd->sd_vol.sv_chunks[c]->src_meta.scm_status = new_state;
1618 sd->sd_set_vol_state(sd);
1619
1620 sd->sd_must_flush = 1;
1621 workq_add_task(NULL, 0, sr_save_metadata_callback, sd, NULL);
1622 done:
1623 splx(s);
1624 }
1625
1626 void
1627 sr_raid_set_vol_state(struct sr_discipline *sd)
1628 {
1629 int states[SR_MAX_STATES];
1630 int new_state, i, s, nd;
1631 int old_state = sd->sd_vol.sv_meta.svm_status;
1632
1633 DNPRINTF(SR_D_STATE, "%s: %s: sr_raid_set_vol_state\n",
1634 DEVNAME(sd->sd_sc), sd->sd_vol.sv_meta.svm_devname);
1635
1636 nd = sd->sd_vol.sv_meta.svm_no_chunk;
1637
1638 for (i = 0; i < SR_MAX_STATES; i++)
1639 states[i] = 0;
1640
1641 for (i = 0; i < nd; i++) {
1642 s = sd->sd_vol.sv_chunks[i]->src_meta.scm_status;
1643 if (s > SR_MAX_STATES)
1644 panic("%s: %s: %s: invalid chunk state",
1645 DEVNAME(sd->sd_sc),
1646 sd->sd_vol.sv_meta.svm_devname,
1647 sd->sd_vol.sv_chunks[i]->src_meta.scm_devname);
1648 states[s]++;
1649 }
1650
1651 if (states[BIOC_SDONLINE] == nd)
1652 new_state = BIOC_SVONLINE;
1653 else if (states[BIOC_SDONLINE] == 0)
1654 new_state = BIOC_SVOFFLINE;
1655 else if (states[BIOC_SDSCRUB] != 0)
1656 new_state = BIOC_SVSCRUB;
1657 else if (states[BIOC_SDREBUILD] != 0)
1658 new_state = BIOC_SVREBUILD;
1659 else if (states[BIOC_SDOFFLINE] != 0)
1660 new_state = BIOC_SVDEGRADED;
1661 else {
1662 printf("old_state = %d, ", old_state);
1663 for (i = 0; i < nd; i++)
1664 printf("%d = %d, ", i,
1665 sd->sd_vol.sv_chunks[i]->src_meta.scm_status);
1666 panic("invalid new_state");
1667 }
1668
1669 DNPRINTF(SR_D_STATE, "%s: %s: sr_raid_set_vol_state %d -> %d\n",
1670 DEVNAME(sd->sd_sc), sd->sd_vol.sv_meta.svm_devname,
1671 old_state, new_state);
1672
1673 switch (old_state) {
1674 case BIOC_SVONLINE:
1675 switch (new_state) {
1676 case BIOC_SVOFFLINE:
1677 case BIOC_SVDEGRADED:
1678 break;
1679 default:
1680 goto die;
1681 }
1682 break;
1683
1684 case BIOC_SVOFFLINE:
1685
1686 goto die;
1687
1688 case BIOC_SVSCRUB:
1689 switch (new_state) {
1690 case BIOC_SVONLINE:
1691 case BIOC_SVOFFLINE:
1692 case BIOC_SVDEGRADED:
1693 case BIOC_SVSCRUB:
1694 break;
1695 default:
1696 goto die;
1697 }
1698 break;
1699
1700 case BIOC_SVBUILDING:
1701 switch (new_state) {
1702 case BIOC_SVONLINE:
1703 case BIOC_SVOFFLINE:
1704 case BIOC_SVBUILDING:
1705 break;
1706 default:
1707 goto die;
1708 }
1709 break;
1710
1711 case BIOC_SVREBUILD:
1712 switch (new_state) {
1713 case BIOC_SVONLINE:
1714 case BIOC_SVOFFLINE:
1715 case BIOC_SVREBUILD:
1716 break;
1717 default:
1718 goto die;
1719 }
1720 break;
1721
1722 case BIOC_SVDEGRADED:
1723 switch (new_state) {
1724 case BIOC_SVOFFLINE:
1725 case BIOC_SVREBUILD:
1726 case BIOC_SVDEGRADED:
1727 break;
1728 default:
1729 goto die;
1730 }
1731 break;
1732
1733 default:
1734 die:
1735 panic("%s: %s: invalid volume state transition "
1736 "%d -> %d\n", DEVNAME(sd->sd_sc),
1737 sd->sd_vol.sv_meta.svm_devname,
1738 old_state, new_state);
1739
1740 }
1741
1742 sd->sd_vol.sv_meta.svm_status = new_state;
1743 }
1744
1745 u_int32_t
1746 sr_checksum(char *s, u_int32_t *p, u_int32_t size)
1747 {
1748 u_int32_t chk = 0;
1749 int i;
1750
1751 DNPRINTF(SR_D_MISC, "%s: sr_checksum %p %d\n", s, p, size);
1752
1753 if (size % sizeof(u_int32_t))
1754 return (0);
1755
1756 for (i = 0; i < size / sizeof(u_int32_t); i++)
1757 chk ^= p[i];
1758
1759 return (chk);
1760 }
1761
1762 void
1763 sr_get_uuid(struct sr_uuid *uuid)
1764 {
1765 int i;
1766
1767 for (i = 0; i < SR_UUID_MAX; i++)
1768 uuid->sui_id[i] = arc4random();
1769 }
1770
1771 void
1772 sr_print_uuid(struct sr_uuid *uuid, int cr)
1773 {
1774 int i;
1775
1776 for (i = 0; i < SR_UUID_MAX; i++)
1777 printf("%x%s", uuid->sui_id[i],
1778 i < SR_UUID_MAX - 1 ? ":" : "");
1779
1780 if (cr)
1781 printf("\n");
1782 }
1783
1784 int
1785 sr_clear_metadata(struct sr_discipline *sd)
1786 {
1787 struct sr_softc *sc = sd->sd_sc;
1788 struct sr_chunk_head *cl = &sd->sd_vol.sv_chunk_list;
1789 struct sr_chunk *ch_entry;
1790 struct buf b;
1791 size_t sz = SR_META_SIZE * 512;
1792 void *m;
1793 int rv = 0;
1794
1795 DNPRINTF(SR_D_META, "%s: sr_clear_metadata\n", DEVNAME(sc));
1796
1797 m = malloc(sz , M_DEVBUF, M_WAITOK);
1798 bzero(m, sz);
1799
1800 SLIST_FOREACH(ch_entry, cl, src_link) {
1801 bzero(&b, sizeof(b));
1802
1803 b.b_flags = B_WRITE;
1804 b.b_blkno = SR_META_OFFSET;
1805 b.b_bcount = sz;
1806 b.b_bufsize = sz;
1807 b.b_resid = sz;
1808 b.b_data = (void *)m;
1809 b.b_error = 0;
1810 b.b_proc = curproc;
1811 b.b_dev = ch_entry->src_dev_mm;
1812 b.b_vp = NULL;
1813 b.b_iodone = NULL;
1814 LIST_INIT(&b.b_dep);
1815 bdevsw_lookup(b.b_dev)->d_strategy(&b);
1816 biowait(&b);
1817
1818 if (b.b_flags & B_ERROR) {
1819 printf("%s: %s i/o error on block %d while clearing "
1820 "metadata %d\n", DEVNAME(sc),
1821 ch_entry->src_devname, b.b_blkno, b.b_error);
1822 rv++;
1823 continue;
1824 }
1825 }
1826
1827 free(m, M_DEVBUF);
1828 return (rv);
1829 }
1830
1831 int
1832 sr_already_assembled(struct sr_discipline *sd)
1833 {
1834 struct sr_softc *sc = sd->sd_sc;
1835 int i;
1836
1837 for (i = 0; i < SR_MAXSCSIBUS; i++)
1838 if (sc->sc_dis[i])
1839 if (!bcmp(&sd->sd_meta->ssd_uuid,
1840 &sc->sc_dis[i]->sd_meta->ssd_uuid,
1841 sizeof(sd->sd_meta->ssd_uuid)))
1842 return (1);
1843
1844 return (0);
1845 }
1846
1847 void
1848 sr_save_metadata_callback(void *arg1, void *arg2)
1849 {
1850 struct sr_discipline *sd = arg1;
1851 int s;
1852
1853 s = splbio();
1854
1855 if (sr_save_metadata(arg1, SR_VOL_DIRTY))
1856 printf("%s: save metadata failed\n",
1857 DEVNAME(sd->sd_sc));
1858
1859 sd->sd_must_flush = 0;
1860 splx(s);
1861 }
1862
1863 int
1864 sr_save_metadata(struct sr_discipline *sd, u_int32_t flags)
1865 {
1866 struct sr_softc *sc = sd->sd_sc;
1867 struct sr_metadata *sm = sd->sd_meta;
1868 struct sr_vol_meta *sv = &sd->sd_vol.sv_meta, *im_sv;
1869 struct sr_chunk_meta *im_sc;
1870 struct sr_chunk *src;
1871 struct buf b;
1872 struct sr_workunit wu;
1873 int i, rv = 1, ch = 0;
1874 size_t sz = SR_META_SIZE * 512;
1875
1876 DNPRINTF(SR_D_META, "%s: sr_save_metadata %s\n",
1877 DEVNAME(sc), sd->sd_vol.sv_meta.svm_devname);
1878
1879 if (!sm) {
1880 printf("%s: no in memory copy of metadata\n", DEVNAME(sc));
1881 goto bad;
1882 }
1883
1884 im_sv = (struct sr_vol_meta *)(sm + 1);
1885 im_sc = (struct sr_chunk_meta *)(im_sv + 1);
1886
1887 if (sizeof(struct sr_metadata) + sizeof(struct sr_vol_meta) +
1888 (sizeof(struct sr_chunk_meta) * sd->sd_vol.sv_meta.svm_no_chunk) >
1889 sz) {
1890 printf("%s: too much metadata; metadata NOT written\n",
1891 DEVNAME(sc));
1892 goto bad;
1893 }
1894
1895 if (sm->ssd_magic == 0) {
1896
1897 sm->ssd_magic = SR_MAGIC;
1898 sm->ssd_version = SR_META_VERSION;
1899 sm->ssd_size = sizeof(struct sr_metadata);
1900 sm->ssd_ondisk = 0;
1901 sm->ssd_flags = sd->sd_meta_flags;
1902
1903 bcopy(&sd->sd_vol.sv_chunks[0]->src_meta.scm_uuid,
1904 &sm->ssd_uuid,
1905 sizeof(struct sr_uuid));
1906
1907
1908 bcopy(sv, im_sv, sizeof(struct sr_vol_meta));
1909 bcopy(&sm->ssd_uuid, &im_sv->svm_uuid,
1910 sizeof(im_sv->svm_uuid));
1911 sm->ssd_vd_ver = SR_VOL_VERSION;
1912 sm->ssd_vd_size = sizeof(struct sr_vol_meta);
1913
1914
1915 for (i = 0; i < sd->sd_vol.sv_meta.svm_no_chunk; i++)
1916 bcopy(sd->sd_vol.sv_chunks[i], &im_sc[i],
1917 sizeof(struct sr_chunk_meta));
1918
1919 sm->ssd_chunk_ver = SR_CHUNK_VERSION;
1920 sm->ssd_chunk_size = sizeof(struct sr_chunk_meta);
1921 sm->ssd_chunk_no = sd->sd_vol.sv_meta.svm_no_chunk;
1922
1923
1924 sm->ssd_opt_ver = SR_OPT_VERSION;
1925 sm->ssd_opt_size = 0;
1926 sm->ssd_opt_no = 0;
1927 }
1928
1929
1930 sm->ssd_ondisk++;
1931 im_sv->svm_flags |= flags;
1932 sm->ssd_vd_chk = sr_checksum(DEVNAME(sc),
1933 (u_int32_t *)im_sv, sm->ssd_vd_size);
1934
1935 sm->ssd_chunk_chk = 0;
1936 for (ch = 0; ch < sm->ssd_chunk_no; ch++)
1937 sm->ssd_chunk_chk ^= sr_checksum(DEVNAME(sc),
1938 (u_int32_t *)&im_sc[ch], sm->ssd_chunk_size);
1939
1940 sr_print_metadata(sm);
1941
1942 for (i = 0; i < sm->ssd_chunk_no; i++) {
1943 memset(&b, 0, sizeof(b));
1944
1945 src = sd->sd_vol.sv_chunks[i];
1946
1947
1948 if (src->src_meta.scm_status == BIOC_SDOFFLINE)
1949 continue;
1950
1951
1952 sm->ssd_vd_volid = im_sv->svm_volid;
1953 sm->ssd_chunk_id = i;
1954 sm->ssd_checksum = sr_checksum(DEVNAME(sc),
1955 (u_int32_t *)sm, sm->ssd_size);
1956 DNPRINTF(SR_D_META, "%s: sr_save_metadata %s: volid: %d "
1957 "chunkid: %d checksum: 0x%x\n",
1958 DEVNAME(sc), src->src_meta.scm_devname,
1959 sm->ssd_vd_volid, sm->ssd_chunk_id,
1960 sm->ssd_checksum);
1961
1962 b.b_flags = B_WRITE;
1963 b.b_blkno = SR_META_OFFSET;
1964 b.b_bcount = sz;
1965 b.b_bufsize = sz;
1966 b.b_resid = sz;
1967 b.b_data = (void *)sm;
1968 b.b_error = 0;
1969 b.b_proc = curproc;
1970 b.b_dev = src->src_dev_mm;
1971 b.b_vp = NULL;
1972 b.b_iodone = NULL;
1973 LIST_INIT(&b.b_dep);
1974 bdevsw_lookup(b.b_dev)->d_strategy(&b);
1975 biowait(&b);
1976
1977
1978 sm->ssd_vd_volid = 0;
1979 sm->ssd_chunk_id = 0;
1980 sm->ssd_checksum = 0;
1981
1982
1983
1984 if (b.b_flags & B_ERROR) {
1985 printf("%s: %s i/o error on block %d while writing "
1986 "metadata %d\n", DEVNAME(sc),
1987 src->src_meta.scm_devname, b.b_blkno, b.b_error);
1988 goto bad;
1989 }
1990
1991 DNPRINTF(SR_D_META, "%s: sr_save_metadata written to %s\n",
1992 DEVNAME(sc), src->src_meta.scm_devname);
1993 }
1994
1995 bzero(&wu, sizeof(wu));
1996 wu.swu_fake = 1;
1997 wu.swu_dis = sd;
1998 sd->sd_scsi_sync(&wu);
1999
2000 rv = 0;
2001 bad:
2002 return (rv);
2003 }
2004
2005 int
2006 sr_boot_assembly(struct sr_softc *sc)
2007 {
2008 struct device *dv;
2009 struct buf *bp;
2010 struct bdevsw *bdsw;
2011 struct disklabel label;
2012 struct sr_metadata *sm;
2013 struct sr_metadata_list_head mlh;
2014 struct sr_metadata_list *mle, *mle2;
2015 struct sr_vol_meta *vm;
2016 struct bioc_createraid bc;
2017 dev_t dev, devr, *dt = NULL;
2018 int error, majdev, i, no_dev, rv = 0;
2019 size_t sz = SR_META_SIZE * 512;
2020
2021 DNPRINTF(SR_D_META, "%s: sr_boot_assembly\n", DEVNAME(sc));
2022
2023 SLIST_INIT(&mlh);
2024 bp = geteblk(sz);
2025 if (!bp)
2026 return (ENOMEM);
2027
2028 TAILQ_FOREACH(dv, &alldevs, dv_list) {
2029 if (dv->dv_class != DV_DISK)
2030 continue;
2031
2032 majdev = findblkmajor(dv);
2033 if (majdev == -1)
2034 continue;
2035
2036 bp->b_dev = dev = MAKEDISKDEV(majdev, dv->dv_unit, RAW_PART);
2037 bdsw = &bdevsw[majdev];
2038
2039
2040 if (!strncmp(dv->dv_xname, "fd", 2) ||
2041 !strncmp(dv->dv_xname, "cd", 2) ||
2042 !strncmp(dv->dv_xname, "rx", 2))
2043 continue;
2044
2045
2046
2047
2048
2049
2050
2051
2052 error = (*bdsw->d_open)(dev, FREAD, S_IFCHR, curproc);
2053 if (error) {
2054 DNPRINTF(SR_D_META, "%s: sr_boot_assembly open failed"
2055 "\n", DEVNAME(sc));
2056 continue;
2057 }
2058
2059
2060 error = (*bdsw->d_ioctl)(dev, DIOCGDINFO, (void *)&label,
2061 FREAD, curproc);
2062 if (error) {
2063 DNPRINTF(SR_D_META, "%s: sr_boot_assembly ioctl "
2064 "failed\n", DEVNAME(sc));
2065 error = (*bdsw->d_close)(dev, FREAD, S_IFCHR, curproc);
2066 continue;
2067 }
2068
2069
2070 error = (*bdsw->d_close)(dev, FREAD, S_IFCHR, curproc);
2071 if (error) {
2072 DNPRINTF(SR_D_META, "%s: sr_boot_assembly close "
2073 "failed\n", DEVNAME(sc));
2074 continue;
2075 }
2076
2077
2078 for (i = 0; i < MAXPARTITIONS; i++) {
2079 if (label.d_partitions[i].p_fstype != FS_RAID)
2080 continue;
2081
2082
2083 bp->b_dev = devr = MAKEDISKDEV(majdev, dv->dv_unit, i);
2084 error = (*bdsw->d_open)(devr, FREAD, S_IFCHR, curproc);
2085 if (error) {
2086 DNPRINTF(SR_D_META, "%s: sr_boot_assembly "
2087 "open failed, partition %d\n",
2088 DEVNAME(sc), i);
2089 continue;
2090 }
2091
2092 bp->b_flags = B_BUSY | B_READ;
2093 bp->b_blkno = SR_META_OFFSET;
2094 bp->b_cylinder = 0;
2095 bp->b_bcount = sz;
2096 bp->b_bufsize = sz;
2097 bp->b_resid = sz;
2098 (*bdsw->d_strategy)(bp);
2099 if ((error = biowait(bp))) {
2100 DNPRINTF(SR_D_META, "%s: sr_boot_assembly "
2101 "strategy failed, partition %d\n",
2102 DEVNAME(sc));
2103 error = (*bdsw->d_close)(devr, FREAD, S_IFCHR,
2104 curproc);
2105 continue;
2106 }
2107
2108 sm = (struct sr_metadata *)bp->b_data;
2109 if (!sr_validate_metadata(sc, devr, sm)) {
2110
2111 mle = malloc(sizeof(*mle), M_DEVBUF, M_WAITOK);
2112 bzero(mle, sizeof(*mle));
2113 mle->sml_metadata = malloc(sz, M_DEVBUF,
2114 M_WAITOK);
2115 bzero(mle->sml_metadata, sz);
2116 bcopy(sm, mle->sml_metadata, sz);
2117 mle->sml_mm = devr;
2118 SLIST_INSERT_HEAD(&mlh, mle, sml_link);
2119 }
2120
2121
2122 error = (*bdsw->d_close)(devr, FREAD, S_IFCHR,
2123 curproc);
2124 if (error) {
2125 DNPRINTF(SR_D_META, "%s: sr_boot_assembly "
2126 "close failed\n", DEVNAME(sc));
2127 continue;
2128 }
2129 }
2130 }
2131
2132
2133
2134
2135
2136
2137 dt = malloc(BIOC_CRMAXLEN, M_DEVBUF, M_WAITOK);
2138 SLIST_FOREACH(mle, &mlh, sml_link) {
2139
2140 if (mle->sml_used)
2141 continue;
2142
2143 no_dev = 0;
2144 bzero(dt, BIOC_CRMAXLEN);
2145 SLIST_FOREACH(mle2, &mlh, sml_link) {
2146
2147 if (mle2->sml_used)
2148 continue;
2149
2150
2151 if (mle->sml_metadata->ssd_vd_volid !=
2152 mle2->sml_metadata->ssd_vd_volid)
2153 continue;
2154
2155
2156 if (bcmp(&mle->sml_metadata->ssd_uuid,
2157 &mle2->sml_metadata->ssd_uuid,
2158 sizeof(mle->sml_metadata->ssd_uuid)))
2159 continue;
2160
2161
2162 if (dt[mle2->sml_metadata->ssd_chunk_id]) {
2163 printf("%s: chunk id already in use; can not "
2164 "assemble volume\n", DEVNAME(sc));
2165 goto unwind;
2166 }
2167 dt[mle2->sml_metadata->ssd_chunk_id] = mle2->sml_mm;
2168 no_dev++;
2169 mle2->sml_used = 1;
2170 }
2171 if (mle->sml_metadata->ssd_chunk_no != no_dev) {
2172 printf("%s: not assembling partial disk that used to "
2173 "be volume %d\n", DEVNAME(sc),
2174 mle->sml_metadata->ssd_vd_volid);
2175 continue;
2176 }
2177
2178 bzero(&bc, sizeof(bc));
2179 vm = (struct sr_vol_meta *)(mle->sml_metadata + 1);
2180 bc.bc_level = vm->svm_level;
2181 bc.bc_dev_list_len = no_dev * sizeof(dev_t);
2182 bc.bc_dev_list = dt;
2183 bc.bc_flags = BIOC_SCDEVT;
2184 sr_ioctl_createraid(sc, &bc, 0);
2185 rv++;
2186 }
2187
2188 unwind:
2189 if (dt)
2190 free(dt, M_DEVBUF);
2191
2192 for (mle = SLIST_FIRST(&mlh); mle != SLIST_END(&mlh); mle = mle2) {
2193 mle2 = SLIST_NEXT(mle, sml_link);
2194
2195 free(mle->sml_metadata, M_DEVBUF);
2196 free(mle, M_DEVBUF);
2197 }
2198 SLIST_INIT(&mlh);
2199
2200 return (rv);
2201 }
2202
2203 int
2204 sr_validate_metadata(struct sr_softc *sc, dev_t dev, struct sr_metadata *sm)
2205 {
2206 struct sr_vol_meta *mv;
2207 struct sr_chunk_meta *mc;
2208 char *name, devname[32];
2209 int maj, part, unit;
2210 u_int32_t chk;
2211
2212 DNPRINTF(SR_D_META, "%s: sr_validate_metadata(0x%x)\n",
2213 DEVNAME(sc), dev);
2214
2215 bzero(devname, sizeof(devname));
2216
2217 if (sm->ssd_magic != SR_MAGIC)
2218 goto bad;
2219
2220 maj = major(dev);
2221 part = DISKPART(dev);
2222 unit = DISKUNIT(dev);
2223
2224 name = findblkname(maj);
2225 if (name == NULL)
2226 goto bad;
2227
2228 snprintf(devname, sizeof(devname),
2229 "%s%d%c", name, unit, part + 'a');
2230 name = devname;
2231
2232
2233 if (sm->ssd_version != SR_META_VERSION) {
2234 printf("%s: %s can not read metadata version %d, "
2235 "expected %d\n", DEVNAME(sc),
2236 devname, sm->ssd_version,
2237 SR_META_VERSION);
2238 goto bad;
2239 }
2240 if (sm->ssd_size != sizeof(struct sr_metadata)) {
2241 printf("%s: %s invalid metadata size %d, "
2242 "expected %d\n", DEVNAME(sc),
2243 devname, sm->ssd_size,
2244 sizeof(struct sr_metadata));
2245 goto bad;
2246 }
2247 chk = sr_checksum(DEVNAME(sc), (u_int32_t *)sm, sm->ssd_size);
2248
2249
2250
2251
2252 if (chk != 0) {
2253 printf("%s: %s invalid metadata checksum 0x%x, "
2254 "expected 0x%x\n", DEVNAME(sc),
2255 devname, sm->ssd_checksum, chk);
2256 goto bad;
2257 }
2258
2259
2260 if (sm->ssd_vd_ver != SR_VOL_VERSION) {
2261 printf("%s: %s can not read volume metadata version "
2262 "%d, expected %d\n", DEVNAME(sc),
2263 devname, sm->ssd_vd_ver,
2264 SR_VOL_VERSION);
2265 goto bad;
2266 }
2267 if (sm->ssd_vd_size != sizeof(struct sr_vol_meta)) {
2268 printf("%s: %s invalid volume metadata size %d, "
2269 "expected %d\n", DEVNAME(sc),
2270 devname, sm->ssd_vd_size,
2271 sizeof(struct sr_vol_meta));
2272 goto bad;
2273 }
2274 mv = (struct sr_vol_meta *)(sm + 1);
2275 chk = sr_checksum(DEVNAME(sc), (u_int32_t *)mv, sm->ssd_vd_size);
2276 if (chk != sm->ssd_vd_chk) {
2277 printf("%s: %s invalid volume metadata checksum 0x%x, "
2278 "expected 0x%x\n", DEVNAME(sc),
2279 devname, sm->ssd_vd_chk, chk);
2280 goto bad;
2281 }
2282
2283
2284 if (sm->ssd_chunk_ver != SR_CHUNK_VERSION) {
2285 printf("%s: %s can not read chunk metadata version "
2286 "%d, expected %d\n", DEVNAME(sc),
2287 devname, sm->ssd_chunk_ver,
2288 SR_CHUNK_VERSION);
2289 goto bad;
2290 }
2291 if (sm->ssd_chunk_size != sizeof(struct sr_chunk_meta)) {
2292 printf("%s: %s invalid chunk metadata size %d, "
2293 "expected %d\n", DEVNAME(sc),
2294 devname, sm->ssd_chunk_size,
2295 sizeof(struct sr_chunk_meta));
2296 goto bad;
2297 }
2298
2299 mc = (struct sr_chunk_meta *)(mv + 1);
2300
2301 chk = sr_checksum(DEVNAME(sc), (u_int32_t *)(mc),
2302 sm->ssd_chunk_size * sm->ssd_chunk_no);
2303
2304 if (chk != sm->ssd_chunk_chk) {
2305 printf("%s: %s invalid chunk metadata checksum 0x%x, "
2306 "expected 0x%x\n", DEVNAME(sc),
2307 devname, sm->ssd_chunk_chk, chk);
2308 goto bad;
2309 }
2310
2311
2312 if (strncmp(mc[sm->ssd_chunk_id].scm_devname, name,
2313 sizeof(mc[sm->ssd_chunk_id].scm_devname)))
2314 printf("%s: roaming device %s -> %s\n", DEVNAME(sc),
2315 mc[sm->ssd_chunk_id].scm_devname, name);
2316
2317
2318 DNPRINTF(SR_D_META, "%s: sr_validate_metadata valid metadata %s\n",
2319 DEVNAME(sc), devname);
2320
2321 return (0);
2322 bad:
2323 DNPRINTF(SR_D_META, "%s: sr_validate_metadata invalid metadata %s\n",
2324 DEVNAME(sc), devname);
2325
2326 return (1);
2327 }
2328
2329 void
2330 sr_shutdown(void *arg)
2331 {
2332 struct sr_discipline *sd = arg;
2333 #ifdef SR_DEBUG
2334 struct sr_softc *sc = sd->sd_sc;
2335 #endif
2336 DNPRINTF(SR_D_DIS, "%s: sr_shutdown %s\n",
2337 DEVNAME(sc), sd->sd_vol.sv_meta.svm_devname);
2338
2339 sr_save_metadata(sd, 0);
2340
2341 sr_shutdown_discipline(sd);
2342 }
2343
2344 #ifndef SMALL_KERNEL
2345 int
2346 sr_create_sensors(struct sr_discipline *sd)
2347 {
2348 struct sr_softc *sc = sd->sd_sc;
2349 int rv = 1;
2350
2351 DNPRINTF(SR_D_STATE, "%s: %s: sr_create_sensors\n",
2352 DEVNAME(sc), sd->sd_vol.sv_meta.svm_devname);
2353
2354 strlcpy(sd->sd_vol.sv_sensordev.xname, DEVNAME(sc),
2355 sizeof(sd->sd_vol.sv_sensordev.xname));
2356
2357 sd->sd_vol.sv_sensor.type = SENSOR_DRIVE;
2358 sd->sd_vol.sv_sensor.status = SENSOR_S_UNKNOWN;
2359 strlcpy(sd->sd_vol.sv_sensor.desc, sd->sd_vol.sv_meta.svm_devname,
2360 sizeof(sd->sd_vol.sv_sensor.desc));
2361
2362 sensor_attach(&sd->sd_vol.sv_sensordev, &sd->sd_vol.sv_sensor);
2363
2364 if (sc->sc_sensors_running == 0) {
2365 if (sensor_task_register(sc, sr_refresh_sensors, 10) == NULL)
2366 goto bad;
2367 sc->sc_sensors_running = 1;
2368 }
2369 sensordev_install(&sd->sd_vol.sv_sensordev);
2370
2371 rv = 0;
2372 bad:
2373 return (rv);
2374 }
2375
2376 void
2377 sr_delete_sensors(struct sr_discipline *sd)
2378 {
2379 #ifdef SR_DEBUG
2380 struct sr_softc *sc = sd->sd_sc;
2381 #endif
2382 DNPRINTF(SR_D_STATE, "%s: %s: sr_delete_sensors\n",
2383 DEVNAME(sc), sd->sd_vol.sv_meta.svm_devname);
2384
2385 if (sd->sd_vol.sv_sensor_valid)
2386 sensordev_deinstall(&sd->sd_vol.sv_sensordev);
2387 }
2388
2389 void
2390 sr_refresh_sensors(void *arg)
2391 {
2392 struct sr_softc *sc = arg;
2393 int i, vol;
2394 struct sr_volume *sv;
2395
2396 DNPRINTF(SR_D_STATE, "%s: sr_refresh_sensors\n", DEVNAME(sc));
2397
2398 for (i = 0, vol = -1; i < SR_MAXSCSIBUS; i++) {
2399
2400 if (!sc->sc_dis[i])
2401 continue;
2402
2403 sv = &sc->sc_dis[i]->sd_vol;
2404
2405 switch(sv->sv_meta.svm_status) {
2406 case BIOC_SVOFFLINE:
2407 sv->sv_sensor.value = SENSOR_DRIVE_FAIL;
2408 sv->sv_sensor.status = SENSOR_S_CRIT;
2409 break;
2410
2411 case BIOC_SVDEGRADED:
2412 sv->sv_sensor.value = SENSOR_DRIVE_PFAIL;
2413 sv->sv_sensor.status = SENSOR_S_WARN;
2414 break;
2415
2416 case BIOC_SVSCRUB:
2417 case BIOC_SVONLINE:
2418 sv->sv_sensor.value = SENSOR_DRIVE_ONLINE;
2419 sv->sv_sensor.status = SENSOR_S_OK;
2420 break;
2421
2422 default:
2423 sv->sv_sensor.value = 0;
2424 sv->sv_sensor.status = SENSOR_S_UNKNOWN;
2425 }
2426 }
2427 }
2428 #endif
2429
2430 #ifdef SR_FANCY_STATS
2431 void sr_print_stats(void);
2432
2433 void
2434 sr_print_stats(void)
2435 {
2436 struct sr_softc *sc;
2437 struct sr_discipline *sd;
2438 int i, vol;
2439
2440 for (i = 0; i < softraid_cd.cd_ndevs; i++)
2441 if (softraid_cd.cd_devs[i]) {
2442 sc = softraid_cd.cd_devs[i];
2443
2444 break;
2445 }
2446
2447 if (!sc) {
2448 printf("no softraid softc found\n");
2449 return;
2450 }
2451
2452 for (i = 0, vol = -1; i < SR_MAXSCSIBUS; i++) {
2453
2454 if (!sc->sc_dis[i])
2455 continue;
2456
2457 sd = sc->sc_dis[i];
2458 printf("%s: ios pending: %d collisions %llu\n",
2459 sd->sd_vol.sv_meta.svm_devname,
2460 sd->sd_wu_pending,
2461 sd->sd_wu_collisions);
2462 }
2463 }
2464 #endif
2465
2466 #ifdef SR_DEBUG
2467 void
2468 sr_print_metadata(struct sr_metadata *sm)
2469 {
2470 struct sr_vol_meta *im_sv;
2471 struct sr_chunk_meta *im_sc;
2472 int ch;
2473
2474 im_sv = (struct sr_vol_meta *)(sm + 1);
2475 im_sc = (struct sr_chunk_meta *)(im_sv + 1);
2476
2477 DNPRINTF(SR_D_META, "\tmeta magic 0x%llx\n", sm->ssd_magic);
2478 DNPRINTF(SR_D_META, "\tmeta version %d\n", sm->ssd_version);
2479 DNPRINTF(SR_D_META, "\tmeta checksum 0x%x\n", sm->ssd_checksum);
2480 DNPRINTF(SR_D_META, "\tmeta size %d\n", sm->ssd_size);
2481 DNPRINTF(SR_D_META, "\tmeta on disk version %u\n", sm->ssd_ondisk);
2482 DNPRINTF(SR_D_META, "\tmeta uuid ");
2483 sr_print_uuid(&sm->ssd_uuid, 1);
2484 DNPRINTF(SR_D_META, "\tvd version %d\n", sm->ssd_vd_ver);
2485 DNPRINTF(SR_D_META, "\tvd size %lu\n", sm->ssd_vd_size);
2486 DNPRINTF(SR_D_META, "\tvd id %u\n", sm->ssd_vd_volid);
2487 DNPRINTF(SR_D_META, "\tvd checksum 0x%x\n", sm->ssd_vd_chk);
2488 DNPRINTF(SR_D_META, "\tchunk version %d\n", sm->ssd_chunk_ver);
2489 DNPRINTF(SR_D_META, "\tchunks %d\n", sm->ssd_chunk_no);
2490 DNPRINTF(SR_D_META, "\tchunk size %u\n", sm->ssd_chunk_size);
2491 DNPRINTF(SR_D_META, "\tchunk id %u\n", sm->ssd_chunk_id);
2492 DNPRINTF(SR_D_META, "\tchunk checksum 0x%x\n", sm->ssd_chunk_chk);
2493
2494 DNPRINTF(SR_D_META, "\t\tvol id %d\n", im_sv->svm_volid);
2495 DNPRINTF(SR_D_META, "\t\tvol status %d\n", im_sv->svm_status);
2496 DNPRINTF(SR_D_META, "\t\tvol flags 0x%x\n", im_sv->svm_flags);
2497 DNPRINTF(SR_D_META, "\t\tvol level %d\n", im_sv->svm_level);
2498 DNPRINTF(SR_D_META, "\t\tvol size %lld\n", im_sv->svm_size);
2499 DNPRINTF(SR_D_META, "\t\tvol name %s\n", im_sv->svm_devname);
2500 DNPRINTF(SR_D_META, "\t\tvol vendor %s\n", im_sv->svm_vendor);
2501 DNPRINTF(SR_D_META, "\t\tvol prod %s\n", im_sv->svm_product);
2502 DNPRINTF(SR_D_META, "\t\tvol rev %s\n", im_sv->svm_revision);
2503 DNPRINTF(SR_D_META, "\t\tvol no chunks %d\n", im_sv->svm_no_chunk);
2504 DNPRINTF(SR_D_META, "\t\tvol uuid ");
2505 sr_print_uuid(& im_sv->svm_uuid, 1);
2506
2507 for (ch = 0; ch < im_sv->svm_no_chunk; ch++) {
2508 DNPRINTF(SR_D_META, "\t\t\tchunk vol id %d\n",
2509 im_sc[ch].scm_volid);
2510 DNPRINTF(SR_D_META, "\t\t\tchunk id %d\n",
2511 im_sc[ch].scm_chunk_id);
2512 DNPRINTF(SR_D_META, "\t\t\tchunk status %d\n",
2513 im_sc[ch].scm_status);
2514 DNPRINTF(SR_D_META, "\t\t\tchunk name %s\n",
2515 im_sc[ch].scm_devname);
2516 DNPRINTF(SR_D_META, "\t\t\tchunk size %lld\n",
2517 im_sc[ch].scm_size);
2518 DNPRINTF(SR_D_META, "\t\t\tchunk coerced size %lld\n",
2519 im_sc[ch].scm_coerced_size);
2520 DNPRINTF(SR_D_META, "\t\t\tchunk uuid ");
2521 sr_print_uuid(&im_sc[ch].scm_uuid, 1);
2522 }
2523 }
2524 #endif
2525
2526
2527 int
2528 sr_raid1_alloc_resources(struct sr_discipline *sd)
2529 {
2530 int rv = EINVAL;
2531
2532 if (!sd)
2533 return (rv);
2534
2535 DNPRINTF(SR_D_DIS, "%s: sr_raid1_alloc_resources\n",
2536 DEVNAME(sd->sd_sc));
2537
2538 if (sr_alloc_wu(sd))
2539 goto bad;
2540 if (sr_alloc_ccb(sd))
2541 goto bad;
2542
2543 rv = 0;
2544 bad:
2545 return (rv);
2546 }
2547
2548 int
2549 sr_raid1_free_resources(struct sr_discipline *sd)
2550 {
2551 int rv = EINVAL;
2552
2553 if (!sd)
2554 return (rv);
2555
2556 DNPRINTF(SR_D_DIS, "%s: sr_raid1_free_resources\n",
2557 DEVNAME(sd->sd_sc));
2558
2559 sr_free_wu(sd);
2560 sr_free_ccb(sd);
2561
2562 if (sd->sd_meta)
2563 free(sd->sd_meta, M_DEVBUF);
2564
2565 rv = 0;
2566 return (rv);
2567 }
2568
2569 int
2570 sr_raid1_rw(struct sr_workunit *wu)
2571 {
2572 struct sr_discipline *sd = wu->swu_dis;
2573 struct scsi_xfer *xs = wu->swu_xs;
2574 struct sr_workunit *wup;
2575 struct sr_ccb *ccb;
2576 struct sr_chunk *scp;
2577 int ios, x, i, s, rt;
2578 daddr64_t blk;
2579
2580 DNPRINTF(SR_D_DIS, "%s: sr_raid1_rw 0x%02x\n", DEVNAME(sd->sd_sc),
2581 xs->cmd->opcode);
2582
2583 if (sd->sd_vol.sv_meta.svm_status == BIOC_SVOFFLINE) {
2584 DNPRINTF(SR_D_DIS, "%s: sr_raid1_rw device offline\n",
2585 DEVNAME(sd->sd_sc));
2586 goto bad;
2587 }
2588
2589 if (xs->datalen == 0) {
2590 printf("%s: %s: illegal block count\n",
2591 DEVNAME(sd->sd_sc), sd->sd_vol.sv_meta.svm_devname);
2592 goto bad;
2593 }
2594
2595 if (xs->cmdlen == 10)
2596 blk = _4btol(((struct scsi_rw_big *)xs->cmd)->addr);
2597 else if (xs->cmdlen == 6)
2598 blk = _3btol(((struct scsi_rw *)xs->cmd)->addr);
2599 else {
2600 printf("%s: %s: illegal cmdlen\n", DEVNAME(sd->sd_sc),
2601 sd->sd_vol.sv_meta.svm_devname);
2602 goto bad;
2603 }
2604
2605 wu->swu_blk_start = blk;
2606 wu->swu_blk_end = blk + (xs->datalen >> 9) - 1;
2607
2608 if (wu->swu_blk_end > sd->sd_vol.sv_meta.svm_size) {
2609 DNPRINTF(SR_D_DIS, "%s: sr_raid1_rw out of bounds start: %lld "
2610 "end: %lld length: %d\n", wu->swu_blk_start,
2611 wu->swu_blk_end, xs->datalen);
2612
2613 sd->sd_scsi_sense.error_code = SSD_ERRCODE_CURRENT |
2614 SSD_ERRCODE_VALID;
2615 sd->sd_scsi_sense.flags = SKEY_ILLEGAL_REQUEST;
2616 sd->sd_scsi_sense.add_sense_code = 0x21;
2617 sd->sd_scsi_sense.add_sense_code_qual = 0x00;
2618 sd->sd_scsi_sense.extra_len = 4;
2619 goto bad;
2620 }
2621
2622
2623 blk += SR_META_SIZE + SR_META_OFFSET;
2624
2625 if (xs->flags & SCSI_DATA_IN)
2626 ios = 1;
2627 else
2628 ios = sd->sd_vol.sv_meta.svm_no_chunk;
2629 wu->swu_io_count = ios;
2630
2631 for (i = 0; i < ios; i++) {
2632 ccb = sr_get_ccb(sd);
2633 if (!ccb) {
2634
2635 printf("%s: %s: too many ccbs queued\n",
2636 DEVNAME(sd->sd_sc),
2637 sd->sd_vol.sv_meta.svm_devname);
2638 goto bad;
2639 }
2640
2641 if (xs->flags & SCSI_POLL) {
2642 ccb->ccb_buf.b_flags = 0;
2643 ccb->ccb_buf.b_iodone = NULL;
2644 } else {
2645 ccb->ccb_buf.b_flags = B_CALL;
2646 ccb->ccb_buf.b_iodone = sr_raid1_intr;
2647 }
2648
2649 ccb->ccb_buf.b_blkno = blk;
2650 ccb->ccb_buf.b_bcount = xs->datalen;
2651 ccb->ccb_buf.b_bufsize = xs->datalen;
2652 ccb->ccb_buf.b_resid = xs->datalen;
2653 ccb->ccb_buf.b_data = xs->data;
2654 ccb->ccb_buf.b_error = 0;
2655 ccb->ccb_buf.b_proc = curproc;
2656 ccb->ccb_wu = wu;
2657
2658 if (xs->flags & SCSI_DATA_IN) {
2659 rt = 0;
2660 ragain:
2661
2662 x = sd->mds.mdd_raid1.sr1_counter++ %
2663 sd->sd_vol.sv_meta.svm_no_chunk;
2664 scp = sd->sd_vol.sv_chunks[x];
2665 switch (scp->src_meta.scm_status) {
2666 case BIOC_SDONLINE:
2667 case BIOC_SDSCRUB:
2668 ccb->ccb_buf.b_flags |= B_READ;
2669 break;
2670
2671 case BIOC_SDOFFLINE:
2672 case BIOC_SDREBUILD:
2673 case BIOC_SDHOTSPARE:
2674 if (rt++ < sd->sd_vol.sv_meta.svm_no_chunk)
2675 goto ragain;
2676
2677
2678 default:
2679
2680 printf("%s: is offline, can't read\n",
2681 DEVNAME(sd->sd_sc));
2682 sr_put_ccb(ccb);
2683 goto bad;
2684 }
2685 } else {
2686
2687 x = i;
2688 scp = sd->sd_vol.sv_chunks[x];
2689 switch (scp->src_meta.scm_status) {
2690 case BIOC_SDONLINE:
2691 case BIOC_SDSCRUB:
2692 case BIOC_SDREBUILD:
2693 ccb->ccb_buf.b_flags |= B_WRITE;
2694 break;
2695
2696 case BIOC_SDHOTSPARE:
2697 case BIOC_SDOFFLINE:
2698 wu->swu_io_count--;
2699 sr_put_ccb(ccb);
2700 continue;
2701
2702 default:
2703 goto bad;
2704 }
2705
2706 }
2707 ccb->ccb_target = x;
2708 ccb->ccb_buf.b_dev = sd->sd_vol.sv_chunks[x]->src_dev_mm;
2709 ccb->ccb_buf.b_vp = NULL;
2710
2711 LIST_INIT(&ccb->ccb_buf.b_dep);
2712
2713 TAILQ_INSERT_TAIL(&wu->swu_ccb, ccb, ccb_link);
2714
2715 DNPRINTF(SR_D_DIS, "%s: %s: sr_raid1: b_bcount: %d "
2716 "b_blkno: %x b_flags 0x%0x b_data %p\n",
2717 DEVNAME(sd->sd_sc), sd->sd_vol.sv_meta.svm_devname,
2718 ccb->ccb_buf.b_bcount, ccb->ccb_buf.b_blkno,
2719 ccb->ccb_buf.b_flags, ccb->ccb_buf.b_data);
2720 }
2721
2722 s = splbio();
2723
2724
2725 if (wu->swu_state == SR_WU_RESTART)
2726 goto start;
2727
2728
2729 if (wu->swu_state == SR_WU_REQUEUE)
2730 goto queued;
2731
2732
2733 TAILQ_FOREACH_REVERSE(wup, &sd->sd_wu_pendq, sr_wu_list, swu_link) {
2734 if (wu->swu_blk_end < wup->swu_blk_start ||
2735 wup->swu_blk_end < wu->swu_blk_start)
2736 continue;
2737
2738
2739 wu->swu_state = SR_WU_DEFERRED;
2740 if (wup->swu_collider)
2741
2742 while (wup->swu_collider)
2743 wup = wup->swu_collider;
2744
2745 wup->swu_collider = wu;
2746 TAILQ_INSERT_TAIL(&sd->sd_wu_defq, wu, swu_link);
2747 sd->sd_wu_collisions++;
2748 goto queued;
2749 }
2750
2751
2752 start:
2753 sr_raid_startwu(wu);
2754 queued:
2755 splx(s);
2756 return (0);
2757 bad:
2758
2759 return (1);
2760 }
2761
2762 void
2763 sr_raid1_intr(struct buf *bp)
2764 {
2765 struct sr_ccb *ccb = (struct sr_ccb *)bp;
2766 struct sr_workunit *wu = ccb->ccb_wu, *wup;
2767 struct sr_discipline *sd = wu->swu_dis;
2768 struct scsi_xfer *xs = wu->swu_xs;
2769 struct sr_softc *sc = sd->sd_sc;
2770 int s, pend;
2771
2772 DNPRINTF(SR_D_INTR, "%s: sr_intr bp %x xs %x\n",
2773 DEVNAME(sc), bp, xs);
2774
2775 DNPRINTF(SR_D_INTR, "%s: sr_intr: b_bcount: %d b_resid: %d"
2776 " b_flags: 0x%0x block: %lld target: %d\n", DEVNAME(sc),
2777 ccb->ccb_buf.b_bcount, ccb->ccb_buf.b_resid, ccb->ccb_buf.b_flags,
2778 ccb->ccb_buf.b_blkno, ccb->ccb_target);
2779
2780 s = splbio();
2781
2782 if (ccb->ccb_buf.b_flags & B_ERROR) {
2783 DNPRINTF(SR_D_INTR, "%s: i/o error on block %lld target: %d\n",
2784 DEVNAME(sc), ccb->ccb_buf.b_blkno, ccb->ccb_target);
2785 wu->swu_ios_failed++;
2786 ccb->ccb_state = SR_CCB_FAILED;
2787 if (ccb->ccb_target != -1)
2788 sd->sd_set_chunk_state(sd, ccb->ccb_target,
2789 BIOC_SDOFFLINE);
2790 else
2791 panic("%s: invalid target on wu: %p", DEVNAME(sc), wu);
2792 } else {
2793 ccb->ccb_state = SR_CCB_OK;
2794 wu->swu_ios_succeeded++;
2795 }
2796 wu->swu_ios_complete++;
2797
2798 DNPRINTF(SR_D_INTR, "%s: sr_intr: comp: %d count: %d failed: %d\n",
2799 DEVNAME(sc), wu->swu_ios_complete, wu->swu_io_count,
2800 wu->swu_ios_failed);
2801
2802 if (wu->swu_ios_complete >= wu->swu_io_count) {
2803
2804 if (wu->swu_ios_failed == wu->swu_ios_complete) {
2805 if (xs->flags & SCSI_DATA_IN) {
2806 printf("%s: retrying read on block %lld\n",
2807 DEVNAME(sc), ccb->ccb_buf.b_blkno);
2808 sr_put_ccb(ccb);
2809 TAILQ_INIT(&wu->swu_ccb);
2810 wu->swu_state = SR_WU_RESTART;
2811 if (sd->sd_scsi_rw(wu))
2812 goto bad;
2813 else
2814 goto retry;
2815 } else {
2816 printf("%s: permanently fail write on block "
2817 "%lld\n", DEVNAME(sc),
2818 ccb->ccb_buf.b_blkno);
2819 xs->error = XS_DRIVER_STUFFUP;
2820 goto bad;
2821 }
2822 }
2823
2824 xs->error = XS_NOERROR;
2825 xs->resid = 0;
2826 xs->flags |= ITSDONE;
2827
2828 pend = 0;
2829 TAILQ_FOREACH(wup, &sd->sd_wu_pendq, swu_link) {
2830 if (wu == wup) {
2831
2832 TAILQ_REMOVE(&sd->sd_wu_pendq, wu, swu_link);
2833 pend = 1;
2834
2835 if (wu->swu_collider) {
2836 if (wu->swu_ios_failed)
2837
2838 sr_raid1_recreate_wu(wu->swu_collider);
2839
2840
2841 wu->swu_collider->swu_state =
2842 SR_WU_INPROGRESS;
2843 TAILQ_REMOVE(&sd->sd_wu_defq,
2844 wu->swu_collider, swu_link);
2845 sr_raid_startwu(wu->swu_collider);
2846 }
2847 break;
2848 }
2849 }
2850
2851 if (!pend)
2852 printf("%s: wu: %p not on pending queue\n",
2853 DEVNAME(sc), wu);
2854
2855
2856 sr_put_wu(wu);
2857 scsi_done(xs);
2858
2859 if (sd->sd_sync && sd->sd_wu_pending == 0)
2860 wakeup(sd);
2861 }
2862
2863 retry:
2864 splx(s);
2865 return;
2866 bad:
2867 xs->error = XS_DRIVER_STUFFUP;
2868 xs->flags |= ITSDONE;
2869 sr_put_wu(wu);
2870 scsi_done(xs);
2871 splx(s);
2872 }
2873
2874 void
2875 sr_raid1_recreate_wu(struct sr_workunit *wu)
2876 {
2877 struct sr_discipline *sd = wu->swu_dis;
2878 struct sr_workunit *wup = wu;
2879 struct sr_ccb *ccb;
2880
2881 do {
2882 DNPRINTF(SR_D_INTR, "%s: sr_raid1_recreate_wu: %p\n", wup);
2883
2884
2885 while ((ccb = TAILQ_FIRST(&wup->swu_ccb)) != NULL) {
2886 TAILQ_REMOVE(&wup->swu_ccb, ccb, ccb_link);
2887 sr_put_ccb(ccb);
2888 }
2889 TAILQ_INIT(&wup->swu_ccb);
2890
2891
2892 wup->swu_state = SR_WU_REQUEUE;
2893 if (sd->sd_scsi_rw(wup))
2894 panic("could not requeue io");
2895
2896 wup = wup->swu_collider;
2897 } while (wup);
2898 }
2899
2900 #ifdef CRYPTO
2901
2902 struct cryptop *
2903 sr_raidc_getcryptop(struct sr_workunit *wu, int encrypt)
2904 {
2905 struct scsi_xfer *xs = wu->swu_xs;
2906 struct sr_discipline *sd = wu->swu_dis;
2907 struct cryptop *crp;
2908 struct cryptodesc *crd;
2909 struct uio *uio;
2910 int flags, i, n;
2911 int blk = 0;
2912
2913 DNPRINTF(SR_D_DIS, "%s: sr_raidc_getcryptop wu: %p encrypt: %d\n",
2914 DEVNAME(sd->sd_sc), wu, encrypt);
2915
2916 uio = malloc(sizeof(*uio), M_DEVBUF, M_WAITOK);
2917 memset(uio, 0, sizeof(*uio));
2918 uio->uio_iov = malloc(sizeof(*uio->uio_iov), M_DEVBUF, M_WAITOK);
2919 uio->uio_iovcnt = 1;
2920 uio->uio_iov->iov_base = xs->data;
2921 uio->uio_iov->iov_len = xs->datalen;
2922
2923 if (xs->cmdlen == 10)
2924 blk = _4btol(((struct scsi_rw_big *)xs->cmd)->addr);
2925 else if (xs->cmdlen == 6)
2926 blk = _3btol(((struct scsi_rw *)xs->cmd)->addr);
2927
2928 n = xs->datalen >> 9;
2929 flags = (encrypt ? CRD_F_ENCRYPT : 0) |
2930 CRD_F_IV_PRESENT | CRD_F_IV_EXPLICIT;
2931
2932 crp = crypto_getreq(n);
2933
2934 crp->crp_sid = sd->mds.mdd_raidc.src_sid;
2935 crp->crp_ilen = xs->datalen;
2936 crp->crp_alloctype = M_DEVBUF;
2937 crp->crp_buf = uio;
2938 for (i = 0, crd = crp->crp_desc; crd; i++, crd = crd->crd_next) {
2939 crd->crd_skip = 512 * i;
2940 crd->crd_len = 512;
2941 crd->crd_inject = 0;
2942 crd->crd_flags = flags;
2943 crd->crd_alg = CRYPTO_AES_CBC;
2944 crd->crd_klen = 256;
2945 crd->crd_rnd = 14;
2946 crd->crd_key = sd->mds.mdd_raidc.src_key;
2947 memset(crd->crd_iv, blk + i, sizeof(crd->crd_iv));
2948 }
2949
2950 return (crp);
2951 }
2952
2953 void *
2954 sr_raidc_putcryptop(struct cryptop *crp)
2955 {
2956 struct uio *uio = crp->crp_buf;
2957 void *opaque = crp->crp_opaque;
2958
2959 DNPRINTF(SR_D_DIS, "sr_raidc_putcryptop crp: %p\n", crp);
2960
2961 free(uio->uio_iov, M_DEVBUF);
2962 free(uio, M_DEVBUF);
2963 crypto_freereq(crp);
2964
2965 return (opaque);
2966 }
2967
2968 int
2969 sr_raidc_alloc_resources(struct sr_discipline *sd)
2970 {
2971 struct cryptoini cri;
2972
2973 if (!sd)
2974 return (EINVAL);
2975
2976 DNPRINTF(SR_D_DIS, "%s: sr_raidc_alloc_resources\n",
2977 DEVNAME(sd->sd_sc));
2978
2979 if (sr_alloc_wu(sd))
2980 return (ENOMEM);
2981 if (sr_alloc_ccb(sd))
2982 return (ENOMEM);
2983
2984
2985 memset(sd->mds.mdd_raidc.src_key, 'k',
2986 sizeof sd->mds.mdd_raidc.src_key);
2987
2988 bzero(&cri, sizeof(cri));
2989 cri.cri_alg = CRYPTO_AES_CBC;
2990 cri.cri_klen = 256;
2991 cri.cri_rnd = 14;
2992 cri.cri_key = sd->mds.mdd_raidc.src_key;
2993
2994 return (crypto_newsession(&sd->mds.mdd_raidc.src_sid, &cri, 0));
2995 }
2996
2997 int
2998 sr_raidc_free_resources(struct sr_discipline *sd)
2999 {
3000 int rv = EINVAL;
3001
3002 if (!sd)
3003 return (rv);
3004
3005 DNPRINTF(SR_D_DIS, "%s: sr_raidc_free_resources\n",
3006 DEVNAME(sd->sd_sc));
3007
3008 sr_free_wu(sd);
3009 sr_free_ccb(sd);
3010
3011 if (sd->sd_meta)
3012 free(sd->sd_meta, M_DEVBUF);
3013
3014 rv = 0;
3015 return (rv);
3016 }
3017
3018 int
3019 sr_raidc_rw(struct sr_workunit *wu)
3020 {
3021 struct cryptop *crp;
3022
3023 DNPRINTF(SR_D_DIS, "%s: sr_raidc_rw wu: %p\n",
3024 DEVNAME(wu->swu_dis->sd_sc), wu);
3025
3026 crp = sr_raidc_getcryptop(wu, 1);
3027 crp->crp_callback = sr_raidc_rw2;
3028 crp->crp_opaque = wu;
3029 crypto_dispatch(crp);
3030
3031 return (0);
3032 }
3033
3034 int
3035 sr_raidc_rw2(struct cryptop *crp)
3036 {
3037 struct sr_workunit *wu = sr_raidc_putcryptop(crp);
3038 struct sr_discipline *sd = wu->swu_dis;
3039 struct scsi_xfer *xs = wu->swu_xs;
3040 struct sr_workunit *wup;
3041 struct sr_ccb *ccb;
3042 struct sr_chunk *scp;
3043 int s, rt;
3044 daddr64_t blk;
3045
3046 DNPRINTF(SR_D_DIS, "%s: sr_raidc_rw2 0x%02x\n", DEVNAME(sd->sd_sc),
3047 xs->cmd->opcode);
3048
3049 if (sd->sd_vol.sv_meta.svm_status == BIOC_SVOFFLINE) {
3050 DNPRINTF(SR_D_DIS, "%s: sr_raidc_rw device offline\n",
3051 DEVNAME(sd->sd_sc));
3052 goto bad;
3053 }
3054
3055 if (xs->datalen == 0) {
3056 printf("%s: %s: illegal block count\n",
3057 DEVNAME(sd->sd_sc), sd->sd_vol.sv_meta.svm_devname);
3058 goto bad;
3059 }
3060
3061 if (xs->cmdlen == 10)
3062 blk = _4btol(((struct scsi_rw_big *)xs->cmd)->addr);
3063 else if (xs->cmdlen == 6)
3064 blk = _3btol(((struct scsi_rw *)xs->cmd)->addr);
3065 else {
3066 printf("%s: %s: illegal cmdlen\n", DEVNAME(sd->sd_sc),
3067 sd->sd_vol.sv_meta.svm_devname);
3068 goto bad;
3069 }
3070
3071 wu->swu_blk_start = blk;
3072 wu->swu_blk_end = blk + (xs->datalen >> 9) - 1;
3073
3074 if (wu->swu_blk_end > sd->sd_vol.sv_meta.svm_size) {
3075 DNPRINTF(SR_D_DIS, "%s: sr_raidc_rw2 out of bounds start: %lld "
3076 "end: %lld length: %d\n", wu->swu_blk_start,
3077 wu->swu_blk_end, xs->datalen);
3078
3079 sd->sd_scsi_sense.error_code = SSD_ERRCODE_CURRENT |
3080 SSD_ERRCODE_VALID;
3081 sd->sd_scsi_sense.flags = SKEY_ILLEGAL_REQUEST;
3082 sd->sd_scsi_sense.add_sense_code = 0x21;
3083 sd->sd_scsi_sense.add_sense_code_qual = 0x00;
3084 sd->sd_scsi_sense.extra_len = 4;
3085 goto bad;
3086 }
3087
3088
3089 blk += SR_META_SIZE + SR_META_OFFSET;
3090
3091 wu->swu_io_count = 1;
3092
3093 ccb = sr_get_ccb(sd);
3094 if (!ccb) {
3095
3096 printf("%s: %s: too many ccbs queued\n",
3097 DEVNAME(sd->sd_sc),
3098 sd->sd_vol.sv_meta.svm_devname);
3099 goto bad;
3100 }
3101
3102 if (xs->flags & SCSI_POLL) {
3103 panic("not yet, crypto poll");
3104 ccb->ccb_buf.b_flags = 0;
3105 ccb->ccb_buf.b_iodone = NULL;
3106 } else {
3107 ccb->ccb_buf.b_flags = B_CALL;
3108 ccb->ccb_buf.b_iodone = sr_raidc_intr;
3109 }
3110
3111 ccb->ccb_buf.b_blkno = blk;
3112 ccb->ccb_buf.b_bcount = xs->datalen;
3113 ccb->ccb_buf.b_bufsize = xs->datalen;
3114 ccb->ccb_buf.b_resid = xs->datalen;
3115 ccb->ccb_buf.b_data = xs->data;
3116 ccb->ccb_buf.b_error = 0;
3117 ccb->ccb_buf.b_proc = curproc;
3118 ccb->ccb_wu = wu;
3119
3120 if (xs->flags & SCSI_DATA_IN) {
3121 rt = 0;
3122 ragain:
3123 scp = sd->sd_vol.sv_chunks[0];
3124 switch (scp->src_meta.scm_status) {
3125 case BIOC_SDONLINE:
3126 case BIOC_SDSCRUB:
3127 ccb->ccb_buf.b_flags |= B_READ;
3128 break;
3129
3130 case BIOC_SDOFFLINE:
3131 case BIOC_SDREBUILD:
3132 case BIOC_SDHOTSPARE:
3133 if (rt++ < sd->sd_vol.sv_meta.svm_no_chunk)
3134 goto ragain;
3135
3136
3137 default:
3138
3139 printf("%s: is offline, can't read\n",
3140 DEVNAME(sd->sd_sc));
3141 sr_put_ccb(ccb);
3142 goto bad;
3143 }
3144 } else {
3145 scp = sd->sd_vol.sv_chunks[0];
3146 switch (scp->src_meta.scm_status) {
3147 case BIOC_SDONLINE:
3148 case BIOC_SDSCRUB:
3149 case BIOC_SDREBUILD:
3150 ccb->ccb_buf.b_flags |= B_WRITE;
3151 break;
3152
3153 case BIOC_SDHOTSPARE:
3154 case BIOC_SDOFFLINE:
3155 wu->swu_io_count--;
3156 sr_put_ccb(ccb);
3157 goto bad;
3158
3159 default:
3160 goto bad;
3161 }
3162
3163 }
3164 ccb->ccb_target = 0;
3165 ccb->ccb_buf.b_dev = sd->sd_vol.sv_chunks[0]->src_dev_mm;
3166 ccb->ccb_buf.b_vp = NULL;
3167
3168 LIST_INIT(&ccb->ccb_buf.b_dep);
3169
3170 TAILQ_INSERT_TAIL(&wu->swu_ccb, ccb, ccb_link);
3171
3172 DNPRINTF(SR_D_DIS, "%s: %s: sr_raidc: b_bcount: %d "
3173 "b_blkno: %x b_flags 0x%0x b_data %p\n",
3174 DEVNAME(sd->sd_sc), sd->sd_vol.sv_meta.svm_devname,
3175 ccb->ccb_buf.b_bcount, ccb->ccb_buf.b_blkno,
3176 ccb->ccb_buf.b_flags, ccb->ccb_buf.b_data);
3177
3178
3179
3180 s = splbio();
3181 TAILQ_FOREACH_REVERSE(wup, &sd->sd_wu_pendq, sr_wu_list, swu_link) {
3182 if (wu->swu_blk_end < wup->swu_blk_start ||
3183 wup->swu_blk_end < wu->swu_blk_start)
3184 continue;
3185
3186
3187 wu->swu_state = SR_WU_DEFERRED;
3188 if (wup->swu_collider)
3189
3190 while (wup->swu_collider)
3191 wup = wup->swu_collider;
3192
3193 wup->swu_collider = wu;
3194 TAILQ_INSERT_TAIL(&sd->sd_wu_defq, wu, swu_link);
3195 sd->sd_wu_collisions++;
3196 goto queued;
3197 }
3198
3199
3200
3201 sr_raid_startwu(wu);
3202
3203 queued:
3204 splx(s);
3205 return (0);
3206 bad:
3207
3208 return (1);
3209 }
3210
3211 void
3212 sr_raidc_intr(struct buf *bp)
3213 {
3214 struct sr_ccb *ccb = (struct sr_ccb *)bp;
3215 struct sr_workunit *wu = ccb->ccb_wu;
3216 struct cryptop *crp;
3217 #ifdef SR_DEBUG
3218 struct sr_softc *sc = wu->swu_dis->sd_sc;
3219 #endif
3220
3221 DNPRINTF(SR_D_INTR, "%s: sr_raidc_intr bp: %x xs: %x\n",
3222 DEVNAME(sc), bp, wu->swu_xs);
3223
3224 DNPRINTF(SR_D_INTR, "%s: sr_raidc_intr: b_bcount: %d b_resid: %d"
3225 " b_flags: 0x%0x\n", DEVNAME(sc), ccb->ccb_buf.b_bcount,
3226 ccb->ccb_buf.b_resid, ccb->ccb_buf.b_flags);
3227
3228 crp = sr_raidc_getcryptop(wu, 0);
3229 crp->crp_callback = sr_raidc_intr2;
3230 crp->crp_opaque = bp;
3231 crypto_dispatch(crp);
3232 }
3233
3234 int
3235 sr_raidc_intr2(struct cryptop *crp)
3236 {
3237 struct buf *bp = sr_raidc_putcryptop(crp);
3238 struct sr_ccb *ccb = (struct sr_ccb *)bp;
3239 struct sr_workunit *wu = ccb->ccb_wu, *wup;
3240 struct sr_discipline *sd = wu->swu_dis;
3241 struct scsi_xfer *xs = wu->swu_xs;
3242 struct sr_softc *sc = sd->sd_sc;
3243 int s, pend;
3244
3245 DNPRINTF(SR_D_INTR, "%s: sr_raidc_intr2 crp: %x xs: %x\n",
3246 DEVNAME(sc), crp, xs);
3247
3248 s = splbio();
3249
3250 if (ccb->ccb_buf.b_flags & B_ERROR) {
3251 printf("%s: i/o error on block %lld\n", DEVNAME(sc),
3252 ccb->ccb_buf.b_blkno);
3253 wu->swu_ios_failed++;
3254 ccb->ccb_state = SR_CCB_FAILED;
3255 if (ccb->ccb_target != -1)
3256 sd->sd_set_chunk_state(sd, ccb->ccb_target,
3257 BIOC_SDOFFLINE);
3258 else
3259 panic("%s: invalid target on wu: %p", DEVNAME(sc), wu);
3260 } else {
3261 ccb->ccb_state = SR_CCB_OK;
3262 wu->swu_ios_succeeded++;
3263 }
3264 wu->swu_ios_complete++;
3265
3266 DNPRINTF(SR_D_INTR, "%s: sr_raidc_intr2: comp: %d count: %d\n",
3267 DEVNAME(sc), wu->swu_ios_complete, wu->swu_io_count);
3268
3269 if (wu->swu_ios_complete == wu->swu_io_count) {
3270 if (wu->swu_ios_failed == wu->swu_ios_complete)
3271 xs->error = XS_DRIVER_STUFFUP;
3272 else
3273 xs->error = XS_NOERROR;
3274
3275 xs->resid = 0;
3276 xs->flags |= ITSDONE;
3277
3278 pend = 0;
3279 TAILQ_FOREACH(wup, &sd->sd_wu_pendq, swu_link) {
3280 if (wu == wup) {
3281
3282 TAILQ_REMOVE(&sd->sd_wu_pendq, wu, swu_link);
3283 pend = 1;
3284
3285 if (wu->swu_collider) {
3286
3287 wu->swu_collider->swu_state =
3288 SR_WU_INPROGRESS;
3289 TAILQ_REMOVE(&sd->sd_wu_defq,
3290 wu->swu_collider, swu_link);
3291 sr_raid_startwu(wu->swu_collider);
3292 }
3293 break;
3294 }
3295 }
3296
3297 if (!pend)
3298 printf("%s: wu: %p not on pending queue\n",
3299 DEVNAME(sc), wu);
3300
3301
3302 sr_put_wu(wu);
3303 scsi_done(xs);
3304
3305 if (sd->sd_sync && sd->sd_wu_pending == 0)
3306 wakeup(sd);
3307 }
3308
3309 splx(s);
3310
3311 return (0);
3312 }
3313 #endif