sd.c revision 1.18.2.4 1 /*
2 * Written by Julian Elischer (julian (at) dialix.oz.au)
3 * for TRW Financial Systems for use under the MACH(2.5) operating system.
4 *
5 * TRW Financial Systems, in accordance with their agreement with Carnegie
6 * Mellon University, makes this software available to CMU to distribute
7 * or use in any manner that they see fit as long as this message is kept with
8 * the software. For this reason TFS also grants any other persons or
9 * organisations permission to use or modify this software.
10 *
11 * TFS supplies this software to be publicly redistributed
12 * on the understanding that TFS is not responsible for the correct
13 * functioning of this software in any circumstances.
14 *
15 * Ported to run under 386BSD by Julian Elischer (julian (at) dialix.oz.au) Sept 1992
16 *
17 * $Id: sd.c,v 1.18.2.4 1993/11/24 19:19:49 mycroft Exp $
18 */
19
20 #include <sys/types.h>
21 #include <sys/param.h>
22 #include <sys/dkbad.h>
23 #include <sys/systm.h>
24 #include <sys/conf.h>
25 #include <sys/file.h>
26 #include <sys/stat.h>
27 #include <sys/ioctl.h>
28 #include <sys/buf.h>
29 #include <sys/uio.h>
30 #include <sys/malloc.h>
31 #include <sys/errno.h>
32 #include <sys/device.h>
33 #include <sys/disklabel.h>
34 #include <sys/disk.h>
35
36 #include <scsi/scsi_all.h>
37 #include <scsi/scsi_disk.h>
38 #include <scsi/scsiconf.h>
39
40 #ifdef DDB
41 int Debugger();
42 #else /* DDB */
43 #define Debugger()
44 #endif /* DDB */
45
46 #define SECSIZE 512
47 #define SDOUTSTANDING 2
48 #define SDQSIZE 4
49 #define SD_RETRIES 4
50
51 #define MAKESDDEV(maj, unit, part) (makedev(maj,(unit<<3)|part))
52 #define SDPART(z) (minor(z) & 7)
53 #define SDUNIT(z) (minor(z) >> 3)
54 #define RAW_PART 3
55
56 void sdstrategy();
57 void sdstart();
58
59 struct scsi_device sd_switch =
60 {
61 NULL, /* Use default error handler */
62 sdstart, /* have a queue, served by this */
63 NULL, /* have no async handler */
64 NULL, /* Use default 'done' routine */
65 "sd",
66 0
67 };
68
69 struct sd_data {
70 struct dkdevice sc_dk;
71
72 u_int32 flags;
73 #define SDINIT 0x04 /* device has been init'd */
74 #define SDHAVELABEL 0x10 /* have read the label */
75 #define SDDOSPART 0x20 /* Have read the DOS partition table */
76 #define SDWRITEPROT 0x40 /* Device in readonly mode (S/W) */
77 struct scsi_link *sc_link; /* contains our targ, lun etc. */
78 u_int32 ad_info; /* info about the adapter */
79 u_int32 cmdscount; /* cmds allowed outstanding by board */
80 boolean wlabel; /* label is writable */
81 struct disk_parms {
82 u_char heads; /* Number of heads */
83 u_int16 cyls; /* Number of cylinders */
84 u_char sectors; /*dubious *//* Number of sectors/track */
85 u_int16 secsiz; /* Number of bytes/sector */
86 u_int32 disksize; /* total number sectors */
87 } params;
88 u_int32 partflags[MAXPARTITIONS]; /* per partition flags */
89 #define SDOPEN 0x01
90 u_int32 openparts; /* one bit for each open partition */
91 u_int32 sd_start_of_unix; /* unix vs dos partitions */
92 struct buf buf_queue;
93 u_int32 xfer_block_wait;
94 };
95
96 void sdattach __P((struct device *, struct device *, void *));
97
98 struct cfdriver sdcd =
99 { NULL, "sd", scsi_targmatch, sdattach, DV_DISK, sizeof(struct sd_data) };
100
101 int sdgetdisklabel __P((struct sd_data *));
102 int sd_get_parms __P((struct sd_data *, int));
103
104 /*
105 * The routine called by the low level scsi routine when it discovers
106 * a device suitable for this driver.
107 */
108 void
109 sdattach(parent, self, aux)
110 struct device *parent, *self;
111 void *aux;
112 {
113 struct sd_data *sd;
114 struct disk_parms *dp;
115 struct scsi_link *sc_link = aux;
116
117 SC_DEBUG(sc_link, SDEV_DB2, ("sdattach: "));
118
119 dp = &sd->params;
120 /*
121 * Store information needed to contact our base driver
122 */
123 sd->sc_link = sc_link;
124 sc_link->device = &sd_switch;
125 sc_link->dev_unit = self->dv_unit;
126
127 if (sd->sc_link->adapter->adapter_info) {
128 sd->ad_info = ((*(sd->sc_link->adapter->adapter_info)) (sc_link->adapter_softc));
129 sd->cmdscount = sd->ad_info & AD_INF_MAX_CMDS;
130 if (sd->cmdscount > SDOUTSTANDING) {
131 sd->cmdscount = SDOUTSTANDING;
132 }
133 } else {
134 sd->ad_info = 1;
135 sd->cmdscount = 1;
136 }
137 sc_link->opennings = sd->cmdscount;
138 /*
139 * Use the subdriver to request information regarding
140 * the drive. We cannot use interrupts yet, so the
141 * request must specify this.
142 */
143 sd_get_parms(sd, SCSI_NOSLEEP | SCSI_NOMASK);
144 printf("%s: %dMB (%d total sec), %d cyl, %d head, %d sec, %d bytes/sec\n",
145 self->dv_xname, dp->disksize / ((1024L * 1024L) / dp->secsiz),
146 dp->disksize, dp->cyls, dp->heads, dp->sectors, dp->secsiz);
147 sd->flags |= SDINIT;
148 }
149
150 /*
151 * open the device. Make sure the partition info is a up-to-date as can be.
152 */
153 int
154 sdopen(dev)
155 dev_t dev;
156 {
157 int errcode = 0;
158 int unit, part;
159 struct sd_data *sd;
160 struct scsi_link *sc_link;
161
162 unit = SDUNIT(dev);
163 part = SDPART(dev);
164
165 if (unit >= sdcd.cd_ndevs)
166 return ENXIO;
167 sd = sdcd.cd_devs[unit];
168 /*
169 * Make sure the disk has been initialised
170 * At some point in the future, get the scsi driver
171 * to look for a new device if we are not initted
172 */
173 if (!sd || !(sd->flags & SDINIT))
174 return ENXIO;
175
176 sc_link = sd->sc_link;
177
178 SC_DEBUG(sc_link, SDEV_DB1,
179 ("sdopen: dev=0x%x (unit %d (of %d),partition %d)\n"
180 ,dev, unit, sdcd.cd_ndevs, part));
181
182 /*
183 * "unit attention" errors should occur here if the
184 * drive has been restarted or the pack changed.
185 * just ingnore the result, it's a decoy instruction
186 * The error code will act on the error though
187 * and invalidate any media information we had.
188 */
189 scsi_test_unit_ready(sc_link, 0);
190
191 /*
192 * If it's been invalidated, then forget the label
193 */
194 sc_link->flags |= SDEV_OPEN; /* unit attn becomes an err now */
195 if (!(sc_link->flags & SDEV_MEDIA_LOADED)) {
196 sd->flags &= ~SDHAVELABEL;
197
198 /*
199 * If somebody still has it open, then forbid re-entry.
200 */
201 if (sd->openparts) {
202 errcode = ENXIO;
203 goto bad;
204 }
205 }
206
207 /*
208 * In case it is a funny one, tell it to start
209 * not needed for most hard drives (ignore failure)
210 */
211 scsi_start_unit(sc_link, SCSI_ERR_OK | SCSI_SILENT);
212
213 /*
214 * Check that it is still responding and ok.
215 */
216 if (scsi_test_unit_ready(sc_link, 0)) {
217 SC_DEBUG(sc_link, SDEV_DB3, ("device not reponding\n"));
218 errcode = ENXIO;
219 goto bad;
220 }
221 SC_DEBUG(sc_link, SDEV_DB3, ("device ok\n"));
222
223 /*
224 * Load the physical device parameters
225 */
226 sd_get_parms(sd, 0); /* sets SDEV_MEDIA_LOADED */
227 if (sd->params.secsiz != SECSIZE) { /* XXX One day... */
228 printf("sd%d: Can't deal with %d bytes logical blocks\n",
229 unit, sd->params.secsiz);
230 Debugger();
231 errcode = ENXIO;
232 goto bad;
233 }
234 SC_DEBUG(sc_link, SDEV_DB3, ("Params loaded "));
235
236 /* Lock the pack in. */
237 scsi_prevent(sc_link, PR_PREVENT, SCSI_ERR_OK | SCSI_SILENT);
238
239 /*
240 * Load the partition info if not already loaded.
241 */
242 if ((errcode = sdgetdisklabel(sd)) && (part != RAW_PART))
243 goto bad;
244 SC_DEBUG(sc_link, SDEV_DB3, ("Disklabel loaded "));
245
246 /*
247 * Check the partition is legal
248 */
249 if (part >= MAXPARTITIONS) {
250 errcode = ENXIO;
251 goto bad;
252 }
253 SC_DEBUG(sc_link, SDEV_DB3, ("partition ok"));
254
255 /*
256 * Check that the partition exists
257 */
258 if ((sd->sc_dk.dk_label.d_partitions[part].p_size == 0)
259 && (part != RAW_PART)) {
260 errcode = ENXIO;
261 goto bad;
262 }
263 sd->partflags[part] |= SDOPEN;
264 sd->openparts |= (1 << part);
265 SC_DEBUG(sc_link, SDEV_DB3, ("open\n"));
266 return 0;
267
268 bad:
269 if (!(sd->openparts)) {
270 scsi_prevent(sc_link, PR_ALLOW, SCSI_ERR_OK | SCSI_SILENT);
271 sc_link->flags &= ~SDEV_OPEN;
272 }
273 return errcode;
274 }
275
276 /*
277 * close the device.. only called if we are the LAST occurence of an open
278 * device. Convenient now but usually a pain.
279 */
280 int
281 sdclose(dev)
282 dev_t dev;
283 {
284 int unit, part;
285 struct sd_data *sd;
286
287 unit = SDUNIT(dev);
288 part = SDPART(dev);
289 sd = sdcd.cd_devs[unit];
290 sd->partflags[part] &= ~SDOPEN;
291 sd->openparts &= ~(1 << part);
292 if (!(sd->openparts)) {
293 scsi_prevent(sd->sc_link, PR_ALLOW, SCSI_SILENT | SCSI_ERR_OK);
294 sd->sc_link->flags &= ~SDEV_OPEN;
295 }
296 return 0;
297 }
298
299 /*
300 * trim the size of the transfer if needed, called by physio
301 * basically the smaller of our max and the scsi driver's
302 * minphys (note we have no max)
303 *
304 * Trim buffer length if buffer-size is bigger than page size
305 */
306 void
307 sdminphys(bp)
308 struct buf *bp;
309 {
310 register struct sd_data *sd = sdcd.cd_devs[SDUNIT(bp->b_dev)];
311
312 (sd->sc_link->adapter->scsi_minphys) (bp);
313 }
314
315 /*
316 * Actually translate the requested transfer into one the physical driver
317 * can understand. The transfer is described by a buf and will include
318 * only one physical transfer.
319 */
320 void
321 sdstrategy(bp)
322 struct buf *bp;
323 {
324 struct buf *dp;
325 int opri;
326 struct sd_data *sd;
327 int unit;
328
329 unit = SDUNIT(bp->b_dev);
330 sd = sdcd.cd_devs[unit];
331 SC_DEBUG(sd->sc_link, SDEV_DB2, ("sdstrategy "));
332 SC_DEBUG(sd->sc_link, SDEV_DB1,
333 (" %d bytes @ blk%d\n", bp->b_bcount, bp->b_blkno));
334 sdminphys(bp);
335 /*
336 * If the device has been made invalid, error out
337 */
338 if (!(sd->sc_link->flags & SDEV_MEDIA_LOADED)) {
339 sd->flags &= ~SDHAVELABEL;
340 bp->b_error = EIO;
341 goto bad;
342 }
343 /*
344 * "soft" write protect check
345 */
346 if ((sd->flags & SDWRITEPROT) && (bp->b_flags & B_READ) == 0) {
347 bp->b_error = EROFS;
348 goto bad;
349 }
350 /*
351 * If it's a null transfer, return immediatly
352 */
353 if (bp->b_bcount == 0) {
354 goto done;
355 }
356 /*
357 * Decide which unit and partition we are talking about
358 * only raw is ok if no label
359 */
360 if (SDPART(bp->b_dev) != RAW_PART) {
361 if (!(sd->flags & SDHAVELABEL)) {
362 bp->b_error = EIO;
363 goto bad;
364 }
365 /*
366 * do bounds checking, adjust transfer. if error, process.
367 * if end of partition, just return
368 */
369 if (bounds_check_with_label(bp, &sd->sc_dk.dk_label, sd->wlabel) <= 0)
370 goto done;
371 /* otherwise, process transfer request */
372 }
373 opri = splbio();
374 dp = &sd->buf_queue;
375
376 /*
377 * Place it in the queue of disk activities for this disk
378 */
379 disksort(dp, bp);
380
381 /*
382 * Tell the device to get going on the transfer if it's
383 * not doing anything, otherwise just wait for completion
384 */
385 sdstart(unit);
386
387 splx(opri);
388 bad:
389 bp->b_flags |= B_ERROR;
390 done:
391
392 /*
393 * Correctly set the buf to indicate a completed xfer
394 */
395 bp->b_resid = bp->b_bcount;
396 biodone(bp);
397 }
398
399 /*
400 * sdstart looks to see if there is a buf waiting for the device
401 * and that the device is not already busy. If both are true,
402 * It dequeues the buf and creates a scsi command to perform the
403 * transfer in the buf. The transfer request will call scsi_done
404 * on completion, which will in turn call this routine again
405 * so that the next queued transfer is performed.
406 * The bufs are queued by the strategy routine (sdstrategy)
407 *
408 * This routine is also called after other non-queued requests
409 * have been made of the scsi driver, to ensure that the queue
410 * continues to be drained.
411 *
412 * must be called at the correct (highish) spl level
413 * sdstart() is called at splbio from sdstrategy and scsi_done
414 */
415 void
416 sdstart(unit)
417 int unit;
418 {
419 register struct sd_data *sd = sdcd.cd_devs[unit];
420 register struct scsi_link *sc_link = sd->sc_link;
421 struct buf *bp = 0;
422 struct buf *dp;
423 struct scsi_rw_big cmd;
424 int blkno, nblk;
425 struct partition *p;
426
427 SC_DEBUG(sc_link, SDEV_DB2, ("sdstart "));
428 /*
429 * Check if the device has room for another command
430 */
431 while (sc_link->opennings) {
432
433 /*
434 * there is excess capacity, but a special waits
435 * It'll need the adapter as soon as we clear out of the
436 * way and let it run (user level wait).
437 */
438 if (sc_link->flags & SDEV_WAITING) {
439 return;
440 }
441 /*
442 * See if there is a buf with work for us to do..
443 */
444 dp = &sd->buf_queue;
445 if ((bp = dp->b_actf) == NULL) { /* yes, an assign */
446 return;
447 }
448 dp->b_actf = bp->av_forw;
449
450 /*
451 * If the device has become invalid, abort all the
452 * reads and writes until all files have been closed and
453 * re-openned
454 */
455 if (!(sc_link->flags & SDEV_MEDIA_LOADED)) {
456 sd->flags &= ~SDHAVELABEL;
457 goto bad;
458 }
459 /*
460 * We have a buf, now we know we are going to go through
461 * With this thing..
462 *
463 * First, translate the block to absolute
464 */
465 p = sd->sc_dk.dk_label.d_partitions + SDPART(bp->b_dev);
466 blkno = bp->b_blkno + p->p_offset;
467 nblk = (bp->b_bcount + 511) >> 9;
468
469 /*
470 * Fill out the scsi command
471 */
472 bzero(&cmd, sizeof(cmd));
473 cmd.op_code = (bp->b_flags & B_READ)
474 ? READ_BIG : WRITE_BIG;
475 cmd.addr_3 = (blkno & 0xff000000) >> 24;
476 cmd.addr_2 = (blkno & 0xff0000) >> 16;
477 cmd.addr_1 = (blkno & 0xff00) >> 8;
478 cmd.addr_0 = blkno & 0xff;
479 cmd.length2 = (nblk & 0xff00) >> 8;
480 cmd.length1 = (nblk & 0xff);
481 /*
482 * Call the routine that chats with the adapter.
483 * Note: we cannot sleep as we may be an interrupt
484 */
485 if (scsi_scsi_cmd(sc_link,
486 (struct scsi_generic *) &cmd,
487 sizeof(cmd),
488 (u_char *) bp->b_un.b_addr,
489 bp->b_bcount,
490 SD_RETRIES,
491 10000,
492 bp,
493 SCSI_NOSLEEP | ((bp->b_flags & B_READ) ?
494 SCSI_DATA_IN : SCSI_DATA_OUT))
495 == SUCCESSFULLY_QUEUED) {
496 } else {
497 bad:
498 printf("sd%d: oops not queued", unit);
499 bp->b_error = EIO;
500 bp->b_flags |= B_ERROR;
501 biodone(bp);
502 }
503 }
504 }
505
506 /*
507 * Perform special action on behalf of the user
508 * Knows about the internals of this device
509 */
510 int
511 sdioctl(dev_t dev, int cmd, caddr_t addr, int flag)
512 {
513 /* struct sd_cmd_buf *args; */
514 int error = 0;
515 unsigned char unit, part;
516 register struct sd_data *sd;
517
518 /*
519 * Find the device that the user is talking about
520 */
521 unit = SDUNIT(dev);
522 part = SDPART(dev);
523 sd = sdcd.cd_devs[unit];
524 SC_DEBUG(sd->sc_link, SDEV_DB1, ("sdioctl (0x%x)", cmd));
525
526 /*
527 * If the device is not valid.. abandon ship
528 */
529 if (!(sd->sc_link->flags & SDEV_MEDIA_LOADED))
530 return EIO;
531 switch (cmd) {
532
533 case DIOCSBAD:
534 error = EINVAL;
535 break;
536
537 case DIOCGDINFO:
538 *(struct disklabel *) addr = sd->sc_dk.dk_label;
539 break;
540
541 case DIOCGPART:
542 ((struct partinfo *) addr)->disklab = &sd->sc_dk.dk_label;
543 ((struct partinfo *) addr)->part =
544 &sd->sc_dk.dk_label.d_partitions[SDPART(dev)];
545 break;
546
547 case DIOCSDINFO:
548 if ((flag & FWRITE) == 0)
549 error = EBADF;
550 else
551 error = setdisklabel(&sd->sc_dk.dk_label,
552 (struct disklabel *)addr,
553 /*(sd->flags & DKFL_BSDLABEL) ? sd->openparts : */ 0,
554 &sd->sc_dk.dk_cpulabel);
555 if (error == 0)
556 sd->flags |= SDHAVELABEL;
557 break;
558
559 case DIOCWLABEL:
560 sd->flags &= ~SDWRITEPROT;
561 if ((flag & FWRITE) == 0)
562 error = EBADF;
563 else
564 sd->wlabel = *(boolean *) addr;
565 break;
566
567 case DIOCWDINFO:
568 sd->flags &= ~SDWRITEPROT;
569 if ((flag & FWRITE) == 0)
570 error = EBADF;
571 else {
572 error = setdisklabel(&sd->sc_dk.dk_label,
573 (struct disklabel *)addr,
574 /*(sd->flags & SDHAVELABEL) ? sd->openparts : */ 0,
575 &sd->sc_dk.dk_cpulabel);
576 if (!error) {
577 boolean wlab;
578
579 /* ok - write will succeed */
580 sd->flags |= SDHAVELABEL;
581
582 /* simulate opening partition 0 so write succeeds */
583 sd->openparts |= (1 << 0); /* XXX */
584 wlab = sd->wlabel;
585 sd->wlabel = 1;
586 error = writedisklabel(dev, sdstrategy,
587 &sd->sc_dk.dk_label,
588 &sd->sc_dk.dk_cpulabel);
589 sd->wlabel = wlab;
590 }
591 }
592 break;
593
594 default:
595 if (part == RAW_PART)
596 error = scsi_do_ioctl(sd->sc_link, cmd, addr, flag);
597 else
598 error = ENOTTY;
599 break;
600 }
601 return error;
602 }
603
604 /*
605 * Load the label information on the named device
606 */
607 int
608 sdgetdisklabel(sd)
609 struct sd_data *sd;
610 {
611 char *errstring;
612
613 /*
614 * If the inflo is already loaded, use it
615 */
616 if (sd->flags & SDHAVELABEL)
617 return 0;
618
619 bzero(&sd->sc_dk.dk_label, sizeof(struct disklabel));
620 /*
621 * make partition 3 the whole disk in case of failure then get pdinfo
622 * for historical reasons, make part a same as raw part
623 */
624 sd->sc_dk.dk_label.d_partitions[0].p_offset = 0;
625 sd->sc_dk.dk_label.d_partitions[0].p_size = sd->params.disksize;
626 sd->sc_dk.dk_label.d_partitions[RAW_PART].p_offset = 0;
627 sd->sc_dk.dk_label.d_partitions[RAW_PART].p_size = sd->params.disksize;
628 sd->sc_dk.dk_label.d_npartitions = MAXPARTITIONS;
629 sd->sc_dk.dk_label.d_secsize = SECSIZE; /* as long as it's not 0 */
630 sd->sc_dk.dk_label.d_ntracks = sd->params.heads;
631 sd->sc_dk.dk_label.d_nsectors = sd->params.sectors;
632 sd->sc_dk.dk_label.d_ncylinders = sd->params.cyls;
633 sd->sc_dk.dk_label.d_secpercyl = sd->params.heads * sd->params.sectors;
634 if (sd->sc_dk.dk_label.d_secpercyl == 0) {
635 sd->sc_dk.dk_label.d_secpercyl = 100;
636 /* as long as it's not 0 - readdisklabel divides by it (?) */
637 }
638 /*
639 * Call the generic disklabel extraction routine
640 */
641 if (errstring = readdisklabel(MAKESDDEV(0, sd->sc_dk.dk_dev.dv_unit,
642 RAW_PART), sdstrategy,
643 &sd->sc_dk.dk_label,
644 &sd->sc_dk.dk_cpulabel)) {
645 printf("%s: %s\n", sd->sc_dk.dk_dev.dv_xname, errstring);
646 return ENXIO;
647 }
648 sd->flags |= SDHAVELABEL; /* WE HAVE IT ALL NOW */
649 return 0;
650 }
651
652 /*
653 * Find out from the device what it's capacity is
654 */
655 u_int32
656 sd_size(sd, flags)
657 struct sd_data *sd;
658 int flags;
659 {
660 struct scsi_read_cap_data rdcap;
661 struct scsi_read_capacity scsi_cmd;
662 u_int32 size;
663
664 /*
665 * make up a scsi command and ask the scsi driver to do
666 * it for you.
667 */
668 bzero(&scsi_cmd, sizeof(scsi_cmd));
669 scsi_cmd.op_code = READ_CAPACITY;
670
671 /*
672 * If the command works, interpret the result as a 4 byte
673 * number of blocks
674 */
675 if (scsi_scsi_cmd(sd->sc_link, (struct scsi_generic *) &scsi_cmd,
676 sizeof(scsi_cmd), (u_char *) &rdcap, sizeof(rdcap),
677 SD_RETRIES, 2000, NULL, flags | SCSI_DATA_IN) != 0) {
678 printf("%s: could not get size\n", sd->sc_dk.dk_dev.dv_xname);
679 return 0;
680 } else {
681 size = rdcap.addr_0 + 1;
682 size += rdcap.addr_1 << 8;
683 size += rdcap.addr_2 << 16;
684 size += rdcap.addr_3 << 24;
685 }
686 return size;
687 }
688
689 /*
690 * Tell the device to map out a defective block
691 */
692 int
693 sd_reassign_blocks(sd, block)
694 struct sd_data *sd;
695 int block;
696 {
697 struct scsi_reassign_blocks scsi_cmd;
698 struct scsi_reassign_blocks_data rbdata;
699
700 bzero(&scsi_cmd, sizeof(scsi_cmd));
701 bzero(&rbdata, sizeof(rbdata));
702 scsi_cmd.op_code = REASSIGN_BLOCKS;
703
704 rbdata.length_msb = 0;
705 rbdata.length_lsb = sizeof(rbdata.defect_descriptor[0]);
706 rbdata.defect_descriptor[0].dlbaddr_3 = ((block >> 24) & 0xff);
707 rbdata.defect_descriptor[0].dlbaddr_2 = ((block >> 16) & 0xff);
708 rbdata.defect_descriptor[0].dlbaddr_1 = ((block >> 8) & 0xff);
709 rbdata.defect_descriptor[0].dlbaddr_0 = ((block) & 0xff);
710
711 return scsi_scsi_cmd(sd->sc_link, (struct scsi_generic *) &scsi_cmd,
712 sizeof(scsi_cmd), (u_char *) &rbdata,
713 sizeof(rbdata), SD_RETRIES, 5000, NULL,
714 SCSI_DATA_OUT);
715 }
716
717 #define b2tol(a) (((unsigned)(a##_1) << 8) + (unsigned)a##_0 )
718
719 /*
720 * Get the scsi driver to send a full inquiry to the
721 * device and use the results to fill out the disk
722 * parameter structure.
723 */
724 int
725 sd_get_parms(sd, flags)
726 struct sd_data *sd;
727 int flags;
728 {
729 struct disk_parms *disk_parms = &sd->params;
730 struct scsi_mode_sense scsi_cmd;
731 struct scsi_mode_sense_data {
732 struct scsi_mode_header header;
733 struct blk_desc blk_desc;
734 union disk_pages pages;
735 } scsi_sense;
736 u_int32 sectors;
737
738 /*
739 * First check if we have it all loaded
740 */
741 if (sd->flags & SDEV_MEDIA_LOADED)
742 return 0;
743
744 /*
745 * do a "mode sense page 4"
746 */
747 bzero(&scsi_cmd, sizeof(scsi_cmd));
748 scsi_cmd.op_code = MODE_SENSE;
749 scsi_cmd.page = 4;
750 scsi_cmd.length = 0x20;
751 /*
752 * If the command worked, use the results to fill out
753 * the parameter structure
754 */
755 if (scsi_scsi_cmd(sd->sc_link, (struct scsi_generic *) &scsi_cmd,
756 sizeof(scsi_cmd), (u_char *) &scsi_sense,
757 sizeof(scsi_sense), SD_RETRIES, 2000, NULL,
758 flags | SCSI_DATA_IN) != 0) {
759
760 printf("%s: could not mode sense", sd->sc_dk.dk_dev.dv_xname);
761 printf(" (4); using ficticious geometry\n");
762 /*
763 * use adaptec standard ficticious geometry
764 * this depends on which controller (e.g. 1542C is
765 * different. but we have to put SOMETHING here..)
766 */
767 sectors = sd_size(sd, flags);
768 disk_parms->heads = 64;
769 disk_parms->sectors = 32;
770 disk_parms->cyls = sectors / (64 * 32);
771 disk_parms->secsiz = SECSIZE;
772 disk_parms->disksize = sectors;
773 } else {
774
775 SC_DEBUG(sd->sc_link, SDEV_DB3,
776 ("%d cyls, %d heads, %d precomp, %d red_write, %d land_zone\n",
777 _3btol(&scsi_sense.pages.rigid_geometry.ncyl_2),
778 scsi_sense.pages.rigid_geometry.nheads,
779 b2tol(scsi_sense.pages.rigid_geometry.st_cyl_wp),
780 b2tol(scsi_sense.pages.rigid_geometry.st_cyl_rwc),
781 b2tol(scsi_sense.pages.rigid_geometry.land_zone)));
782
783 /*
784 * KLUDGE!!(for zone recorded disks)
785 * give a number of sectors so that sec * trks * cyls
786 * is <= disk_size
787 * can lead to wasted space! THINK ABOUT THIS !
788 */
789 disk_parms->heads = scsi_sense.pages.rigid_geometry.nheads;
790 disk_parms->cyls = _3btol(&scsi_sense.pages.rigid_geometry.ncyl_2);
791 disk_parms->secsiz = _3btol(scsi_sense.blk_desc.blklen);
792
793 sectors = sd_size(sd, flags);
794 disk_parms->disksize = sectors;
795 sectors /= (disk_parms->heads * disk_parms->cyls);
796 disk_parms->sectors = sectors; /* dubious on SCSI *//*XXX */
797 }
798 sd->sc_link->flags |= SDEV_MEDIA_LOADED;
799 return 0;
800 }
801
802 int
803 sdsize(dev_t dev)
804 {
805 int unit = SDUNIT(dev), part = SDPART(dev), val;
806 struct sd_data *sd;
807
808 if (unit >= sdcd.cd_ndevs)
809 return -1;
810 sd = sdcd.cd_devs[unit];
811 if (!sd || !(sd->flags & SDINIT))
812 return -1;
813
814 if ((sd->flags & SDHAVELABEL) == 0) {
815 val = sdopen(MAKESDDEV(major(dev), unit, RAW_PART), FREAD, S_IFBLK, 0);
816 if (val != 0)
817 return -1;
818 }
819 if (sd->flags & SDWRITEPROT)
820 return -1;
821
822 return (int)sd->sc_dk.dk_label.d_partitions[part].p_size;
823 }
824
825
826 #define SCSIDUMP 1
827 #undef SCSIDUMP
828 #define NOT_TRUSTED 1
829
830 #ifdef SCSIDUMP
831 #include <vm/vm.h>
832
833 static struct scsi_xfer sx;
834 #define MAXTRANSFER 8 /* 1 page at a time */
835
836 /*
837 * dump all of physical memory into the partition specified, starting
838 * at offset 'dumplo' into the partition.
839 */
840 int
841 sddump(dev_t dev)
842 { /* dump core after a system crash */
843 register struct sd_data *sd; /* disk unit to do the IO */
844 int32 num; /* number of sectors to write */
845 u_int32 unit, part;
846 int32 blkoff, blknum, blkcnt = MAXTRANSFER;
847 int32 nblocks;
848 char *addr;
849 struct scsi_rw_big cmd;
850 extern int Maxmem;
851 static int sddoingadump = 0;
852 #define MAPTO CADDR1
853 extern caddr_t MAPTO; /* map the page we are about to write, here */
854 struct scsi_xfer *xs = &sx;
855 int retval;
856 int c;
857
858 addr = (char *) 0; /* starting address */
859
860 /* toss any characters present prior to dump */
861 while ((c = sgetc(1)) && (c != 0x100)); /*syscons and pccons differ */
862
863 /* size of memory to dump */
864 num = Maxmem;
865 unit = SDUNIT(dev); /* eventually support floppies? */
866 part = SDPART(dev); /* file system */
867 /* check for acceptable drive number */
868 if (unit >= sdcd.cd_ndevs)
869 return ENXIO;
870
871 sd = sd_data[unit];
872 if (!sd)
873 return ENXIO;
874 /* was it ever initialized etc. ? */
875 if (!(sd->flags & SDINIT))
876 return ENXIO;
877 if (sd->sc_link->flags & SDEV_MEDIA_LOADED != SDEV_MEDIA_LOADED)
878 return ENXIO;
879 if (sd->flags & SDWRITEPROT)
880 return ENXIO;
881
882 /* Convert to disk sectors */
883 num = (u_int32) num * NBPG / sd->sc_dk.dk_label.d_secsize;
884
885 /* check if controller active */
886 if (sddoingadump)
887 return EFAULT;
888
889 nblocks = sd->sc_dk.dk_label.d_partitions[part].p_size;
890 blkoff = sd->sc_dk.dk_label.d_partitions[part].p_offset;
891
892 /* check transfer bounds against partition size */
893 if ((dumplo < 0) || ((dumplo + num) > nblocks))
894 return EINVAL;
895
896 sddoingadump = 1;
897
898 blknum = dumplo + blkoff;
899 /* blkcnt = initialise_me; */
900 while (num > 0) {
901 pmap_enter(kernel_pmap,
902 MAPTO,
903 trunc_page(addr),
904 VM_PROT_READ,
905 TRUE);
906 #ifndef NOT_TRUSTED
907 /*
908 * Fill out the scsi command
909 */
910 bzero(&cmd, sizeof(cmd));
911 cmd.op_code = WRITE_BIG;
912 cmd.addr_3 = (blknum & 0xff000000) >> 24;
913 cmd.addr_2 = (blknum & 0xff0000) >> 16;
914 cmd.addr_1 = (blknum & 0xff00) >> 8;
915 cmd.addr_0 = blknum & 0xff;
916 cmd.length2 = (blkcnt & 0xff00) >> 8;
917 cmd.length1 = (blkcnt & 0xff);
918 /*
919 * Fill out the scsi_xfer structure
920 * Note: we cannot sleep as we may be an interrupt
921 * don't use scsi_scsi_cmd() as it may want
922 * to wait for an xs.
923 */
924 bzero(xs, sizeof(sx));
925 xs->flags |= SCSI_NOMASK | SCSI_NOSLEEP | INUSE;
926 xs->sc_link = sd->sc_link;
927 xs->retries = SD_RETRIES;
928 xs->timeout = 10000; /* 10000 millisecs for a disk ! */
929 xs->cmd = (struct scsi_generic *) &cmd;
930 xs->cmdlen = sizeof(cmd);
931 xs->resid = blkcnt * 512;
932 xs->error = XS_NOERROR;
933 xs->bp = 0;
934 xs->data = (u_char *) MAPTO;
935 xs->datalen = blkcnt * 512;
936
937 /*
938 * Pass all this info to the scsi driver.
939 */
940 retval = (*(sd->sc_link->adapter->scsi_cmd)) (xs);
941 switch (retval) {
942 case SUCCESSFULLY_QUEUED:
943 case HAD_ERROR:
944 return ENXIO; /* we said not to sleep! */
945 case COMPLETE:
946 break;
947 default:
948 return ENXIO; /* we said not to sleep! */
949 }
950 #else /* NOT_TRUSTED */
951 /* lets just talk about this first... */
952 printf("sd%d: dump addr 0x%x, blk %d\n", unit, addr, blknum);
953 #endif /* NOT_TRUSTED */
954
955 if ((unsigned) addr % (1024 * 1024) == 0)
956 printf("%d ", num / 2048);
957 /* update block count */
958 num -= blkcnt;
959 blknum += blkcnt;
960 (int) addr += 512 * blkcnt;
961
962 /* operator aborting dump? */
963 if ((c = sgetc(1)) && (c != 0x100))
964 return EINTR;
965 }
966 return 0;
967 }
968 #else /* SCSIDUMP */
969 int
970 sddump()
971 {
972 printf("\nsddump() -- not implemented\n");
973 DELAY(60000000); /* 60 seconds */
974 return -1;
975 }
976 #endif /* SCSIDUMP */
977