FreeBSD/Linux Kernel Cross Reference
sys/scsi/scsi_disk.c
1 /*
2 * Mach Operating System
3 * Copyright (c) 1991,1990 Carnegie Mellon University
4 * All Rights Reserved.
5 *
6 * Permission to use, copy, modify and distribute this software and its
7 * documentation is hereby granted, provided that both the copyright
8 * notice and this permission notice appear in all copies of the
9 * software, derivative works or modified versions, and any portions
10 * thereof, and that both notices appear in supporting documentation.
11 *
12 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15 *
16 * Carnegie Mellon requests users of this software to return to
17 *
18 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
19 * School of Computer Science
20 * Carnegie Mellon University
21 * Pittsburgh PA 15213-3890
22 *
23 * any improvements or extensions that they make and grant Carnegie Mellon
24 * the rights to redistribute these changes.
25 */
26 /*
27 * HISTORY
28 * $Log: scsi_disk.c,v $
29 * Revision 2.15 93/05/10 21:23:10 rvb
30 * Remove depends on DEV_BSIZE.
31 * [93/05/06 10:06:25 af]
32 *
33 * Revision 2.14 92/08/03 17:55:04 jfriedl
34 * removed silly prototypes
35 * [92/08/02 jfriedl]
36 *
37 * Revision 2.13 92/05/21 17:24:34 jfriedl
38 * Cleanup to quiet gcc warnings. Remove unused local variables.
39 * [92/05/20 jfriedl]
40 *
41 * Revision 2.12 92/02/23 22:44:59 elf
42 * Changed the interface of a number of functions not to
43 * require the scsi_softc pointer any longer. It was
44 * mostly unused, now it can be found via tgt->masterno.
45 * [92/02/22 19:29:26 af]
46 *
47 * Revision 2.11 91/08/24 12:29:08 af
48 * Bcopy casts.
49 *
50 * Revision 2.10 91/06/19 11:57:47 rvb
51 * File moved here from mips/PMAX since it is now "MI" code, also
52 * used by Vax3100 and soon -- the omron luna88k.
53 * [91/06/04 rvb]
54 *
55 * Revision 2.9 91/05/14 17:30:28 mrt
56 * Correcting copyright
57 *
58 * Revision 2.8 91/05/13 06:05:40 af
59 * Enabled some group-1 commands needed on big disks.
60 * Wrote all those that were missing, kept disabled until
61 * we find a use for them (via ioctls, I am afraid).
62 * [91/05/12 16:24:35 af]
63 *
64 * Revision 2.7.1.1 91/03/29 17:13:10 af
65 * Enabled some group-1 commands needed on big disks.
66 * Wrote all those that were missing, kept disabled until
67 * we find a use for them (via ioctls, I am afraid).
68 *
69 * Revision 2.7 91/02/05 17:45:49 mrt
70 * Added author notices
71 * [91/02/04 11:19:35 mrt]
72 *
73 * Changed to use new Mach copyright
74 * [91/02/02 12:18:21 mrt]
75 *
76 * Revision 2.6 90/12/05 23:35:14 af
77 * Use and prefer BSD/OSF labels.
78 * [90/12/03 23:48:09 af]
79 *
80 * Revision 2.4.1.1 90/11/01 03:39:58 af
81 * Created, from the SCSI specs:
82 * "Small Computer Systems Interface (SCSI)", ANSI Draft
83 * X3T9.2/82-2 - Rev 17B December 1985
84 * "Small Computer System Interface - 2 (SCSI-II)", ANSI Draft
85 * X3T9.2/86-109 - Rev 10C March 1990
86 * [90/10/11 af]
87 */
88 /*
89 * File: scsi_disk.c
90 * Author: Alessandro Forin, Carnegie Mellon University
91 * Date: 10/90
92 *
93 * Middle layer of the SCSI driver: SCSI protocol implementation
94 *
95 * This file contains code for SCSI commands for DISK devices.
96 */
97
98 #include <mach/std_types.h>
99 #include <scsi/compat_30.h>
100
101 #include <scsi/scsi.h>
102 #include <scsi/scsi2.h>
103 #include <scsi/scsi_defs.h>
104
105
106
107
108 char *scdisk_name(internal)
109 boolean_t internal;
110 {
111 return internal ? "rz" : "disk";
112 }
113
114 /*
115 * SCSI commands partially specific to disks
116 */
117 void scdisk_read( tgt, secno, ior)
118 register target_info_t *tgt;
119 register unsigned int secno;
120 io_req_t ior;
121 {
122 scsi_cmd_read_t *cmd;
123 register unsigned len;
124 unsigned int max_dma_data;
125
126 max_dma_data = scsi_softc[(unsigned char)tgt->masterno]->max_dma_data;
127
128 len = ior->io_count;
129 if (len > max_dma_data)
130 len = max_dma_data;
131 if (len < tgt->block_size)
132 len = tgt->block_size;
133
134 cmd = (scsi_cmd_read_t*) (tgt->cmd_ptr);
135 cmd->scsi_cmd_code = SCSI_CMD_READ;
136 cmd->scsi_cmd_lun_and_lba1 = (secno>>16)&SCSI_LBA_MASK;
137 cmd->scsi_cmd_lba2 = (secno>> 8)&0xff;
138 cmd->scsi_cmd_lba3 = (secno )&0xff;
139 cmd->scsi_cmd_xfer_len = len / tgt->block_size;
140 cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
141
142 tgt->cur_cmd = SCSI_CMD_READ;
143
144 scsi_go(tgt, sizeof(*cmd), len, FALSE);
145 }
146
147 void scdisk_write( tgt, secno, ior)
148 register target_info_t *tgt;
149 register unsigned int secno;
150 io_req_t ior;
151 {
152 scsi_cmd_write_t *cmd;
153 unsigned len; /* in bytes */
154 unsigned int max_dma_data;
155
156 max_dma_data = scsi_softc[(unsigned char)tgt->masterno]->max_dma_data;
157
158 len = ior->io_count;
159 if (len > max_dma_data)
160 len = max_dma_data;
161 if (len < tgt->block_size)
162 len = tgt->block_size;
163
164 cmd = (scsi_cmd_write_t*) (tgt->cmd_ptr);
165 cmd->scsi_cmd_code = SCSI_CMD_WRITE;
166 cmd->scsi_cmd_lun_and_lba1 = (secno>>16)&SCSI_LBA_MASK;
167 cmd->scsi_cmd_lba2 = (secno>> 8)&0xff;
168 cmd->scsi_cmd_lba3 = (secno )&0xff;
169 cmd->scsi_cmd_xfer_len = len / tgt->block_size;
170 cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
171
172 tgt->cur_cmd = SCSI_CMD_WRITE;
173
174 scsi_go(tgt, sizeof(*cmd), 0, FALSE);
175 }
176
177
178 int scdisk_mode_select(tgt, lbn, ior, mdata, mlen, save)
179 register target_info_t *tgt;
180 register int lbn;
181 io_req_t ior;
182 char *mdata;
183 int mlen, save;
184 {
185 scsi_cmd_mode_select_t *cmd;
186 scsi_mode_select_param_t *parm;
187
188 bzero(tgt->cmd_ptr, sizeof(*cmd) + sizeof(*parm));
189 cmd = (scsi_cmd_mode_select_t*) (tgt->cmd_ptr);
190 cmd->scsi_cmd_code = SCSI_CMD_MODE_SELECT;
191 cmd->scsi_cmd_lun_and_lba1 = SCSI_CMD_MSL_PF; /* XXX only if... */
192 cmd->scsi_cmd_xfer_len = sizeof(scsi_mode_select_param_t);/* no vuq */
193
194 parm = (scsi_mode_select_param_t*) (cmd + 1);
195 if (mdata) {
196 cmd->scsi_cmd_xfer_len = mlen;
197 bcopy(mdata, (char*)parm, mlen);
198 if (save)
199 cmd->scsi_cmd_lun_and_lba1 |= SCSI_CMD_MSL_SP;
200 } else {
201 /* parm->medium_type = if (floppy)disk.. */
202 parm->desc_len = 8;
203 /* this really is the LBN */
204 parm->descs[0].density_code = 0;/* XXX default XXX */
205 parm->descs[0].reclen1 = (lbn>>16)&0xff;
206 parm->descs[0].reclen2 = (lbn>> 8)&0xff;
207 parm->descs[0].reclen3 = (lbn )&0xff;
208 mlen = sizeof(*parm);
209 }
210
211 tgt->cur_cmd = SCSI_CMD_MODE_SELECT;
212
213 scsi_go_and_wait(tgt, sizeof(*cmd) + mlen, 0, ior);
214
215 return tgt->done;
216 }
217
218 /*
219 * SCSI commands fully specific to disks
220 */
221 int scsi_read_capacity( tgt, lbn, ior)
222 register target_info_t *tgt;
223 int lbn;
224 io_req_t ior;
225 {
226 scsi_cmd_read_capacity_t *cmd;
227
228 bzero(tgt->cmd_ptr, sizeof(*cmd));
229 cmd = (scsi_cmd_read_capacity_t*) (tgt->cmd_ptr);
230 cmd->scsi_cmd_code = SCSI_CMD_READ_CAPACITY;
231 /* all zeroes, unless... */
232 if (lbn) {
233 cmd->scsi_cmd_rcap_flags = SCSI_CMD_RCAP_PMI;
234 cmd->scsi_cmd_lba1 = (lbn>>24);
235 cmd->scsi_cmd_lba2 = (lbn>>16)&0xff;
236 cmd->scsi_cmd_lba3 = (lbn>> 8)&0xff;
237 cmd->scsi_cmd_lba4 = (lbn )&0xff;
238 }
239
240 tgt->cur_cmd = SCSI_CMD_READ_CAPACITY;
241
242 scsi_go_and_wait(tgt, sizeof(*cmd), sizeof(scsi_rcap_data_t),ior);
243
244 return tgt->done;
245 }
246
247 void scsi_reassign_blocks( tgt, defect_list, n_defects, ior)
248 register target_info_t *tgt;
249 unsigned int *defect_list; /* In ascending order ! */
250 int n_defects;
251 io_req_t ior;
252 {
253 scsi_cmd_reassign_blocks_t *cmd;
254 scsi_Ldefect_data_t *parm;
255
256 cmd = (scsi_cmd_reassign_blocks_t*) (tgt->cmd_ptr);
257 cmd->scsi_cmd_code = SCSI_CMD_REASSIGN_BLOCKS;
258 cmd->scsi_cmd_lun_and_lba1 = 0;
259 cmd->scsi_cmd_lba2 = 0;
260 cmd->scsi_cmd_lba3 = 0;
261 cmd->scsi_cmd_xfer_len = 0;
262 cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
263
264 parm = (scsi_Ldefect_data_t *) (cmd + 1);
265 parm->res1 = parm->res2 = 0;
266 n_defects *= 4; /* in 4-byte-ints */
267 parm->list_len_msb = n_defects >> 8;
268 parm->list_len_lsb = n_defects;
269 bcopy((char*)defect_list, (char*)parm->defects, n_defects);
270
271 tgt->cur_cmd = SCSI_CMD_REASSIGN_BLOCKS;
272
273 scsi_go(tgt, sizeof(*cmd) + sizeof(*parm) + (n_defects - 4), 0, FALSE);
274 }
275
276 void scsi_medium_removal( tgt, allow, ior)
277 register target_info_t *tgt;
278 boolean_t allow;
279 io_req_t ior;
280 {
281 scsi_cmd_medium_removal_t *cmd;
282
283 cmd = (scsi_cmd_medium_removal_t*) (tgt->cmd_ptr);
284 cmd->scsi_cmd_code = SCSI_CMD_PREVENT_ALLOW_REMOVAL;
285 cmd->scsi_cmd_lun_and_lba1 = 0;
286 cmd->scsi_cmd_lba2 = 0;
287 cmd->scsi_cmd_lba3 = 0;
288 cmd->scsi_cmd_pa_prevent = allow ? 0 : 1;
289 cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
290
291
292 tgt->cur_cmd = SCSI_CMD_PREVENT_ALLOW_REMOVAL;
293
294 scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
295 }
296
297 int scsi_format_unit( tgt, mode, vuqe, intlv, ior)
298 register target_info_t *tgt;
299 int mode, vuqe;
300 register unsigned int intlv;
301 io_req_t ior;
302 {
303 scsi_cmd_format_t *cmd;
304 char *parms;
305
306 cmd = (scsi_cmd_format_t*) (tgt->cmd_ptr);
307 cmd->scsi_cmd_code = SCSI_CMD_FORMAT_UNIT;
308 cmd->scsi_cmd_lun_and_lba1 =
309 mode & (SCSI_CMD_FMT_FMTDATA|SCSI_CMD_FMT_CMPLIST|SCSI_CMD_FMT_LIST_TYPE);
310 cmd->scsi_cmd_lba2 = vuqe;
311 cmd->scsi_cmd_lba3 = intlv >> 8;
312 cmd->scsi_cmd_xfer_len = intlv;
313 cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
314
315 parms = (char*) cmd + 1;
316 if (ior->io_count)
317 bcopy(ior->io_data, parms, ior->io_count);
318 else
319 bzero(parms, 0xff - sizeof(*cmd));
320
321 tgt->cur_cmd = SCSI_CMD_FORMAT_UNIT;
322
323 scsi_go_and_wait(tgt, sizeof(*cmd) + ior->io_count, 0, ior);
324 return tgt->done;
325 }
326
327
328 /* Group 1 Commands */
329
330 void scsi_long_read( tgt, secno, ior)
331 register target_info_t *tgt;
332 register unsigned int secno;
333 io_req_t ior;
334 {
335 scsi_cmd_long_read_t *cmd;
336 register unsigned len, n_blks;
337 unsigned int max_dma_data;
338
339 max_dma_data = scsi_softc[(unsigned char)tgt->masterno]->max_dma_data;
340
341 len = ior->io_count;
342 if (len > max_dma_data)
343 len = max_dma_data;
344 if (len < tgt->block_size)
345 len = tgt->block_size;
346 n_blks = len /tgt->block_size;
347
348 cmd = (scsi_cmd_long_read_t*) (tgt->cmd_ptr);
349 cmd->scsi_cmd_code = SCSI_CMD_LONG_READ;
350 cmd->scsi_cmd_lun_and_relbit = 0;
351 cmd->scsi_cmd_lba1 = secno >> 24;
352 cmd->scsi_cmd_lba2 = secno >> 16;
353 cmd->scsi_cmd_lba3 = secno >> 8;
354 cmd->scsi_cmd_lba4 = secno;
355 cmd->scsi_cmd_xxx = 0;
356 cmd->scsi_cmd_xfer_len_1 = n_blks >> 8;
357 cmd->scsi_cmd_xfer_len_2 = n_blks;
358 cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
359
360 tgt->cur_cmd = SCSI_CMD_LONG_READ;
361
362 scsi_go(tgt, sizeof(*cmd), len, FALSE);
363 }
364
365 void scsi_long_write( tgt, secno, ior)
366 register target_info_t *tgt;
367 register unsigned int secno;
368 io_req_t ior;
369 {
370 scsi_cmd_long_write_t *cmd;
371 unsigned len; /* in bytes */
372 unsigned int max_dma_data, n_blks;
373
374 max_dma_data = scsi_softc[(unsigned char)tgt->masterno]->max_dma_data;
375
376 len = ior->io_count;
377 if (len > max_dma_data)
378 len = max_dma_data;
379 if (len < tgt->block_size)
380 len = tgt->block_size;
381 n_blks = len /tgt->block_size;
382
383 cmd = (scsi_cmd_long_write_t*) (tgt->cmd_ptr);
384 cmd->scsi_cmd_code = SCSI_CMD_LONG_WRITE;
385 cmd->scsi_cmd_lun_and_relbit = 0;
386 cmd->scsi_cmd_lba1 = secno >> 24;
387 cmd->scsi_cmd_lba2 = secno >> 16;
388 cmd->scsi_cmd_lba3 = secno >> 8;
389 cmd->scsi_cmd_lba4 = secno;
390 cmd->scsi_cmd_xxx = 0;
391 cmd->scsi_cmd_xfer_len_1 = n_blks >> 8;
392 cmd->scsi_cmd_xfer_len_2 = n_blks;
393 cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
394
395 tgt->cur_cmd = SCSI_CMD_LONG_WRITE;
396
397 scsi_go(tgt, sizeof(*cmd), 0, FALSE);
398 }
399
400 int scdisk_verify( tgt, secno, nsectrs, ior)
401 register target_info_t *tgt;
402 int secno, nsectrs;
403 io_req_t ior;
404 {
405 scsi_cmd_verify_long_t *cmd;
406 int len;
407
408 len = ior->io_count;
409
410 cmd = (scsi_cmd_verify_long_t*) (tgt->cmd_ptr);
411 cmd->scsi_cmd_code = SCSI_CMD_VERIFY_1;
412 cmd->scsi_cmd_lun_and_relbit = len ? SCSI_CMD_VFY_BYTCHK : 0;
413 cmd->scsi_cmd_lba1 = secno >> 24;
414 cmd->scsi_cmd_lba2 = secno >> 16;
415 cmd->scsi_cmd_lba3 = secno >> 8;
416 cmd->scsi_cmd_lba4 = secno;
417 cmd->scsi_cmd_xxx = 0;
418 cmd->scsi_cmd_xfer_len_1 = (nsectrs) >> 8;
419 cmd->scsi_cmd_xfer_len_2 = nsectrs;
420 cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
421
422 tgt->cur_cmd = SCSI_CMD_VERIFY_1;
423
424 scsi_go_and_wait(tgt, sizeof(*cmd) + len, 0, ior);
425 return tgt->done;
426 }
427
428
429 int scsi_read_defect( tgt, mode, ior)
430 register target_info_t *tgt;
431 register unsigned int mode;
432 io_req_t ior;
433 {
434 scsi_cmd_long_read_t *cmd;
435 register unsigned len;
436
437 len = ior->io_count;
438 if (len > 0xffff)
439 len = 0xffff;
440
441 cmd = (scsi_cmd_read_defect_t*) (tgt->cmd_ptr);
442 cmd->scsi_cmd_code = SCSI_CMD_READ_DEFECT_DATA;
443 cmd->scsi_cmd_lun_and_relbit = 0;
444 cmd->scsi_cmd_lba1 = mode & 0x1f;
445 cmd->scsi_cmd_lba2 = 0;
446 cmd->scsi_cmd_lba3 = 0;
447 cmd->scsi_cmd_lba4 = 0;
448 cmd->scsi_cmd_xxx = 0;
449 cmd->scsi_cmd_xfer_len_1 = (len) >> 8;
450 cmd->scsi_cmd_xfer_len_2 = (len);
451 cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
452
453 /* ++ HACK Alert */
454 /* tgt->cur_cmd = SCSI_CMD_READ_DEFECT_DATA;*/
455 tgt->cur_cmd = SCSI_CMD_LONG_READ;
456 /* -- HACK Alert */
457
458 scsi_go(tgt, sizeof(*cmd), len, FALSE);
459 iowait(ior);
460 return tgt->done;
461 }
462
463
464 #if 0 /* unused commands */
465 scsi_rezero_unit( tgt, ior)
466 register target_info_t *tgt;
467 io_req_t ior;
468 {
469 scsi_cmd_rezero_t *cmd;
470
471 cmd = (scsi_cmd_rezero_t*) (tgt->cmd_ptr);
472 cmd->scsi_cmd_code = SCSI_CMD_REZERO_UNIT;
473 cmd->scsi_cmd_lun_and_lba1 = 0;
474 cmd->scsi_cmd_lba2 = 0;
475 cmd->scsi_cmd_lba3 = 0;
476 cmd->scsi_cmd_xfer_len = 0;
477 cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
478
479
480 tgt->cur_cmd = SCSI_CMD_REZERO_UNIT;
481
482 scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
483
484 }
485
486 scsi_seek( tgt, where, ior)
487 register target_info_t *tgt;
488 register unsigned int where;
489 io_req_t ior;
490 {
491 scsi_cmd_seek_t *cmd;
492
493 cmd = (scsi_cmd_seek_t*) (tgt->cmd_ptr);
494 cmd->scsi_cmd_code = SCSI_CMD_SEEK;
495 cmd->scsi_cmd_lun_and_lba1 = (where >> 16) & 0x1f;
496 cmd->scsi_cmd_lba2 = where >> 8;
497 cmd->scsi_cmd_lba3 = where;
498 cmd->scsi_cmd_xfer_len = 0;
499 cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
500
501
502 tgt->cur_cmd = SCSI_CMD_SEEK;
503
504 scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
505
506 }
507
508 scsi_reserve( tgt, len, id, mode, ior)
509 register target_info_t *tgt;
510 register unsigned int len;
511 unsigned char id;
512 io_req_t ior;
513 {
514 scsi_cmd_reserve_t *cmd;
515
516 cmd = (scsi_cmd_reserve_t*) (tgt->cmd_ptr);
517 cmd->scsi_cmd_code = SCSI_CMD_RESERVE;
518 cmd->scsi_cmd_lun_and_lba1 = mode & 0x1f;
519 cmd->scsi_cmd_reserve_id = id;
520 cmd->scsi_cmd_extent_llen1 = len >> 8;
521 cmd->scsi_cmd_extent_llen2 = len;
522 cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
523
524
525 tgt->cur_cmd = SCSI_CMD_RESERVE;
526
527 scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
528
529 }
530
531 scsi_release( tgt, id, mode, ior)
532 register target_info_t *tgt;
533 unsigned char id, mode;
534 io_req_t ior;
535 {
536 scsi_cmd_release_t *cmd;
537
538 cmd = (scsi_cmd_release_t*) (tgt->cmd_ptr);
539 cmd->scsi_cmd_code = SCSI_CMD_RELEASE;
540 cmd->scsi_cmd_lun_and_lba1 = mode & 0x1f;
541 cmd->scsi_cmd_reserve_id = id;
542 cmd->scsi_cmd_lba3 = 0;
543 cmd->scsi_cmd_xfer_len = 0;
544 cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
545
546
547 tgt->cur_cmd = SCSI_CMD_RELEASE;
548
549 scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
550
551 }
552
553
554 /* Group 1 Commands */
555
556 scsi_long_seek( tgt, secno, ior)
557 register target_info_t *tgt;
558 io_req_t ior;
559 {
560 scsi_cmd_long_seek_t *cmd;
561
562 cmd = (scsi_cmd_long_seek_t*) (tgt->cmd_ptr);
563 cmd->scsi_cmd_code = SCSI_CMD_LONG_SEEK;
564 cmd->scsi_cmd_lun_and_relbit = 0;
565 cmd->scsi_cmd_lba1 = secno >> 24;
566 cmd->scsi_cmd_lba2 = secno >> 16;
567 cmd->scsi_cmd_lba3 = secno >> 8;
568 cmd->scsi_cmd_lba4 = secno;
569 cmd->scsi_cmd_xxx = 0;
570 cmd->scsi_cmd_xfer_len_1 = 0;
571 cmd->scsi_cmd_xfer_len_2 = 0;
572 cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
573
574 tgt->cur_cmd = SCSI_CMD_LONG_SEEK;
575
576 scsi_go(tgt, sizeof(*cmd), 0, FALSE);
577 }
578
579 scsi_write_verify( tgt, secno, ior)
580 register target_info_t *tgt;
581 io_req_t ior;
582 {
583 scsi_cmd_write_vfy_t *cmd;
584 unsigned len; /* in bytes */
585 unsigned int max_dma_data, n_blks;
586
587 max_dma_data = scsi_softc[(unsigned char)tgt->masterno]->max_dma_data;
588
589 len = ior->io_count;
590 if (len > max_dma_data)
591 len = max_dma_data;
592 if (len < tgt->block_size)
593 len = tgt->block_size;
594 n_blks = len / tgt->block_size;
595
596 cmd = (scsi_cmd_write_vfy_t*) (tgt->cmd_ptr);
597 cmd->scsi_cmd_code = SCSI_CMD_WRITE_AND_VERIFY;
598 cmd->scsi_cmd_lun_and_relbit = SCSI_CMD_VFY_BYTCHK;
599 cmd->scsi_cmd_lba1 = secno >> 24;
600 cmd->scsi_cmd_lba2 = secno >> 16;
601 cmd->scsi_cmd_lba3 = secno >> 8;
602 cmd->scsi_cmd_lba4 = secno;
603 cmd->scsi_cmd_xxx = 0;
604 cmd->scsi_cmd_xfer_len_1 = n_blks >> 8;
605 cmd->scsi_cmd_xfer_len_2 = n_blks;
606 cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
607
608 tgt->cur_cmd = SCSI_CMD_WRITE_AND_VERIFY;
609
610 scsi_go(tgt, sizeof(*cmd), 0, FALSE);
611 }
612
613 scsi_search_data( tgt, secno, how, flags, ior)
614 register target_info_t *tgt;
615 io_req_t ior;
616 {
617 scsi_cmd_search_t *cmd;
618 unsigned len; /* in bytes */
619 unsigned int max_dma_data, n_blks;
620
621 max_dma_data = scsi_softc[(unsigned char)tgt->masterno]->max_dma_data;
622
623 if (how != SCSI_CMD_SEARCH_HIGH &&
624 how != SCSI_CMD_SEARCH_EQUAL &&
625 how != SCSI_CMD_SEARCH_LOW)
626 panic("scsi_search_data");
627
628 len = ior->io_count;
629 if (len > max_dma_data)
630 len = max_dma_data;
631 n_blks = len / tgt->block_size;
632
633 cmd = (scsi_cmd_search_t*) (tgt->cmd_ptr);
634 cmd->scsi_cmd_code = how;
635 cmd->scsi_cmd_lun_and_relbit = flags & 0x1e;
636 cmd->scsi_cmd_lba1 = secno >> 24;
637 cmd->scsi_cmd_lba2 = secno >> 16;
638 cmd->scsi_cmd_lba3 = secno >> 8;
639 cmd->scsi_cmd_lba4 = secno;
640 cmd->scsi_cmd_xxx = 0;
641 cmd->scsi_cmd_xfer_len_1 = n_blks >> 8;
642 cmd->scsi_cmd_xfer_len_2 = n_blks;
643 cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
644
645 tgt->cur_cmd = how;
646
647 scsi_go(tgt, sizeof(*cmd), 0, FALSE);
648 }
649
650
651 scsi_set_limits( tgt, secno, nblocks, inhibit, ior)
652 register target_info_t *tgt;
653 io_req_t ior;
654 {
655 scsi_cmd_set_limits_t *cmd;
656
657 cmd = (scsi_cmd_set_limits_t*) (tgt->cmd_ptr);
658 cmd->scsi_cmd_code = SCSI_CMD_SET_LIMITS;
659 cmd->scsi_cmd_lun_and_relbit = inhibit & 0x3;
660 cmd->scsi_cmd_lba1 = secno >> 24;
661 cmd->scsi_cmd_lba2 = secno >> 16;
662 cmd->scsi_cmd_lba3 = secno >> 8;
663 cmd->scsi_cmd_lba4 = secno;
664 cmd->scsi_cmd_xxx = 0;
665 cmd->scsi_cmd_xfer_len_1 = nblocks >> 8;
666 cmd->scsi_cmd_xfer_len_2 = nblocks;
667 cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
668
669 tgt->cur_cmd = SCSI_CMD_SET_LIMITS;
670
671 scsi_go(tgt, sizeof(*cmd), 0, FALSE);
672 }
673
674
675 #endif
676
677 #ifdef SCSI2
678 scsi_lock_cache
679 scsi_prefetch
680 scsi_read_defect_data
681 scsi_sync_cache
682 scsi_write_same
683 #endif SCSI2
Cache object: c2332b3ca807d4d3e3ad24370363f873
|