FreeBSD/Linux Kernel Cross Reference
sys/cam/scsi/scsi_da.c
1 /*-
2 * Implementation of SCSI Direct Access Peripheral driver for CAM.
3 *
4 * Copyright (c) 1997 Justin T. Gibbs.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions, and the following disclaimer,
12 * without modification, immediately at the beginning of the file.
13 * 2. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD: releng/6.3/sys/cam/scsi/scsi_da.c 169996 2007-05-25 20:14:02Z mjacob $");
31
32 #include <sys/param.h>
33
34 #ifdef _KERNEL
35 #include <sys/systm.h>
36 #include <sys/kernel.h>
37 #include <sys/bio.h>
38 #include <sys/sysctl.h>
39 #include <sys/taskqueue.h>
40 #endif /* _KERNEL */
41
42 #include <sys/devicestat.h>
43 #include <sys/conf.h>
44 #include <sys/eventhandler.h>
45 #include <sys/malloc.h>
46 #include <sys/cons.h>
47
48 #include <machine/md_var.h>
49
50 #include <vm/vm.h>
51 #include <vm/pmap.h>
52
53 #include <geom/geom_disk.h>
54
55 #ifndef _KERNEL
56 #include <stdio.h>
57 #include <string.h>
58 #endif /* _KERNEL */
59
60 #include <cam/cam.h>
61 #include <cam/cam_ccb.h>
62 #include <cam/cam_periph.h>
63 #include <cam/cam_xpt_periph.h>
64
65 #include <cam/scsi/scsi_message.h>
66
67 #ifndef _KERNEL
68 #include <cam/scsi/scsi_da.h>
69 #endif /* !_KERNEL */
70
71 #ifdef _KERNEL
72 typedef enum {
73 DA_STATE_PROBE,
74 DA_STATE_PROBE2,
75 DA_STATE_NORMAL
76 } da_state;
77
78 typedef enum {
79 DA_FLAG_PACK_INVALID = 0x001,
80 DA_FLAG_NEW_PACK = 0x002,
81 DA_FLAG_PACK_LOCKED = 0x004,
82 DA_FLAG_PACK_REMOVABLE = 0x008,
83 DA_FLAG_TAGGED_QUEUING = 0x010,
84 DA_FLAG_NEED_OTAG = 0x020,
85 DA_FLAG_WENT_IDLE = 0x040,
86 DA_FLAG_RETRY_UA = 0x080,
87 DA_FLAG_OPEN = 0x100,
88 DA_FLAG_SCTX_INIT = 0x200
89 } da_flags;
90
91 typedef enum {
92 DA_Q_NONE = 0x00,
93 DA_Q_NO_SYNC_CACHE = 0x01,
94 DA_Q_NO_6_BYTE = 0x02,
95 DA_Q_NO_PREVENT = 0x04
96 } da_quirks;
97
98 typedef enum {
99 DA_CCB_PROBE = 0x01,
100 DA_CCB_PROBE2 = 0x02,
101 DA_CCB_BUFFER_IO = 0x03,
102 DA_CCB_WAITING = 0x04,
103 DA_CCB_DUMP = 0x05,
104 DA_CCB_TYPE_MASK = 0x0F,
105 DA_CCB_RETRY_UA = 0x10
106 } da_ccb_state;
107
108 /* Offsets into our private area for storing information */
109 #define ccb_state ppriv_field0
110 #define ccb_bp ppriv_ptr1
111
112 struct disk_params {
113 u_int8_t heads;
114 u_int32_t cylinders;
115 u_int8_t secs_per_track;
116 u_int32_t secsize; /* Number of bytes/sector */
117 u_int64_t sectors; /* total number sectors */
118 };
119
120 struct da_softc {
121 struct bio_queue_head bio_queue;
122 SLIST_ENTRY(da_softc) links;
123 LIST_HEAD(, ccb_hdr) pending_ccbs;
124 da_state state;
125 da_flags flags;
126 da_quirks quirks;
127 int minimum_cmd_size;
128 int ordered_tag_count;
129 int outstanding_cmds;
130 struct disk_params params;
131 struct disk *disk;
132 union ccb saved_ccb;
133 struct task sysctl_task;
134 struct sysctl_ctx_list sysctl_ctx;
135 struct sysctl_oid *sysctl_tree;
136 };
137
138 struct da_quirk_entry {
139 struct scsi_inquiry_pattern inq_pat;
140 da_quirks quirks;
141 };
142
143 static const char quantum[] = "QUANTUM";
144 static const char microp[] = "MICROP";
145
146 static struct da_quirk_entry da_quirk_table[] =
147 {
148 /* SPI, FC devices */
149 {
150 /*
151 * Fujitsu M2513A MO drives.
152 * Tested devices: M2513A2 firmware versions 1200 & 1300.
153 * (dip switch selects whether T_DIRECT or T_OPTICAL device)
154 * Reported by: W.Scholten <whs@xs4all.nl>
155 */
156 {T_DIRECT, SIP_MEDIA_REMOVABLE, "FUJITSU", "M2513A", "*"},
157 /*quirks*/ DA_Q_NO_SYNC_CACHE
158 },
159 {
160 /* See above. */
161 {T_OPTICAL, SIP_MEDIA_REMOVABLE, "FUJITSU", "M2513A", "*"},
162 /*quirks*/ DA_Q_NO_SYNC_CACHE
163 },
164 {
165 /*
166 * This particular Fujitsu drive doesn't like the
167 * synchronize cache command.
168 * Reported by: Tom Jackson <toj@gorilla.net>
169 */
170 {T_DIRECT, SIP_MEDIA_FIXED, "FUJITSU", "M2954*", "*"},
171 /*quirks*/ DA_Q_NO_SYNC_CACHE
172
173 },
174 {
175 /*
176 * This drive doesn't like the synchronize cache command
177 * either. Reported by: Matthew Jacob <mjacob@feral.com>
178 * in NetBSD PR kern/6027, August 24, 1998.
179 */
180 {T_DIRECT, SIP_MEDIA_FIXED, microp, "2217*", "*"},
181 /*quirks*/ DA_Q_NO_SYNC_CACHE
182 },
183 {
184 /*
185 * This drive doesn't like the synchronize cache command
186 * either. Reported by: Hellmuth Michaelis (hm@kts.org)
187 * (PR 8882).
188 */
189 {T_DIRECT, SIP_MEDIA_FIXED, microp, "2112*", "*"},
190 /*quirks*/ DA_Q_NO_SYNC_CACHE
191 },
192 {
193 /*
194 * Doesn't like the synchronize cache command.
195 * Reported by: Blaz Zupan <blaz@gold.amis.net>
196 */
197 {T_DIRECT, SIP_MEDIA_FIXED, "NEC", "D3847*", "*"},
198 /*quirks*/ DA_Q_NO_SYNC_CACHE
199 },
200 {
201 /*
202 * Doesn't like the synchronize cache command.
203 * Reported by: Blaz Zupan <blaz@gold.amis.net>
204 */
205 {T_DIRECT, SIP_MEDIA_FIXED, quantum, "MAVERICK 540S", "*"},
206 /*quirks*/ DA_Q_NO_SYNC_CACHE
207 },
208 {
209 /*
210 * Doesn't like the synchronize cache command.
211 */
212 {T_DIRECT, SIP_MEDIA_FIXED, quantum, "LPS525S", "*"},
213 /*quirks*/ DA_Q_NO_SYNC_CACHE
214 },
215 {
216 /*
217 * Doesn't like the synchronize cache command.
218 * Reported by: walter@pelissero.de
219 */
220 {T_DIRECT, SIP_MEDIA_FIXED, quantum, "LPS540S", "*"},
221 /*quirks*/ DA_Q_NO_SYNC_CACHE
222 },
223 {
224 /*
225 * Doesn't work correctly with 6 byte reads/writes.
226 * Returns illegal request, and points to byte 9 of the
227 * 6-byte CDB.
228 * Reported by: Adam McDougall <bsdx@spawnet.com>
229 */
230 {T_DIRECT, SIP_MEDIA_FIXED, quantum, "VIKING 4*", "*"},
231 /*quirks*/ DA_Q_NO_6_BYTE
232 },
233 {
234 /* See above. */
235 {T_DIRECT, SIP_MEDIA_FIXED, quantum, "VIKING 2*", "*"},
236 /*quirks*/ DA_Q_NO_6_BYTE
237 },
238 {
239 /*
240 * Doesn't like the synchronize cache command.
241 * Reported by: walter@pelissero.de
242 */
243 {T_DIRECT, SIP_MEDIA_FIXED, "CONNER", "CP3500*", "*"},
244 /*quirks*/ DA_Q_NO_SYNC_CACHE
245 },
246 {
247 /*
248 * The CISS RAID controllers do not support SYNC_CACHE
249 */
250 {T_DIRECT, SIP_MEDIA_FIXED, "COMPAQ", "RAID*", "*"},
251 /*quirks*/ DA_Q_NO_SYNC_CACHE
252 },
253 /* USB mass storage devices supported by umass(4) */
254 {
255 /*
256 * EXATELECOM (Sigmatel) i-Bead 100/105 USB Flash MP3 Player
257 * PR: kern/51675
258 */
259 {T_DIRECT, SIP_MEDIA_REMOVABLE, "EXATEL", "i-BEAD10*", "*"},
260 /*quirks*/ DA_Q_NO_SYNC_CACHE
261 },
262 {
263 /*
264 * Power Quotient Int. (PQI) USB flash key
265 * PR: kern/53067
266 */
267 {T_DIRECT, SIP_MEDIA_REMOVABLE, "Generic*", "USB Flash Disk*",
268 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
269 },
270 {
271 /*
272 * Creative Nomad MUVO mp3 player (USB)
273 * PR: kern/53094
274 */
275 {T_DIRECT, SIP_MEDIA_REMOVABLE, "CREATIVE", "NOMAD_MUVO", "*"},
276 /*quirks*/ DA_Q_NO_SYNC_CACHE|DA_Q_NO_PREVENT
277 },
278 {
279 /*
280 * Jungsoft NEXDISK USB flash key
281 * PR: kern/54737
282 */
283 {T_DIRECT, SIP_MEDIA_REMOVABLE, "JUNGSOFT", "NEXDISK*", "*"},
284 /*quirks*/ DA_Q_NO_SYNC_CACHE
285 },
286 {
287 /*
288 * FreeDik USB Mini Data Drive
289 * PR: kern/54786
290 */
291 {T_DIRECT, SIP_MEDIA_REMOVABLE, "FreeDik*", "Mini Data Drive",
292 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
293 },
294 {
295 /*
296 * Sigmatel USB Flash MP3 Player
297 * PR: kern/57046
298 */
299 {T_DIRECT, SIP_MEDIA_REMOVABLE, "SigmaTel", "MSCN", "*"},
300 /*quirks*/ DA_Q_NO_SYNC_CACHE|DA_Q_NO_PREVENT
301 },
302 {
303 /*
304 * Neuros USB Digital Audio Computer
305 * PR: kern/63645
306 */
307 {T_DIRECT, SIP_MEDIA_REMOVABLE, "NEUROS", "dig. audio comp.",
308 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
309 },
310 {
311 /*
312 * SEAGRAND NP-900 MP3 Player
313 * PR: kern/64563
314 */
315 {T_DIRECT, SIP_MEDIA_REMOVABLE, "SEAGRAND", "NP-900*", "*"},
316 /*quirks*/ DA_Q_NO_SYNC_CACHE|DA_Q_NO_PREVENT
317 },
318 {
319 /*
320 * iRiver iFP MP3 player (with UMS Firmware)
321 * PR: kern/54881, i386/63941, kern/66124
322 */
323 {T_DIRECT, SIP_MEDIA_REMOVABLE, "iRiver", "iFP*", "*"},
324 /*quirks*/ DA_Q_NO_SYNC_CACHE
325 },
326 {
327 /*
328 * Frontier Labs NEX IA+ Digital Audio Player, rev 1.10/0.01
329 * PR: kern/70158
330 */
331 {T_DIRECT, SIP_MEDIA_REMOVABLE, "FL" , "Nex*", "*"},
332 /*quirks*/ DA_Q_NO_SYNC_CACHE
333 },
334 {
335 /*
336 * ZICPlay USB MP3 Player with FM
337 * PR: kern/75057
338 */
339 {T_DIRECT, SIP_MEDIA_REMOVABLE, "ACTIONS*" , "USB DISK*", "*"},
340 /*quirks*/ DA_Q_NO_SYNC_CACHE
341 },
342 {
343 /*
344 * TEAC USB floppy mechanisms
345 */
346 {T_DIRECT, SIP_MEDIA_REMOVABLE, "TEAC" , "FD-05*", "*"},
347 /*quirks*/ DA_Q_NO_SYNC_CACHE
348 },
349 {
350 /*
351 * Kingston DataTraveler II+ USB Pen-Drive.
352 * Reported by: Pawel Jakub Dawidek <pjd@FreeBSD.org>
353 */
354 {T_DIRECT, SIP_MEDIA_REMOVABLE, "Kingston" , "DataTraveler II+", "*"},
355 /*quirks*/ DA_Q_NO_SYNC_CACHE
356 },
357 {
358 /*
359 * Motorola E398 Mobile Phone (TransFlash memory card).
360 * Reported by: Wojciech A. Koszek <dunstan@FreeBSD.czest.pl>
361 * PR: usb/89889
362 */
363 {T_DIRECT, SIP_MEDIA_REMOVABLE, "Motorola" , "Motorola Phone",
364 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
365 },
366 {
367 /*
368 * Qware BeatZkey! Pro
369 * PR: usb/79164
370 */
371 {T_DIRECT, SIP_MEDIA_REMOVABLE, "GENERIC", "USB DISK DEVICE",
372 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
373 },
374 {
375 /*
376 * Time DPA20B 1GB MP3 Player
377 * PR: usb/81846
378 */
379 {T_DIRECT, SIP_MEDIA_REMOVABLE, "USB2.0*", "(FS) FLASH DISK*",
380 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
381 },
382 {
383 /*
384 * Samsung USB key 128Mb
385 * PR: usb/90081
386 */
387 {T_DIRECT, SIP_MEDIA_REMOVABLE, "USB-DISK", "FreeDik-FlashUsb",
388 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
389 },
390 {
391 /*
392 * Kingston DataTraveler 2.0 USB Flash memory.
393 * PR: usb/89196
394 */
395 {T_DIRECT, SIP_MEDIA_REMOVABLE, "Kingston", "DataTraveler 2.0",
396 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
397 },
398 {
399 /*
400 * Creative MUVO Slim mp3 player (USB)
401 * PR: usb/86131
402 */
403 {T_DIRECT, SIP_MEDIA_REMOVABLE, "CREATIVE", "MuVo Slim",
404 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE|DA_Q_NO_PREVENT
405 },
406 {
407 /*
408 * United MP5512 Portable MP3 Player (2-in-1 USB DISK/MP3)
409 * PR: usb/80487
410 */
411 {T_DIRECT, SIP_MEDIA_REMOVABLE, "Generic*", "MUSIC DISK",
412 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
413 },
414 {
415 /*
416 * SanDisk Micro Cruzer 128MB
417 * PR: usb/75970
418 */
419 {T_DIRECT, SIP_MEDIA_REMOVABLE, "SanDisk" , "Micro Cruzer",
420 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
421 },
422 {
423 /*
424 * TOSHIBA TransMemory USB sticks
425 * PR: kern/94660
426 */
427 {T_DIRECT, SIP_MEDIA_REMOVABLE, "TOSHIBA", "TransMemory",
428 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
429 },
430 {
431 /*
432 * PNY USB Flash keys
433 * PR: usb/75578, usb/72344, usb/65436
434 */
435 {T_DIRECT, SIP_MEDIA_REMOVABLE, "*" , "USB DISK*",
436 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
437 },
438 {
439 /*
440 * Genesys 6-in-1 Card Reader
441 * PR: usb/94647
442 */
443 {T_DIRECT, SIP_MEDIA_REMOVABLE, "Generic*", "STORAGE DEVICE*",
444 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
445 },
446 {
447 /*
448 * Rekam Digital CAMERA
449 * PR: usb/98713
450 */
451 {T_DIRECT, SIP_MEDIA_REMOVABLE, "CAMERA*", "4MP-9J6*",
452 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
453 },
454 {
455 /*
456 * iRiver H10 MP3 player
457 * PR: usb/102547
458 */
459 {T_DIRECT, SIP_MEDIA_REMOVABLE, "iriver", "H10*",
460 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
461 },
462 {
463 /*
464 * X-Micro Flash Disk
465 * PR: usb/96901
466 */
467 {T_DIRECT, SIP_MEDIA_REMOVABLE, "X-Micro" , "Flash Disk",
468 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
469 },
470 {
471 /*
472 * EasyMP3 EM732X USB 2.0 Flash MP3 Player
473 * PR: usb/96546
474 */
475 {T_DIRECT, SIP_MEDIA_REMOVABLE, "EM732X", "MP3 Player*",
476 "1.0"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
477 },
478 };
479
480 static disk_strategy_t dastrategy;
481 static dumper_t dadump;
482 static periph_init_t dainit;
483 static void daasync(void *callback_arg, u_int32_t code,
484 struct cam_path *path, void *arg);
485 static void dasysctlinit(void *context, int pending);
486 static int dacmdsizesysctl(SYSCTL_HANDLER_ARGS);
487 static periph_ctor_t daregister;
488 static periph_dtor_t dacleanup;
489 static periph_start_t dastart;
490 static periph_oninv_t daoninvalidate;
491 static void dadone(struct cam_periph *periph,
492 union ccb *done_ccb);
493 static int daerror(union ccb *ccb, u_int32_t cam_flags,
494 u_int32_t sense_flags);
495 static void daprevent(struct cam_periph *periph, int action);
496 static int dagetcapacity(struct cam_periph *periph);
497 static void dasetgeom(struct cam_periph *periph, uint32_t block_len,
498 uint64_t maxsector);
499 static timeout_t dasendorderedtag;
500 static void dashutdown(void *arg, int howto);
501
502 #ifndef DA_DEFAULT_TIMEOUT
503 #define DA_DEFAULT_TIMEOUT 60 /* Timeout in seconds */
504 #endif
505
506 #ifndef DA_DEFAULT_RETRY
507 #define DA_DEFAULT_RETRY 4
508 #endif
509
510 #ifndef DA_DEFAULT_SEND_ORDERED
511 #define DA_DEFAULT_SEND_ORDERED 1
512 #endif
513
514
515 static int da_retry_count = DA_DEFAULT_RETRY;
516 static int da_default_timeout = DA_DEFAULT_TIMEOUT;
517 static int da_send_ordered = DA_DEFAULT_SEND_ORDERED;
518
519 SYSCTL_NODE(_kern_cam, OID_AUTO, da, CTLFLAG_RD, 0,
520 "CAM Direct Access Disk driver");
521 SYSCTL_INT(_kern_cam_da, OID_AUTO, retry_count, CTLFLAG_RW,
522 &da_retry_count, 0, "Normal I/O retry count");
523 TUNABLE_INT("kern.cam.da.retry_count", &da_retry_count);
524 SYSCTL_INT(_kern_cam_da, OID_AUTO, default_timeout, CTLFLAG_RW,
525 &da_default_timeout, 0, "Normal I/O timeout (in seconds)");
526 TUNABLE_INT("kern.cam.da.default_timeout", &da_default_timeout);
527 SYSCTL_INT(_kern_cam_da, OID_AUTO, da_send_ordered, CTLFLAG_RW,
528 &da_send_ordered, 0, "Send Ordered Tags");
529 TUNABLE_INT("kern.cam.da.da_send_ordered", &da_send_ordered);
530
531 /*
532 * DA_ORDEREDTAG_INTERVAL determines how often, relative
533 * to the default timeout, we check to see whether an ordered
534 * tagged transaction is appropriate to prevent simple tag
535 * starvation. Since we'd like to ensure that there is at least
536 * 1/2 of the timeout length left for a starved transaction to
537 * complete after we've sent an ordered tag, we must poll at least
538 * four times in every timeout period. This takes care of the worst
539 * case where a starved transaction starts during an interval that
540 * meets the requirement "don't send an ordered tag" test so it takes
541 * us two intervals to determine that a tag must be sent.
542 */
543 #ifndef DA_ORDEREDTAG_INTERVAL
544 #define DA_ORDEREDTAG_INTERVAL 4
545 #endif
546
547 static struct periph_driver dadriver =
548 {
549 dainit, "da",
550 TAILQ_HEAD_INITIALIZER(dadriver.units), /* generation */ 0
551 };
552
553 PERIPHDRIVER_DECLARE(da, dadriver);
554
555 static SLIST_HEAD(,da_softc) softc_list;
556
557 static int
558 daopen(struct disk *dp)
559 {
560 struct cam_periph *periph;
561 struct da_softc *softc;
562 int unit;
563 int error;
564 int s;
565
566 s = splsoftcam();
567 periph = (struct cam_periph *)dp->d_drv1;
568 if (periph == NULL) {
569 splx(s);
570 return (ENXIO);
571 }
572 unit = periph->unit_number;
573
574 softc = (struct da_softc *)periph->softc;
575
576 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE,
577 ("daopen: disk=%s%d (unit %d)\n", dp->d_name, dp->d_unit,
578 unit));
579
580 if ((error = cam_periph_lock(periph, PRIBIO|PCATCH)) != 0)
581 return (error); /* error code from tsleep */
582
583 if (cam_periph_acquire(periph) != CAM_REQ_CMP)
584 return(ENXIO);
585 softc->flags |= DA_FLAG_OPEN;
586
587 if ((softc->flags & DA_FLAG_PACK_INVALID) != 0) {
588 /* Invalidate our pack information. */
589 softc->flags &= ~DA_FLAG_PACK_INVALID;
590 }
591 splx(s);
592
593 error = dagetcapacity(periph);
594
595 if (error == 0) {
596
597 softc->disk->d_sectorsize = softc->params.secsize;
598 softc->disk->d_mediasize = softc->params.secsize * (off_t)softc->params.sectors;
599 /* XXX: these are not actually "firmware" values, so they may be wrong */
600 softc->disk->d_fwsectors = softc->params.secs_per_track;
601 softc->disk->d_fwheads = softc->params.heads;
602 softc->disk->d_devstat->block_size = softc->params.secsize;
603 softc->disk->d_devstat->flags &= ~DEVSTAT_BS_UNAVAILABLE;
604 }
605
606 if (error == 0) {
607 if ((softc->flags & DA_FLAG_PACK_REMOVABLE) != 0 &&
608 (softc->quirks & DA_Q_NO_PREVENT) == 0)
609 daprevent(periph, PR_PREVENT);
610 } else {
611 softc->flags &= ~DA_FLAG_OPEN;
612 cam_periph_release(periph);
613 }
614 cam_periph_unlock(periph);
615 return (error);
616 }
617
618 static int
619 daclose(struct disk *dp)
620 {
621 struct cam_periph *periph;
622 struct da_softc *softc;
623 int error;
624
625 periph = (struct cam_periph *)dp->d_drv1;
626 if (periph == NULL)
627 return (ENXIO);
628
629 softc = (struct da_softc *)periph->softc;
630
631 if ((error = cam_periph_lock(periph, PRIBIO)) != 0) {
632 return (error); /* error code from tsleep */
633 }
634
635 if ((softc->quirks & DA_Q_NO_SYNC_CACHE) == 0) {
636 union ccb *ccb;
637
638 ccb = cam_periph_getccb(periph, /*priority*/1);
639
640 scsi_synchronize_cache(&ccb->csio,
641 /*retries*/1,
642 /*cbfcnp*/dadone,
643 MSG_SIMPLE_Q_TAG,
644 /*begin_lba*/0,/* Cover the whole disk */
645 /*lb_count*/0,
646 SSD_FULL_SIZE,
647 5 * 60 * 1000);
648
649 cam_periph_runccb(ccb, /*error_routine*/NULL, /*cam_flags*/0,
650 /*sense_flags*/SF_RETRY_UA,
651 softc->disk->d_devstat);
652
653 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
654 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
655 CAM_SCSI_STATUS_ERROR) {
656 int asc, ascq;
657 int sense_key, error_code;
658
659 scsi_extract_sense(&ccb->csio.sense_data,
660 &error_code,
661 &sense_key,
662 &asc, &ascq);
663 if (sense_key != SSD_KEY_ILLEGAL_REQUEST)
664 scsi_sense_print(&ccb->csio);
665 } else {
666 xpt_print_path(periph->path);
667 printf("Synchronize cache failed, status "
668 "== 0x%x, scsi status == 0x%x\n",
669 ccb->csio.ccb_h.status,
670 ccb->csio.scsi_status);
671 }
672 }
673
674 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
675 cam_release_devq(ccb->ccb_h.path,
676 /*relsim_flags*/0,
677 /*reduction*/0,
678 /*timeout*/0,
679 /*getcount_only*/0);
680
681 xpt_release_ccb(ccb);
682
683 }
684
685 if ((softc->flags & DA_FLAG_PACK_REMOVABLE) != 0) {
686 if ((softc->quirks & DA_Q_NO_PREVENT) == 0)
687 daprevent(periph, PR_ALLOW);
688 /*
689 * If we've got removeable media, mark the blocksize as
690 * unavailable, since it could change when new media is
691 * inserted.
692 */
693 softc->disk->d_devstat->flags |= DEVSTAT_BS_UNAVAILABLE;
694 }
695
696 softc->flags &= ~DA_FLAG_OPEN;
697 cam_periph_unlock(periph);
698 cam_periph_release(periph);
699 return (0);
700 }
701
702 /*
703 * Actually translate the requested transfer into one the physical driver
704 * can understand. The transfer is described by a buf and will include
705 * only one physical transfer.
706 */
707 static void
708 dastrategy(struct bio *bp)
709 {
710 struct cam_periph *periph;
711 struct da_softc *softc;
712 int s;
713
714 periph = (struct cam_periph *)bp->bio_disk->d_drv1;
715 if (periph == NULL) {
716 biofinish(bp, NULL, ENXIO);
717 return;
718 }
719 softc = (struct da_softc *)periph->softc;
720 #if 0
721 /*
722 * check it's not too big a transfer for our adapter
723 */
724 scsi_minphys(bp,&sd_switch);
725 #endif
726
727 /*
728 * Mask interrupts so that the pack cannot be invalidated until
729 * after we are in the queue. Otherwise, we might not properly
730 * clean up one of the buffers.
731 */
732 s = splbio();
733
734 /*
735 * If the device has been made invalid, error out
736 */
737 if ((softc->flags & DA_FLAG_PACK_INVALID)) {
738 splx(s);
739 biofinish(bp, NULL, ENXIO);
740 return;
741 }
742
743 /*
744 * Place it in the queue of disk activities for this disk
745 */
746 bioq_disksort(&softc->bio_queue, bp);
747
748 splx(s);
749
750 /*
751 * Schedule ourselves for performing the work.
752 */
753 xpt_schedule(periph, /* XXX priority */1);
754
755 return;
756 }
757
758 static int
759 dadump(void *arg, void *virtual, vm_offset_t physical, off_t offset, size_t length)
760 {
761 struct cam_periph *periph;
762 struct da_softc *softc;
763 u_int secsize;
764 struct ccb_scsiio csio;
765 struct disk *dp;
766
767 dp = arg;
768 periph = dp->d_drv1;
769 if (periph == NULL)
770 return (ENXIO);
771 softc = (struct da_softc *)periph->softc;
772 secsize = softc->params.secsize;
773
774 if ((softc->flags & DA_FLAG_PACK_INVALID) != 0)
775 return (ENXIO);
776
777 if (length > 0) {
778 xpt_setup_ccb(&csio.ccb_h, periph->path, /*priority*/1);
779 csio.ccb_h.ccb_state = DA_CCB_DUMP;
780 scsi_read_write(&csio,
781 /*retries*/1,
782 dadone,
783 MSG_ORDERED_Q_TAG,
784 /*read*/FALSE,
785 /*byte2*/0,
786 /*minimum_cmd_size*/ softc->minimum_cmd_size,
787 offset / secsize,
788 length / secsize,
789 /*data_ptr*/(u_int8_t *) virtual,
790 /*dxfer_len*/length,
791 /*sense_len*/SSD_FULL_SIZE,
792 DA_DEFAULT_TIMEOUT * 1000);
793 xpt_polled_action((union ccb *)&csio);
794
795 if ((csio.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
796 printf("Aborting dump due to I/O error.\n");
797 if ((csio.ccb_h.status & CAM_STATUS_MASK) ==
798 CAM_SCSI_STATUS_ERROR)
799 scsi_sense_print(&csio);
800 else
801 printf("status == 0x%x, scsi status == 0x%x\n",
802 csio.ccb_h.status, csio.scsi_status);
803 return(EIO);
804 }
805 return(0);
806 }
807
808 /*
809 * Sync the disk cache contents to the physical media.
810 */
811 if ((softc->quirks & DA_Q_NO_SYNC_CACHE) == 0) {
812
813 xpt_setup_ccb(&csio.ccb_h, periph->path, /*priority*/1);
814 csio.ccb_h.ccb_state = DA_CCB_DUMP;
815 scsi_synchronize_cache(&csio,
816 /*retries*/1,
817 /*cbfcnp*/dadone,
818 MSG_SIMPLE_Q_TAG,
819 /*begin_lba*/0,/* Cover the whole disk */
820 /*lb_count*/0,
821 SSD_FULL_SIZE,
822 5 * 60 * 1000);
823 xpt_polled_action((union ccb *)&csio);
824
825 if ((csio.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
826 if ((csio.ccb_h.status & CAM_STATUS_MASK) ==
827 CAM_SCSI_STATUS_ERROR) {
828 int asc, ascq;
829 int sense_key, error_code;
830
831 scsi_extract_sense(&csio.sense_data,
832 &error_code,
833 &sense_key,
834 &asc, &ascq);
835 if (sense_key != SSD_KEY_ILLEGAL_REQUEST)
836 scsi_sense_print(&csio);
837 } else {
838 xpt_print_path(periph->path);
839 printf("Synchronize cache failed, status "
840 "== 0x%x, scsi status == 0x%x\n",
841 csio.ccb_h.status, csio.scsi_status);
842 }
843 }
844 }
845 return (0);
846 }
847
848 static void
849 dainit(void)
850 {
851 cam_status status;
852 struct cam_path *path;
853
854 SLIST_INIT(&softc_list);
855
856 /*
857 * Install a global async callback. This callback will
858 * receive async callbacks like "new device found".
859 */
860 status = xpt_create_path(&path, /*periph*/NULL, CAM_XPT_PATH_ID,
861 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD);
862
863 if (status == CAM_REQ_CMP) {
864 struct ccb_setasync csa;
865
866 xpt_setup_ccb(&csa.ccb_h, path, /*priority*/5);
867 csa.ccb_h.func_code = XPT_SASYNC_CB;
868 csa.event_enable = AC_FOUND_DEVICE;
869 csa.callback = daasync;
870 csa.callback_arg = NULL;
871 xpt_action((union ccb *)&csa);
872 status = csa.ccb_h.status;
873 xpt_free_path(path);
874 }
875
876 if (status != CAM_REQ_CMP) {
877 printf("da: Failed to attach master async callback "
878 "due to status 0x%x!\n", status);
879 } else if (da_send_ordered) {
880
881 /*
882 * Schedule a periodic event to occasionally send an
883 * ordered tag to a device.
884 */
885 timeout(dasendorderedtag, NULL,
886 (DA_DEFAULT_TIMEOUT * hz) / DA_ORDEREDTAG_INTERVAL);
887
888 /* Register our shutdown event handler */
889 if ((EVENTHANDLER_REGISTER(shutdown_post_sync, dashutdown,
890 NULL, SHUTDOWN_PRI_DEFAULT)) == NULL)
891 printf("dainit: shutdown event registration failed!\n");
892 }
893 }
894
895 static void
896 daoninvalidate(struct cam_periph *periph)
897 {
898 int s;
899 struct da_softc *softc;
900 struct ccb_setasync csa;
901
902 softc = (struct da_softc *)periph->softc;
903
904 /*
905 * De-register any async callbacks.
906 */
907 xpt_setup_ccb(&csa.ccb_h, periph->path,
908 /* priority */ 5);
909 csa.ccb_h.func_code = XPT_SASYNC_CB;
910 csa.event_enable = 0;
911 csa.callback = daasync;
912 csa.callback_arg = periph;
913 xpt_action((union ccb *)&csa);
914
915 softc->flags |= DA_FLAG_PACK_INVALID;
916
917 /*
918 * Although the oninvalidate() routines are always called at
919 * splsoftcam, we need to be at splbio() here to keep the buffer
920 * queue from being modified while we traverse it.
921 */
922 s = splbio();
923
924 /*
925 * Return all queued I/O with ENXIO.
926 * XXX Handle any transactions queued to the card
927 * with XPT_ABORT_CCB.
928 */
929 bioq_flush(&softc->bio_queue, NULL, ENXIO);
930 splx(s);
931
932 SLIST_REMOVE(&softc_list, softc, da_softc, links);
933
934 disk_gone(softc->disk);
935 xpt_print_path(periph->path);
936 printf("lost device\n");
937 }
938
939 static void
940 dacleanup(struct cam_periph *periph)
941 {
942 struct da_softc *softc;
943
944 softc = (struct da_softc *)periph->softc;
945
946 xpt_print_path(periph->path);
947 printf("removing device entry\n");
948 /*
949 * If we can't free the sysctl tree, oh well...
950 */
951 if ((softc->flags & DA_FLAG_SCTX_INIT) != 0
952 && sysctl_ctx_free(&softc->sysctl_ctx) != 0) {
953 xpt_print_path(periph->path);
954 printf("can't remove sysctl context\n");
955 }
956 disk_destroy(softc->disk);
957 free(softc, M_DEVBUF);
958 }
959
960 static void
961 daasync(void *callback_arg, u_int32_t code,
962 struct cam_path *path, void *arg)
963 {
964 struct cam_periph *periph;
965
966 periph = (struct cam_periph *)callback_arg;
967 switch (code) {
968 case AC_FOUND_DEVICE:
969 {
970 struct ccb_getdev *cgd;
971 cam_status status;
972
973 cgd = (struct ccb_getdev *)arg;
974 if (cgd == NULL)
975 break;
976
977 if (SID_TYPE(&cgd->inq_data) != T_DIRECT
978 && SID_TYPE(&cgd->inq_data) != T_RBC
979 && SID_TYPE(&cgd->inq_data) != T_OPTICAL)
980 break;
981
982 /*
983 * Allocate a peripheral instance for
984 * this device and start the probe
985 * process.
986 */
987 status = cam_periph_alloc(daregister, daoninvalidate,
988 dacleanup, dastart,
989 "da", CAM_PERIPH_BIO,
990 cgd->ccb_h.path, daasync,
991 AC_FOUND_DEVICE, cgd);
992
993 if (status != CAM_REQ_CMP
994 && status != CAM_REQ_INPROG)
995 printf("daasync: Unable to attach to new device "
996 "due to status 0x%x\n", status);
997 break;
998 }
999 case AC_SENT_BDR:
1000 case AC_BUS_RESET:
1001 {
1002 struct da_softc *softc;
1003 struct ccb_hdr *ccbh;
1004 int s;
1005
1006 softc = (struct da_softc *)periph->softc;
1007 s = splsoftcam();
1008 /*
1009 * Don't fail on the expected unit attention
1010 * that will occur.
1011 */
1012 softc->flags |= DA_FLAG_RETRY_UA;
1013 LIST_FOREACH(ccbh, &softc->pending_ccbs, periph_links.le)
1014 ccbh->ccb_state |= DA_CCB_RETRY_UA;
1015 splx(s);
1016 /* FALLTHROUGH*/
1017 }
1018 default:
1019 cam_periph_async(periph, code, path, arg);
1020 break;
1021 }
1022 }
1023
1024 static void
1025 dasysctlinit(void *context, int pending)
1026 {
1027 struct cam_periph *periph;
1028 struct da_softc *softc;
1029 char tmpstr[80], tmpstr2[80];
1030
1031 periph = (struct cam_periph *)context;
1032 softc = (struct da_softc *)periph->softc;
1033
1034 snprintf(tmpstr, sizeof(tmpstr), "CAM DA unit %d", periph->unit_number);
1035 snprintf(tmpstr2, sizeof(tmpstr2), "%d", periph->unit_number);
1036
1037 mtx_lock(&Giant);
1038 sysctl_ctx_init(&softc->sysctl_ctx);
1039 softc->flags |= DA_FLAG_SCTX_INIT;
1040 softc->sysctl_tree = SYSCTL_ADD_NODE(&softc->sysctl_ctx,
1041 SYSCTL_STATIC_CHILDREN(_kern_cam_da), OID_AUTO, tmpstr2,
1042 CTLFLAG_RD, 0, tmpstr);
1043 if (softc->sysctl_tree == NULL) {
1044 printf("dasysctlinit: unable to allocate sysctl tree\n");
1045 mtx_unlock(&Giant);
1046 return;
1047 }
1048
1049 /*
1050 * Now register the sysctl handler, so the user can the value on
1051 * the fly.
1052 */
1053 SYSCTL_ADD_PROC(&softc->sysctl_ctx,SYSCTL_CHILDREN(softc->sysctl_tree),
1054 OID_AUTO, "minimum_cmd_size", CTLTYPE_INT | CTLFLAG_RW,
1055 &softc->minimum_cmd_size, 0, dacmdsizesysctl, "I",
1056 "Minimum CDB size");
1057
1058 mtx_unlock(&Giant);
1059 }
1060
1061 static int
1062 dacmdsizesysctl(SYSCTL_HANDLER_ARGS)
1063 {
1064 int error, value;
1065
1066 value = *(int *)arg1;
1067
1068 error = sysctl_handle_int(oidp, &value, 0, req);
1069
1070 if ((error != 0)
1071 || (req->newptr == NULL))
1072 return (error);
1073
1074 /*
1075 * Acceptable values here are 6, 10, 12 or 16.
1076 */
1077 if (value < 6)
1078 value = 6;
1079 else if ((value > 6)
1080 && (value <= 10))
1081 value = 10;
1082 else if ((value > 10)
1083 && (value <= 12))
1084 value = 12;
1085 else if (value > 12)
1086 value = 16;
1087
1088 *(int *)arg1 = value;
1089
1090 return (0);
1091 }
1092
1093 static cam_status
1094 daregister(struct cam_periph *periph, void *arg)
1095 {
1096 int s;
1097 struct da_softc *softc;
1098 struct ccb_setasync csa;
1099 struct ccb_pathinq cpi;
1100 struct ccb_getdev *cgd;
1101 char tmpstr[80];
1102 caddr_t match;
1103
1104 cgd = (struct ccb_getdev *)arg;
1105 if (periph == NULL) {
1106 printf("daregister: periph was NULL!!\n");
1107 return(CAM_REQ_CMP_ERR);
1108 }
1109
1110 if (cgd == NULL) {
1111 printf("daregister: no getdev CCB, can't register device\n");
1112 return(CAM_REQ_CMP_ERR);
1113 }
1114
1115 softc = (struct da_softc *)malloc(sizeof(*softc), M_DEVBUF,
1116 M_NOWAIT|M_ZERO);
1117
1118 if (softc == NULL) {
1119 printf("daregister: Unable to probe new device. "
1120 "Unable to allocate softc\n");
1121 return(CAM_REQ_CMP_ERR);
1122 }
1123
1124 LIST_INIT(&softc->pending_ccbs);
1125 softc->state = DA_STATE_PROBE;
1126 bioq_init(&softc->bio_queue);
1127 if (SID_IS_REMOVABLE(&cgd->inq_data))
1128 softc->flags |= DA_FLAG_PACK_REMOVABLE;
1129 if ((cgd->inq_data.flags & SID_CmdQue) != 0)
1130 softc->flags |= DA_FLAG_TAGGED_QUEUING;
1131
1132 periph->softc = softc;
1133
1134 /*
1135 * See if this device has any quirks.
1136 */
1137 match = cam_quirkmatch((caddr_t)&cgd->inq_data,
1138 (caddr_t)da_quirk_table,
1139 sizeof(da_quirk_table)/sizeof(*da_quirk_table),
1140 sizeof(*da_quirk_table), scsi_inquiry_match);
1141
1142 if (match != NULL)
1143 softc->quirks = ((struct da_quirk_entry *)match)->quirks;
1144 else
1145 softc->quirks = DA_Q_NONE;
1146
1147 /* Check if the SIM does not want 6 byte commands */
1148 xpt_setup_ccb(&cpi.ccb_h, periph->path, /*priority*/1);
1149 cpi.ccb_h.func_code = XPT_PATH_INQ;
1150 xpt_action((union ccb *)&cpi);
1151 if (cpi.ccb_h.status == CAM_REQ_CMP && (cpi.hba_misc & PIM_NO_6_BYTE))
1152 softc->quirks |= DA_Q_NO_6_BYTE;
1153
1154 TASK_INIT(&softc->sysctl_task, 0, dasysctlinit, periph);
1155
1156 /*
1157 * RBC devices don't have to support READ(6), only READ(10).
1158 */
1159 if (softc->quirks & DA_Q_NO_6_BYTE || SID_TYPE(&cgd->inq_data) == T_RBC)
1160 softc->minimum_cmd_size = 10;
1161 else
1162 softc->minimum_cmd_size = 6;
1163
1164 /*
1165 * Load the user's default, if any.
1166 */
1167 snprintf(tmpstr, sizeof(tmpstr), "kern.cam.da.%d.minimum_cmd_size",
1168 periph->unit_number);
1169 TUNABLE_INT_FETCH(tmpstr, &softc->minimum_cmd_size);
1170
1171 /*
1172 * 6, 10, 12 and 16 are the currently permissible values.
1173 */
1174 if (softc->minimum_cmd_size < 6)
1175 softc->minimum_cmd_size = 6;
1176 else if ((softc->minimum_cmd_size > 6)
1177 && (softc->minimum_cmd_size <= 10))
1178 softc->minimum_cmd_size = 10;
1179 else if ((softc->minimum_cmd_size > 10)
1180 && (softc->minimum_cmd_size <= 12))
1181 softc->minimum_cmd_size = 12;
1182 else if (softc->minimum_cmd_size > 12)
1183 softc->minimum_cmd_size = 16;
1184
1185 /*
1186 * Block our timeout handler while we
1187 * add this softc to the dev list.
1188 */
1189 s = splsoftclock();
1190 SLIST_INSERT_HEAD(&softc_list, softc, links);
1191 splx(s);
1192
1193 /*
1194 * Register this media as a disk
1195 */
1196
1197 softc->disk = disk_alloc();
1198 softc->disk->d_open = daopen;
1199 softc->disk->d_close = daclose;
1200 softc->disk->d_strategy = dastrategy;
1201 softc->disk->d_dump = dadump;
1202 softc->disk->d_name = "da";
1203 softc->disk->d_drv1 = periph;
1204 softc->disk->d_maxsize = DFLTPHYS; /* XXX: probably not arbitrary */
1205 softc->disk->d_unit = periph->unit_number;
1206 softc->disk->d_flags = DISKFLAG_NEEDSGIANT;
1207 disk_create(softc->disk, DISK_VERSION);
1208
1209 /*
1210 * Add async callbacks for bus reset and
1211 * bus device reset calls. I don't bother
1212 * checking if this fails as, in most cases,
1213 * the system will function just fine without
1214 * them and the only alternative would be to
1215 * not attach the device on failure.
1216 */
1217 xpt_setup_ccb(&csa.ccb_h, periph->path, /*priority*/5);
1218 csa.ccb_h.func_code = XPT_SASYNC_CB;
1219 csa.event_enable = AC_SENT_BDR | AC_BUS_RESET | AC_LOST_DEVICE;
1220 csa.callback = daasync;
1221 csa.callback_arg = periph;
1222 xpt_action((union ccb *)&csa);
1223 /*
1224 * Lock this peripheral until we are setup.
1225 * This first call can't block
1226 */
1227 (void)cam_periph_lock(periph, PRIBIO);
1228 xpt_schedule(periph, /*priority*/5);
1229
1230 return(CAM_REQ_CMP);
1231 }
1232
1233 static void
1234 dastart(struct cam_periph *periph, union ccb *start_ccb)
1235 {
1236 struct da_softc *softc;
1237
1238 softc = (struct da_softc *)periph->softc;
1239
1240
1241 switch (softc->state) {
1242 case DA_STATE_NORMAL:
1243 {
1244 /* Pull a buffer from the queue and get going on it */
1245 struct bio *bp;
1246 int s;
1247
1248 /*
1249 * See if there is a buf with work for us to do..
1250 */
1251 s = splbio();
1252 bp = bioq_first(&softc->bio_queue);
1253 if (periph->immediate_priority <= periph->pinfo.priority) {
1254 CAM_DEBUG_PRINT(CAM_DEBUG_SUBTRACE,
1255 ("queuing for immediate ccb\n"));
1256 start_ccb->ccb_h.ccb_state = DA_CCB_WAITING;
1257 SLIST_INSERT_HEAD(&periph->ccb_list, &start_ccb->ccb_h,
1258 periph_links.sle);
1259 periph->immediate_priority = CAM_PRIORITY_NONE;
1260 splx(s);
1261 wakeup(&periph->ccb_list);
1262 } else if (bp == NULL) {
1263 splx(s);
1264 xpt_release_ccb(start_ccb);
1265 } else {
1266 int oldspl;
1267 u_int8_t tag_code;
1268
1269 bioq_remove(&softc->bio_queue, bp);
1270
1271 if ((softc->flags & DA_FLAG_NEED_OTAG) != 0) {
1272 softc->flags &= ~DA_FLAG_NEED_OTAG;
1273 softc->ordered_tag_count++;
1274 tag_code = MSG_ORDERED_Q_TAG;
1275 } else {
1276 tag_code = MSG_SIMPLE_Q_TAG;
1277 }
1278 scsi_read_write(&start_ccb->csio,
1279 /*retries*/da_retry_count,
1280 /*cbfcnp*/dadone,
1281 /*tag_action*/tag_code,
1282 /*read_op*/bp->bio_cmd == BIO_READ,
1283 /*byte2*/0,
1284 softc->minimum_cmd_size,
1285 /*lba*/bp->bio_pblkno,
1286 /*block_count*/bp->bio_bcount /
1287 softc->params.secsize,
1288 /*data_ptr*/ bp->bio_data,
1289 /*dxfer_len*/ bp->bio_bcount,
1290 /*sense_len*/SSD_FULL_SIZE,
1291 /*timeout*/da_default_timeout*1000);
1292 start_ccb->ccb_h.ccb_state = DA_CCB_BUFFER_IO;
1293
1294 /*
1295 * Block out any asyncronous callbacks
1296 * while we touch the pending ccb list.
1297 */
1298 oldspl = splcam();
1299 LIST_INSERT_HEAD(&softc->pending_ccbs,
1300 &start_ccb->ccb_h, periph_links.le);
1301 softc->outstanding_cmds++;
1302 splx(oldspl);
1303
1304 /* We expect a unit attention from this device */
1305 if ((softc->flags & DA_FLAG_RETRY_UA) != 0) {
1306 start_ccb->ccb_h.ccb_state |= DA_CCB_RETRY_UA;
1307 softc->flags &= ~DA_FLAG_RETRY_UA;
1308 }
1309
1310 start_ccb->ccb_h.ccb_bp = bp;
1311 bp = bioq_first(&softc->bio_queue);
1312 splx(s);
1313
1314 xpt_action(start_ccb);
1315 }
1316
1317 if (bp != NULL) {
1318 /* Have more work to do, so ensure we stay scheduled */
1319 xpt_schedule(periph, /* XXX priority */1);
1320 }
1321 break;
1322 }
1323 case DA_STATE_PROBE:
1324 {
1325 struct ccb_scsiio *csio;
1326 struct scsi_read_capacity_data *rcap;
1327
1328 rcap = (struct scsi_read_capacity_data *)
1329 malloc(sizeof(*rcap), M_TEMP, M_NOWAIT|M_ZERO);
1330 if (rcap == NULL) {
1331 printf("dastart: Couldn't malloc read_capacity data\n");
1332 /* da_free_periph??? */
1333 break;
1334 }
1335 csio = &start_ccb->csio;
1336 scsi_read_capacity(csio,
1337 /*retries*/4,
1338 dadone,
1339 MSG_SIMPLE_Q_TAG,
1340 rcap,
1341 SSD_FULL_SIZE,
1342 /*timeout*/5000);
1343 start_ccb->ccb_h.ccb_bp = NULL;
1344 start_ccb->ccb_h.ccb_state = DA_CCB_PROBE;
1345 xpt_action(start_ccb);
1346 break;
1347 }
1348 case DA_STATE_PROBE2:
1349 {
1350 struct ccb_scsiio *csio;
1351 struct scsi_read_capacity_data_long *rcaplong;
1352
1353 rcaplong = (struct scsi_read_capacity_data_long *)
1354 malloc(sizeof(*rcaplong), M_TEMP, M_NOWAIT|M_ZERO);
1355 if (rcaplong == NULL) {
1356 printf("dastart: Couldn't malloc read_capacity data\n");
1357 /* da_free_periph??? */
1358 break;
1359 }
1360 csio = &start_ccb->csio;
1361 scsi_read_capacity_16(csio,
1362 /*retries*/ 4,
1363 /*cbfcnp*/ dadone,
1364 /*tag_action*/ MSG_SIMPLE_Q_TAG,
1365 /*lba*/ 0,
1366 /*reladr*/ 0,
1367 /*pmi*/ 0,
1368 rcaplong,
1369 /*sense_len*/ SSD_FULL_SIZE,
1370 /*timeout*/ 60000);
1371 start_ccb->ccb_h.ccb_bp = NULL;
1372 start_ccb->ccb_h.ccb_state = DA_CCB_PROBE2;
1373 xpt_action(start_ccb);
1374 break;
1375 }
1376 }
1377 }
1378
1379 static int
1380 cmd6workaround(union ccb *ccb)
1381 {
1382 struct scsi_rw_6 cmd6;
1383 struct scsi_rw_10 *cmd10;
1384 struct da_softc *softc;
1385 u_int8_t *cdb;
1386 int frozen;
1387
1388 cdb = ccb->csio.cdb_io.cdb_bytes;
1389
1390 /* Translation only possible if CDB is an array and cmd is R/W6 */
1391 if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0 ||
1392 (*cdb != READ_6 && *cdb != WRITE_6))
1393 return 0;
1394
1395 xpt_print_path(ccb->ccb_h.path);
1396 printf("READ(6)/WRITE(6) not supported, "
1397 "increasing minimum_cmd_size to 10.\n");
1398 softc = (struct da_softc *)xpt_path_periph(ccb->ccb_h.path)->softc;
1399 softc->minimum_cmd_size = 10;
1400
1401 bcopy(cdb, &cmd6, sizeof(struct scsi_rw_6));
1402 cmd10 = (struct scsi_rw_10 *)cdb;
1403 cmd10->opcode = (cmd6.opcode == READ_6) ? READ_10 : WRITE_10;
1404 cmd10->byte2 = 0;
1405 scsi_ulto4b(scsi_3btoul(cmd6.addr), cmd10->addr);
1406 cmd10->reserved = 0;
1407 scsi_ulto2b(cmd6.length, cmd10->length);
1408 cmd10->control = cmd6.control;
1409 ccb->csio.cdb_len = sizeof(*cmd10);
1410
1411 /* Requeue request, unfreezing queue if necessary */
1412 frozen = (ccb->ccb_h.status & CAM_DEV_QFRZN) != 0;
1413 ccb->ccb_h.status = CAM_REQUEUE_REQ;
1414 xpt_action(ccb);
1415 if (frozen) {
1416 cam_release_devq(ccb->ccb_h.path,
1417 /*relsim_flags*/0,
1418 /*reduction*/0,
1419 /*timeout*/0,
1420 /*getcount_only*/0);
1421 }
1422 return (ERESTART);
1423 }
1424
1425 static void
1426 dadone(struct cam_periph *periph, union ccb *done_ccb)
1427 {
1428 struct da_softc *softc;
1429 struct ccb_scsiio *csio;
1430
1431 softc = (struct da_softc *)periph->softc;
1432 csio = &done_ccb->csio;
1433 switch (csio->ccb_h.ccb_state & DA_CCB_TYPE_MASK) {
1434 case DA_CCB_BUFFER_IO:
1435 {
1436 struct bio *bp;
1437 int oldspl;
1438
1439 bp = (struct bio *)done_ccb->ccb_h.ccb_bp;
1440 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1441 int error;
1442 int s;
1443 int sf;
1444
1445 if ((csio->ccb_h.ccb_state & DA_CCB_RETRY_UA) != 0)
1446 sf = SF_RETRY_UA;
1447 else
1448 sf = 0;
1449
1450 error = daerror(done_ccb, CAM_RETRY_SELTO, sf);
1451 if (error == ERESTART) {
1452 /*
1453 * A retry was scheuled, so
1454 * just return.
1455 */
1456 return;
1457 }
1458 if (error != 0) {
1459
1460 s = splbio();
1461
1462 if (error == ENXIO) {
1463 /*
1464 * Catastrophic error. Mark our pack as
1465 * invalid.
1466 */
1467 /* XXX See if this is really a media
1468 * change first.
1469 */
1470 xpt_print_path(periph->path);
1471 printf("Invalidating pack\n");
1472 softc->flags |= DA_FLAG_PACK_INVALID;
1473 }
1474
1475 /*
1476 * return all queued I/O with EIO, so that
1477 * the client can retry these I/Os in the
1478 * proper order should it attempt to recover.
1479 */
1480 bioq_flush(&softc->bio_queue, NULL, EIO);
1481 splx(s);
1482 bp->bio_error = error;
1483 bp->bio_resid = bp->bio_bcount;
1484 bp->bio_flags |= BIO_ERROR;
1485 } else {
1486 bp->bio_resid = csio->resid;
1487 bp->bio_error = 0;
1488 if (bp->bio_resid != 0)
1489 bp->bio_flags |= BIO_ERROR;
1490 }
1491 if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
1492 cam_release_devq(done_ccb->ccb_h.path,
1493 /*relsim_flags*/0,
1494 /*reduction*/0,
1495 /*timeout*/0,
1496 /*getcount_only*/0);
1497 } else {
1498 if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
1499 panic("REQ_CMP with QFRZN");
1500 bp->bio_resid = csio->resid;
1501 if (csio->resid > 0)
1502 bp->bio_flags |= BIO_ERROR;
1503 }
1504
1505 /*
1506 * Block out any asyncronous callbacks
1507 * while we touch the pending ccb list.
1508 */
1509 oldspl = splcam();
1510 LIST_REMOVE(&done_ccb->ccb_h, periph_links.le);
1511 softc->outstanding_cmds--;
1512 if (softc->outstanding_cmds == 0)
1513 softc->flags |= DA_FLAG_WENT_IDLE;
1514 splx(oldspl);
1515
1516 biodone(bp);
1517 break;
1518 }
1519 case DA_CCB_PROBE:
1520 case DA_CCB_PROBE2:
1521 {
1522 struct scsi_read_capacity_data *rdcap;
1523 struct scsi_read_capacity_data_long *rcaplong;
1524 char announce_buf[80];
1525
1526 rdcap = NULL;
1527 rcaplong = NULL;
1528 if (softc->state == DA_STATE_PROBE)
1529 rdcap =(struct scsi_read_capacity_data *)csio->data_ptr;
1530 else
1531 rcaplong = (struct scsi_read_capacity_data_long *)
1532 csio->data_ptr;
1533
1534 if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
1535 struct disk_params *dp;
1536 uint32_t block_size;
1537 uint64_t maxsector;
1538
1539 if (softc->state == DA_STATE_PROBE) {
1540 block_size = scsi_4btoul(rdcap->length);
1541 maxsector = scsi_4btoul(rdcap->addr);
1542
1543 /*
1544 * According to SBC-2, if the standard 10
1545 * byte READ CAPACITY command returns 2^32,
1546 * we should issue the 16 byte version of
1547 * the command, since the device in question
1548 * has more sectors than can be represented
1549 * with the short version of the command.
1550 */
1551 if (maxsector == 0xffffffff) {
1552 softc->state = DA_STATE_PROBE2;
1553 free(rdcap, M_TEMP);
1554 xpt_release_ccb(done_ccb);
1555 xpt_schedule(periph, /*priority*/5);
1556 return;
1557 }
1558 } else {
1559 block_size = scsi_4btoul(rcaplong->length);
1560 maxsector = scsi_8btou64(rcaplong->addr);
1561 }
1562
1563 /*
1564 * Because GEOM code just will panic us if we
1565 * give them an 'illegal' value we'll avoid that
1566 * here.
1567 */
1568 if (block_size >= MAXPHYS || block_size == 0) {
1569 xpt_print_path(periph->path);
1570 printf("unsupportable block size %ju\n",
1571 (uintmax_t) block_size);
1572 announce_buf[0] = '\0';
1573 cam_periph_invalidate(periph);
1574 } else {
1575 dasetgeom(periph, block_size, maxsector);
1576 dp = &softc->params;
1577 snprintf(announce_buf, sizeof(announce_buf),
1578 "%juMB (%ju %u byte sectors: %dH %dS/T "
1579 "%dC)", (uintmax_t)
1580 (((uintmax_t)dp->secsize *
1581 dp->sectors) / (1024*1024)),
1582 (uintmax_t)dp->sectors,
1583 dp->secsize, dp->heads,
1584 dp->secs_per_track, dp->cylinders);
1585 }
1586 } else {
1587 int error;
1588
1589 announce_buf[0] = '\0';
1590
1591 /*
1592 * Retry any UNIT ATTENTION type errors. They
1593 * are expected at boot.
1594 */
1595 error = daerror(done_ccb, CAM_RETRY_SELTO,
1596 SF_RETRY_UA|SF_NO_PRINT);
1597 if (error == ERESTART) {
1598 /*
1599 * A retry was scheuled, so
1600 * just return.
1601 */
1602 return;
1603 } else if (error != 0) {
1604 struct scsi_sense_data *sense;
1605 int asc, ascq;
1606 int sense_key, error_code;
1607 int have_sense;
1608 cam_status status;
1609 struct ccb_getdev cgd;
1610
1611 /* Don't wedge this device's queue */
1612 status = done_ccb->ccb_h.status;
1613 if ((status & CAM_DEV_QFRZN) != 0)
1614 cam_release_devq(done_ccb->ccb_h.path,
1615 /*relsim_flags*/0,
1616 /*reduction*/0,
1617 /*timeout*/0,
1618 /*getcount_only*/0);
1619
1620
1621 xpt_setup_ccb(&cgd.ccb_h,
1622 done_ccb->ccb_h.path,
1623 /* priority */ 1);
1624 cgd.ccb_h.func_code = XPT_GDEV_TYPE;
1625 xpt_action((union ccb *)&cgd);
1626
1627 if (((csio->ccb_h.flags & CAM_SENSE_PHYS) != 0)
1628 || ((csio->ccb_h.flags & CAM_SENSE_PTR) != 0)
1629 || ((status & CAM_AUTOSNS_VALID) == 0))
1630 have_sense = FALSE;
1631 else
1632 have_sense = TRUE;
1633
1634 if (have_sense) {
1635 sense = &csio->sense_data;
1636 scsi_extract_sense(sense, &error_code,
1637 &sense_key,
1638 &asc, &ascq);
1639 }
1640 /*
1641 * Attach to anything that claims to be a
1642 * direct access or optical disk device,
1643 * as long as it doesn't return a "Logical
1644 * unit not supported" (0x25) error.
1645 */
1646 if ((have_sense) && (asc != 0x25)
1647 && (error_code == SSD_CURRENT_ERROR)) {
1648 const char *sense_key_desc;
1649 const char *asc_desc;
1650
1651 scsi_sense_desc(sense_key, asc, ascq,
1652 &cgd.inq_data,
1653 &sense_key_desc,
1654 &asc_desc);
1655 snprintf(announce_buf,
1656 sizeof(announce_buf),
1657 "Attempt to query device "
1658 "size failed: %s, %s",
1659 sense_key_desc,
1660 asc_desc);
1661 } else {
1662 if (have_sense)
1663 scsi_sense_print(
1664 &done_ccb->csio);
1665 else {
1666 xpt_print_path(periph->path);
1667 printf("got CAM status %#x\n",
1668 done_ccb->ccb_h.status);
1669 }
1670
1671 xpt_print_path(periph->path);
1672 printf("fatal error, failed"
1673 " to attach to device\n");
1674
1675 /*
1676 * Free up resources.
1677 */
1678 cam_periph_invalidate(periph);
1679 }
1680 }
1681 }
1682 free(csio->data_ptr, M_TEMP);
1683 if (announce_buf[0] != '\0') {
1684 xpt_announce_periph(periph, announce_buf);
1685 /*
1686 * Create our sysctl variables, now that we know
1687 * we have successfully attached.
1688 */
1689 taskqueue_enqueue(taskqueue_thread,&softc->sysctl_task);
1690 }
1691 softc->state = DA_STATE_NORMAL;
1692 /*
1693 * Since our peripheral may be invalidated by an error
1694 * above or an external event, we must release our CCB
1695 * before releasing the probe lock on the peripheral.
1696 * The peripheral will only go away once the last lock
1697 * is removed, and we need it around for the CCB release
1698 * operation.
1699 */
1700 xpt_release_ccb(done_ccb);
1701 cam_periph_unlock(periph);
1702 return;
1703 }
1704 case DA_CCB_WAITING:
1705 {
1706 /* Caller will release the CCB */
1707 wakeup(&done_ccb->ccb_h.cbfcnp);
1708 return;
1709 }
1710 case DA_CCB_DUMP:
1711 /* No-op. We're polling */
1712 return;
1713 default:
1714 break;
1715 }
1716 xpt_release_ccb(done_ccb);
1717 }
1718
1719 static int
1720 daerror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags)
1721 {
1722 struct da_softc *softc;
1723 struct cam_periph *periph;
1724 int error;
1725
1726 periph = xpt_path_periph(ccb->ccb_h.path);
1727 softc = (struct da_softc *)periph->softc;
1728
1729 /*
1730 * Automatically detect devices that do not support
1731 * READ(6)/WRITE(6) and upgrade to using 10 byte cdbs.
1732 */
1733 error = 0;
1734 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INVALID) {
1735 error = cmd6workaround(ccb);
1736 } else if (((ccb->ccb_h.status & CAM_STATUS_MASK) ==
1737 CAM_SCSI_STATUS_ERROR)
1738 && (ccb->ccb_h.status & CAM_AUTOSNS_VALID)
1739 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
1740 && ((ccb->ccb_h.flags & CAM_SENSE_PHYS) == 0)
1741 && ((ccb->ccb_h.flags & CAM_SENSE_PTR) == 0)) {
1742 int sense_key, error_code, asc, ascq;
1743
1744 scsi_extract_sense(&ccb->csio.sense_data,
1745 &error_code, &sense_key, &asc, &ascq);
1746 if (sense_key == SSD_KEY_ILLEGAL_REQUEST)
1747 error = cmd6workaround(ccb);
1748 }
1749 if (error == ERESTART)
1750 return (ERESTART);
1751
1752 /*
1753 * XXX
1754 * Until we have a better way of doing pack validation,
1755 * don't treat UAs as errors.
1756 */
1757 sense_flags |= SF_RETRY_UA;
1758 return(cam_periph_error(ccb, cam_flags, sense_flags,
1759 &softc->saved_ccb));
1760 }
1761
1762 static void
1763 daprevent(struct cam_periph *periph, int action)
1764 {
1765 struct da_softc *softc;
1766 union ccb *ccb;
1767 int error;
1768
1769 softc = (struct da_softc *)periph->softc;
1770
1771 if (((action == PR_ALLOW)
1772 && (softc->flags & DA_FLAG_PACK_LOCKED) == 0)
1773 || ((action == PR_PREVENT)
1774 && (softc->flags & DA_FLAG_PACK_LOCKED) != 0)) {
1775 return;
1776 }
1777
1778 ccb = cam_periph_getccb(periph, /*priority*/1);
1779
1780 scsi_prevent(&ccb->csio,
1781 /*retries*/1,
1782 /*cbcfp*/dadone,
1783 MSG_SIMPLE_Q_TAG,
1784 action,
1785 SSD_FULL_SIZE,
1786 5000);
1787
1788 error = cam_periph_runccb(ccb, /*error_routine*/NULL, CAM_RETRY_SELTO,
1789 SF_RETRY_UA, softc->disk->d_devstat);
1790
1791 if (error == 0) {
1792 if (action == PR_ALLOW)
1793 softc->flags &= ~DA_FLAG_PACK_LOCKED;
1794 else
1795 softc->flags |= DA_FLAG_PACK_LOCKED;
1796 }
1797
1798 xpt_release_ccb(ccb);
1799 }
1800
1801 static int
1802 dagetcapacity(struct cam_periph *periph)
1803 {
1804 struct da_softc *softc;
1805 union ccb *ccb;
1806 struct scsi_read_capacity_data *rcap;
1807 struct scsi_read_capacity_data_long *rcaplong;
1808 uint32_t block_len;
1809 uint64_t maxsector;
1810 int error;
1811 u_int32_t sense_flags;
1812
1813 softc = (struct da_softc *)periph->softc;
1814 block_len = 0;
1815 maxsector = 0;
1816 error = 0;
1817 sense_flags = SF_RETRY_UA;
1818 if (softc->flags & DA_FLAG_PACK_REMOVABLE)
1819 sense_flags |= SF_NO_PRINT;
1820
1821 /* Do a read capacity */
1822 rcap = (struct scsi_read_capacity_data *)malloc(sizeof(*rcaplong),
1823 M_TEMP,
1824 M_WAITOK);
1825
1826 ccb = cam_periph_getccb(periph, /*priority*/1);
1827 scsi_read_capacity(&ccb->csio,
1828 /*retries*/4,
1829 /*cbfncp*/dadone,
1830 MSG_SIMPLE_Q_TAG,
1831 rcap,
1832 SSD_FULL_SIZE,
1833 /*timeout*/60000);
1834 ccb->ccb_h.ccb_bp = NULL;
1835
1836 error = cam_periph_runccb(ccb, daerror,
1837 /*cam_flags*/CAM_RETRY_SELTO,
1838 sense_flags,
1839 softc->disk->d_devstat);
1840
1841 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
1842 cam_release_devq(ccb->ccb_h.path,
1843 /*relsim_flags*/0,
1844 /*reduction*/0,
1845 /*timeout*/0,
1846 /*getcount_only*/0);
1847
1848 if (error == 0) {
1849 block_len = scsi_4btoul(rcap->length);
1850 maxsector = scsi_4btoul(rcap->addr);
1851
1852 if (maxsector != 0xffffffff)
1853 goto done;
1854 } else
1855 goto done;
1856
1857 rcaplong = (struct scsi_read_capacity_data_long *)rcap;
1858
1859 scsi_read_capacity_16(&ccb->csio,
1860 /*retries*/ 4,
1861 /*cbfcnp*/ dadone,
1862 /*tag_action*/ MSG_SIMPLE_Q_TAG,
1863 /*lba*/ 0,
1864 /*reladr*/ 0,
1865 /*pmi*/ 0,
1866 rcaplong,
1867 /*sense_len*/ SSD_FULL_SIZE,
1868 /*timeout*/ 60000);
1869 ccb->ccb_h.ccb_bp = NULL;
1870
1871 error = cam_periph_runccb(ccb, daerror,
1872 /*cam_flags*/CAM_RETRY_SELTO,
1873 sense_flags,
1874 softc->disk->d_devstat);
1875
1876 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
1877 cam_release_devq(ccb->ccb_h.path,
1878 /*relsim_flags*/0,
1879 /*reduction*/0,
1880 /*timeout*/0,
1881 /*getcount_only*/0);
1882
1883 if (error == 0) {
1884 block_len = scsi_4btoul(rcaplong->length);
1885 maxsector = scsi_8btou64(rcaplong->addr);
1886 }
1887
1888 done:
1889
1890 if (error == 0)
1891 dasetgeom(periph, block_len, maxsector);
1892
1893 xpt_release_ccb(ccb);
1894
1895 free(rcap, M_TEMP);
1896
1897 return (error);
1898 }
1899
1900 static void
1901 dasetgeom(struct cam_periph *periph, uint32_t block_len, uint64_t maxsector)
1902 {
1903 struct ccb_calc_geometry ccg;
1904 struct da_softc *softc;
1905 struct disk_params *dp;
1906
1907 softc = (struct da_softc *)periph->softc;
1908
1909 dp = &softc->params;
1910 dp->secsize = block_len;
1911 dp->sectors = maxsector + 1;
1912 /*
1913 * Have the controller provide us with a geometry
1914 * for this disk. The only time the geometry
1915 * matters is when we boot and the controller
1916 * is the only one knowledgeable enough to come
1917 * up with something that will make this a bootable
1918 * device.
1919 */
1920 xpt_setup_ccb(&ccg.ccb_h, periph->path, /*priority*/1);
1921 ccg.ccb_h.func_code = XPT_CALC_GEOMETRY;
1922 ccg.block_size = dp->secsize;
1923 ccg.volume_size = dp->sectors;
1924 ccg.heads = 0;
1925 ccg.secs_per_track = 0;
1926 ccg.cylinders = 0;
1927 xpt_action((union ccb*)&ccg);
1928 if ((ccg.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1929 /*
1930 * We don't know what went wrong here- but just pick
1931 * a geometry so we don't have nasty things like divide
1932 * by zero.
1933 */
1934 dp->heads = 255;
1935 dp->secs_per_track = 255;
1936 dp->cylinders = dp->sectors / (255 * 255);
1937 if (dp->cylinders == 0) {
1938 dp->cylinders = 1;
1939 }
1940 } else {
1941 dp->heads = ccg.heads;
1942 dp->secs_per_track = ccg.secs_per_track;
1943 dp->cylinders = ccg.cylinders;
1944 }
1945 }
1946
1947 static void
1948 dasendorderedtag(void *arg)
1949 {
1950 struct da_softc *softc;
1951 int s;
1952 if (da_send_ordered) {
1953 for (softc = SLIST_FIRST(&softc_list);
1954 softc != NULL;
1955 softc = SLIST_NEXT(softc, links)) {
1956 s = splsoftcam();
1957 if ((softc->ordered_tag_count == 0)
1958 && ((softc->flags & DA_FLAG_WENT_IDLE) == 0)) {
1959 softc->flags |= DA_FLAG_NEED_OTAG;
1960 }
1961 if (softc->outstanding_cmds > 0)
1962 softc->flags &= ~DA_FLAG_WENT_IDLE;
1963
1964 softc->ordered_tag_count = 0;
1965 splx(s);
1966 }
1967 /* Queue us up again */
1968 timeout(dasendorderedtag, NULL,
1969 (da_default_timeout * hz) / DA_ORDEREDTAG_INTERVAL);
1970 }
1971 }
1972
1973 /*
1974 * Step through all DA peripheral drivers, and if the device is still open,
1975 * sync the disk cache to physical media.
1976 */
1977 static void
1978 dashutdown(void * arg, int howto)
1979 {
1980 struct cam_periph *periph;
1981 struct da_softc *softc;
1982
1983 TAILQ_FOREACH(periph, &dadriver.units, unit_links) {
1984 union ccb ccb;
1985 softc = (struct da_softc *)periph->softc;
1986
1987 /*
1988 * We only sync the cache if the drive is still open, and
1989 * if the drive is capable of it..
1990 */
1991 if (((softc->flags & DA_FLAG_OPEN) == 0)
1992 || (softc->quirks & DA_Q_NO_SYNC_CACHE))
1993 continue;
1994
1995 xpt_setup_ccb(&ccb.ccb_h, periph->path, /*priority*/1);
1996
1997 ccb.ccb_h.ccb_state = DA_CCB_DUMP;
1998 scsi_synchronize_cache(&ccb.csio,
1999 /*retries*/1,
2000 /*cbfcnp*/dadone,
2001 MSG_SIMPLE_Q_TAG,
2002 /*begin_lba*/0, /* whole disk */
2003 /*lb_count*/0,
2004 SSD_FULL_SIZE,
2005 60 * 60 * 1000);
2006
2007 xpt_polled_action(&ccb);
2008
2009 if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2010 if (((ccb.ccb_h.status & CAM_STATUS_MASK) ==
2011 CAM_SCSI_STATUS_ERROR)
2012 && (ccb.csio.scsi_status == SCSI_STATUS_CHECK_COND)){
2013 int error_code, sense_key, asc, ascq;
2014
2015 scsi_extract_sense(&ccb.csio.sense_data,
2016 &error_code, &sense_key,
2017 &asc, &ascq);
2018
2019 if (sense_key != SSD_KEY_ILLEGAL_REQUEST)
2020 scsi_sense_print(&ccb.csio);
2021 } else {
2022 xpt_print_path(periph->path);
2023 printf("Synchronize cache failed, status "
2024 "== 0x%x, scsi status == 0x%x\n",
2025 ccb.ccb_h.status, ccb.csio.scsi_status);
2026 }
2027 }
2028
2029 if ((ccb.ccb_h.status & CAM_DEV_QFRZN) != 0)
2030 cam_release_devq(ccb.ccb_h.path,
2031 /*relsim_flags*/0,
2032 /*reduction*/0,
2033 /*timeout*/0,
2034 /*getcount_only*/0);
2035
2036 }
2037 }
2038
2039 #else /* !_KERNEL */
2040
2041 /*
2042 * XXX This is only left out of the kernel build to silence warnings. If,
2043 * for some reason this function is used in the kernel, the ifdefs should
2044 * be moved so it is included both in the kernel and userland.
2045 */
2046 void
2047 scsi_format_unit(struct ccb_scsiio *csio, u_int32_t retries,
2048 void (*cbfcnp)(struct cam_periph *, union ccb *),
2049 u_int8_t tag_action, u_int8_t byte2, u_int16_t ileave,
2050 u_int8_t *data_ptr, u_int32_t dxfer_len, u_int8_t sense_len,
2051 u_int32_t timeout)
2052 {
2053 struct scsi_format_unit *scsi_cmd;
2054
2055 scsi_cmd = (struct scsi_format_unit *)&csio->cdb_io.cdb_bytes;
2056 scsi_cmd->opcode = FORMAT_UNIT;
2057 scsi_cmd->byte2 = byte2;
2058 scsi_ulto2b(ileave, scsi_cmd->interleave);
2059
2060 cam_fill_csio(csio,
2061 retries,
2062 cbfcnp,
2063 /*flags*/ (dxfer_len > 0) ? CAM_DIR_OUT : CAM_DIR_NONE,
2064 tag_action,
2065 data_ptr,
2066 dxfer_len,
2067 sense_len,
2068 sizeof(*scsi_cmd),
2069 timeout);
2070 }
2071
2072 #endif /* _KERNEL */
Cache object: 839ab6ebc2568e8ee5fcad7b1370b0e8
|