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