fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
1/*****************************************************************************
2 * pce *
3 *****************************************************************************/
4
5/*****************************************************************************
6 * File name: src/arch/macplus/scsi.c *
7 * Created: 2007-11-13 by Hampa Hug <hampa@hampa.ch> *
8 * Copyright: (C) 2007-2014 Hampa Hug <hampa@hampa.ch> *
9 *****************************************************************************/
10
11/*****************************************************************************
12 * This program is free software. You can redistribute it and / or modify it *
13 * under the terms of the GNU General Public License version 2 as published *
14 * by the Free Software Foundation. *
15 * *
16 * This program is distributed in the hope that it will be useful, but *
17 * WITHOUT ANY WARRANTY, without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General *
19 * Public License for more details. *
20 *****************************************************************************/
21
22
23#include "main.h"
24#include "scsi.h"
25
26#include <stdlib.h>
27#include <string.h>
28
29#include <devices/memory.h>
30
31#include <drivers/block/block.h>
32
33#include <lib/log.h>
34
35
36/* ICR 1 */
37#define E5380_ICR_RST 0x80
38#define E5380_ICR_AIP 0x40
39#define E5380_ICR_LA 0x20
40#define E5380_ICR_ACK 0x10
41#define E5380_ICR_BSY 0x08
42#define E5380_ICR_SEL 0x04
43#define E5380_ICR_ATN 0x02
44#define E5380_ICR_DBUS 0x01
45
46/* MR2 2 */
47#define E5380_MR2_BLK 0x80
48#define E5380_MR2_TARG 0x40
49#define E5380_MR2_PCHK 0x20
50#define E5380_MR2_PINT 0x10
51#define E5380_MR2_EOP 0x08
52#define E5380_MR2_BSY 0x04
53#define E5380_MR2_DMA 0x02
54#define E5380_MR2_ARB 0x01
55
56/* TCR 3 */
57#define E5380_TCR_REQ 0x08
58#define E5380_TCR_MSG 0x04
59#define E5380_TCR_CD 0x02
60#define E5380_TCR_IO 0x01
61
62/* CSB 4 */
63#define E5380_CSB_RST 0x80
64#define E5380_CSB_BSY 0x40
65#define E5380_CSB_REQ 0x20
66#define E5380_CSB_MSG 0x10
67#define E5380_CSB_CD 0x08
68#define E5380_CSB_IO 0x04
69#define E5380_CSB_SEL 0x02
70#define E5380_CSB_DBP 0x01
71
72/* BSR 5 */
73#define E5380_BSR_EDMA 0x80
74#define E5380_BSR_DRQ 0x40
75#define E5380_BSR_SPER 0x20
76#define E5380_BSR_INT 0x10
77#define E5380_BSR_PHSM 0x08
78#define E5380_BSR_BSY 0x04
79#define E5380_BSR_ATN 0x02
80#define E5380_BSR_ACK 0x01
81
82#define E5380_PHASE_FREE 0
83#define E5380_PHASE_ARB 1
84#define E5380_PHASE_SEL 2
85#define E5380_PHASE_MSG_OUT 3
86#define E5380_PHASE_CMD 4
87#define E5380_PHASE_DATA_IN 5
88#define E5380_PHASE_DATA_OUT 6
89#define E5380_PHASE_STATUS 7
90#define E5380_PHASE_MSG_IN 8
91
92
93void mac_scsi_init (mac_scsi_t *scsi)
94{
95 unsigned i;
96
97 scsi->phase = E5380_PHASE_FREE;
98
99 scsi->odr = 0x00;
100 scsi->csd = 0x00;
101 scsi->icr = 0x00;
102 scsi->mr2 = 0x00;
103 scsi->csb = 0x00;
104 scsi->ser = 0x00;
105 scsi->bsr = 0x00;
106
107 scsi->cmd_i = 0;
108 scsi->cmd_n = 0;
109
110 scsi->buf_i = 0;
111 scsi->buf_n = 0;
112 scsi->buf_max = 4096;
113 scsi->buf = malloc (scsi->buf_max);
114
115 scsi->addr_mask = 0xff0;
116 scsi->addr_shift = 4;
117
118 scsi->cmd_start = NULL;
119 scsi->cmd_finish = NULL;
120
121 scsi->set_int_val = 0;
122 scsi->set_int_ext = NULL;
123 scsi->set_int = NULL;
124
125 for (i = 0; i < 8; i++) {
126 scsi->dev[i].valid = 0;
127 }
128
129 scsi->dsks = NULL;
130}
131
132void mac_scsi_free (mac_scsi_t *scsi)
133{
134 free (scsi->buf);
135}
136
137void mac_scsi_set_int_fct (mac_scsi_t *scsi, void *ext, void *fct)
138{
139 scsi->set_int_ext = ext;
140 scsi->set_int = fct;
141}
142
143void mac_scsi_set_disks (mac_scsi_t *scsi, disks_t *dsks)
144{
145 scsi->dsks = dsks;
146}
147
148void mac_scsi_set_drive (mac_scsi_t *scsi, unsigned id, unsigned drive)
149{
150 id &= 7;
151
152 scsi->dev[id].valid = 1;
153 scsi->dev[id].drive = drive;
154 scsi->dev[id].type = MAC_SCSI_DEV_DISK;
155
156 memcpy (scsi->dev[id].vendor, "PCE ", 8);
157 memcpy (scsi->dev[id].product, "PCEDISK ", 16);
158}
159
160void mac_scsi_set_drive_vendor (mac_scsi_t *scsi, unsigned id, const char *vendor)
161{
162 unsigned i;
163 unsigned char *dst;
164
165 dst = scsi->dev[id & 7].vendor;
166
167 for (i = 0; i < 8; i++) {
168 if (*vendor == 0) {
169 dst[i] = ' ';
170 }
171 else {
172 dst[i] = *(vendor++);
173 }
174 }
175}
176
177void mac_scsi_set_drive_product (mac_scsi_t *scsi, unsigned id, const char *product)
178{
179 unsigned i;
180 unsigned char *dst;
181
182 dst = scsi->dev[id & 7].product;
183
184 for (i = 0; i < 16; i++) {
185 if (*product == 0) {
186 dst[i] = ' ';
187 }
188 else {
189 dst[i] = *(product++);
190 }
191 }
192}
193
194static
195int mac_scsi_set_buf_max (mac_scsi_t *scsi, unsigned long max)
196{
197 unsigned char *tmp;
198
199 if (max <= scsi->buf_max) {
200 return (0);
201 }
202
203#ifdef DEBUG_SCSI
204 mac_log_deb ("scsi: buffer size = %lu\n", max);
205#endif
206
207 tmp = realloc (scsi->buf, max);
208
209 if (tmp == NULL) {
210 return (1);
211 }
212
213 scsi->buf = tmp;
214 scsi->buf_max = max;
215
216 return (0);
217}
218
219static
220void mac_scsi_set_int (mac_scsi_t *scsi, int val)
221{
222 val = (val != 0);
223
224 if (scsi->set_int_val == val) {
225 return;
226 }
227
228#ifdef DEBUG_SCSI
229 mac_log_deb ("scsi: interrupt = %d\n", val != 0);
230#endif
231
232 scsi->set_int_val = val;
233
234 if (scsi->set_int != NULL) {
235 scsi->set_int (scsi->set_int_ext, val);
236 }
237}
238
239static
240void mac_scsi_check_phase (mac_scsi_t *scsi)
241{
242 unsigned char dif;
243
244 dif = ((scsi->csb >> 2) ^ scsi->tcr) & 0x07;
245
246 if (dif) {
247#ifdef DEBUG_SCSI
248 mac_log_deb ("scsi: phase mismatch (%02X)\n", dif);
249#endif
250 scsi->bsr &= ~E5380_BSR_PHSM;
251 }
252 else {
253 scsi->bsr |= E5380_BSR_PHSM;
254 }
255}
256
257static
258void mac_scsi_set_phase_free (mac_scsi_t *scsi)
259{
260#ifdef DEBUG_SCSI
261 mac_log_deb ("scsi: phase: free\n");
262#endif
263
264 scsi->phase = E5380_PHASE_FREE;
265
266 scsi->csb &= ~E5380_CSB_BSY;
267 scsi->csb &= ~E5380_CSB_CD;
268 scsi->csb &= ~E5380_CSB_MSG;
269 scsi->csb &= ~E5380_CSB_IO;
270 scsi->csb &= ~E5380_CSB_REQ;
271}
272
273static
274void mac_scsi_set_phase_arb (mac_scsi_t *scsi)
275{
276#ifdef DEBUG_SCSI
277 mac_log_deb ("scsi: phase: arbitration (id=%02X)\n", scsi->odr);
278#endif
279
280 scsi->phase = E5380_PHASE_ARB;
281
282 scsi->csd = scsi->odr;
283 scsi->icr |= E5380_ICR_AIP;
284}
285
286static
287void mac_scsi_set_phase_sel (mac_scsi_t *scsi)
288{
289#ifdef DEBUG_SCSI
290 mac_log_deb ("scsi: phase: selection\n");
291#endif
292
293 scsi->phase = E5380_PHASE_SEL;
294}
295
296static
297void mac_scsi_set_phase_cmd (mac_scsi_t *scsi)
298{
299#ifdef DEBUG_SCSI
300 mac_log_deb ("scsi: phase: command\n");
301#endif
302
303 scsi->phase = E5380_PHASE_CMD;
304
305 scsi->csb |= E5380_CSB_BSY;
306 scsi->csb |= E5380_CSB_CD;
307 scsi->csb &= ~E5380_CSB_IO;
308 scsi->csb &= ~E5380_CSB_MSG;
309 scsi->csb |= E5380_CSB_REQ;
310
311 scsi->cmd_i = 0;
312 scsi->cmd_n = 16;
313}
314
315void mac_scsi_set_phase_data_in (mac_scsi_t *scsi)
316{
317#ifdef DEBUG_SCSI
318 mac_log_deb ("scsi: phase: data in\n");
319#endif
320
321 scsi->phase = E5380_PHASE_DATA_IN;
322
323 scsi->csb |= E5380_CSB_BSY;
324 scsi->csb &= ~E5380_CSB_CD;
325 scsi->csb |= E5380_CSB_IO;
326 scsi->csb &= ~E5380_CSB_MSG;
327 scsi->csb |= E5380_CSB_REQ;
328
329 scsi->csd = scsi->buf[scsi->buf_i];
330}
331
332void mac_scsi_set_phase_data_out (mac_scsi_t *scsi)
333{
334#ifdef DEBUG_SCSI
335 mac_log_deb ("scsi: phase: data out\n");
336#endif
337
338 scsi->phase = E5380_PHASE_DATA_OUT;
339
340 scsi->csb |= E5380_CSB_BSY;
341 scsi->csb &= ~E5380_CSB_CD;
342 scsi->csb &= ~E5380_CSB_IO;
343 scsi->csb &= ~E5380_CSB_MSG;
344 scsi->csb |= E5380_CSB_REQ;
345}
346
347void mac_scsi_set_phase_status (mac_scsi_t *scsi, unsigned char val)
348{
349#ifdef DEBUG_SCSI
350 mac_log_deb ("scsi: phase: status (%02X) cnt=%u\n", val, scsi->buf_i);
351#endif
352
353 scsi->phase = E5380_PHASE_STATUS;
354
355 scsi->csb |= E5380_CSB_BSY;
356 scsi->csb |= E5380_CSB_CD;
357 scsi->csb |= E5380_CSB_IO;
358 scsi->csb &= ~E5380_CSB_MSG;
359 scsi->csb |= E5380_CSB_REQ;
360
361 scsi->csd = val;
362}
363
364static
365void mac_scsi_set_phase_msg_in (mac_scsi_t *scsi, unsigned char val)
366{
367#ifdef DEBUG_SCSI
368 mac_log_deb ("scsi: phase: msg in (%02X)\n", val);
369#endif
370
371 scsi->phase = E5380_PHASE_MSG_IN;
372
373 scsi->csb |= E5380_CSB_BSY;
374 scsi->csb |= E5380_CSB_CD;
375 scsi->csb |= E5380_CSB_IO;
376 scsi->csb |= E5380_CSB_MSG;
377 scsi->csb |= E5380_CSB_REQ;
378
379 scsi->csd = val;
380}
381
382
383static
384void mac_scsi_select (mac_scsi_t *scsi, unsigned char msk)
385{
386 unsigned i;
387
388 msk &= 0x7f;
389
390 i = 0;
391 while (msk != 0) {
392 if (msk & 1) {
393 break;
394 }
395
396 i += 1;
397 msk >>= 1;
398 }
399
400 scsi->sel_drv = i;
401
402#ifdef DEBUG_SCSI
403 mac_log_deb ("scsi: select (id=%02X/%u)\n", scsi->odr, scsi->sel_drv);
404#endif
405}
406
407mac_scsi_dev_t *mac_scsi_get_device (mac_scsi_t *scsi)
408{
409 unsigned id;
410
411 id = scsi->sel_drv & 7;
412
413 if (scsi->dev[id].valid) {
414 return (&scsi->dev[id]);
415 }
416
417 return (NULL);
418}
419
420static
421disk_t *mac_scsi_get_disk (mac_scsi_t *scsi)
422{
423 mac_scsi_dev_t *dev;
424 disk_t *dsk;
425
426 dev = &scsi->dev[scsi->sel_drv & 7];
427
428 if ((dev->valid == 0) || (dev->drive == 0xffff)) {
429 return (NULL);
430 }
431
432 dsk = dsks_get_disk (scsi->dsks, dev->drive);
433
434 return (dsk);
435}
436
437
438static
439void mac_scsi_cmd_test_unit_ready (mac_scsi_t *scsi)
440{
441 mac_scsi_set_phase_status (scsi, 0x00);
442}
443
444static
445void mac_scsi_cmd_sense (mac_scsi_t *scsi)
446{
447 memset (scsi->buf, 0, 13);
448 scsi->buf[0] = 0xf0;
449
450 scsi->buf_i = 0;
451 scsi->buf_n = 13;
452
453 mac_scsi_set_phase_data_in (scsi);
454}
455
456static
457void mac_scsi_cmd_format_unit (mac_scsi_t *scsi)
458{
459 mac_scsi_set_phase_status (scsi, 0x00);
460}
461
462static
463void mac_scsi_cmd_read (mac_scsi_t *scsi, unsigned long lba, unsigned long cnt)
464{
465 mac_scsi_dev_t *dev;
466 disk_t *dsk;
467 int psize;
468
469 dev = mac_scsi_get_device (scsi);
470
471 if (dev == NULL) {
472 mac_scsi_set_phase_status (scsi, 0x02);
473 return;
474 }
475
476 switch (dev->type) {
477 case MAC_SCSI_DEV_DISK:
478 dsk = mac_scsi_get_disk (scsi);
479
480 if (dsk == NULL) {
481 mac_scsi_set_phase_status (scsi, 0x02);
482 return;
483 }
484
485#ifdef DEBUG_SCSI
486 mac_log_deb ("scsi: read %u blocks at %lu\n", cnt, lba);
487#endif
488
489 if (mac_scsi_set_buf_max (scsi, 512UL * cnt)) {
490 mac_log_deb ("scsi: too many blocks (%u)\n", cnt);
491 mac_scsi_set_phase_status (scsi, 0x02);
492 return;
493 }
494
495 if (dsk_read_lba (dsk, scsi->buf, lba, cnt)) {
496 mac_log_deb ("scsi: read error at %lu + %lu\n", lba, cnt);
497 mac_scsi_set_phase_status (scsi, 0x02);
498 return;
499 }
500
501 scsi->buf_i = 0;
502 scsi->buf_n = 512 * cnt;
503
504 mac_scsi_set_phase_data_in (scsi);
505 break;
506 case MAC_SCSI_DEV_DAYNAPORT:
507 if (cnt == 1) {
508 mac_scsi_set_phase_status (scsi, 0x02);
509 return;
510 }
511
512 cnt = 1514 + 6;
513
514 if (mac_scsi_set_buf_max (scsi, cnt)) {
515 mac_scsi_set_phase_status (scsi, 0x02);
516 return;
517 }
518
519 memset (scsi->buf, 0, cnt);
520
521 psize = mac_scsi_daynaport_read (dev, scsi->buf + 6);
522 if (psize > 0) {
523 scsi->buf[0] = (psize >> 8) & 0xff;
524 scsi->buf[1] = psize & 0xff;
525
526 if (mac_scsi_daynaport_data_avail (dev)) {
527 scsi->buf[5] = 0x10;
528 }
529 }
530
531 scsi->buf_i = 0;
532 scsi->buf_n = psize + 6;
533
534 mac_scsi_set_phase_data_in (scsi);
535 break;
536 }
537}
538
539static
540void mac_scsi_cmd_read6 (mac_scsi_t *scsi)
541{
542 unsigned long lba;
543 unsigned long cnt;
544
545 /* lun = (scsi->cmd[1] >> 5) & 0x07; */
546
547 lba = scsi->cmd[1] & 0x1f;
548 lba = (lba << 8) | scsi->cmd[2];
549 lba = (lba << 8) | scsi->cmd[3];
550
551 cnt = scsi->cmd[4];
552 if (cnt == 0) {
553 cnt = 256;
554 }
555
556 mac_scsi_cmd_read (scsi, lba, cnt);
557}
558
559static
560void mac_scsi_cmd_read10 (mac_scsi_t *scsi)
561{
562 unsigned long lba;
563 unsigned long cnt;
564
565 /* lun = (scsi->cmd[1] >> 5) & 0x07; */
566
567 lba = scsi->cmd[2];
568 lba = (lba << 8) | scsi->cmd[3];
569 lba = (lba << 8) | scsi->cmd[4];
570 lba = (lba << 8) | scsi->cmd[5];
571
572 cnt = scsi->cmd[7];
573 cnt = (cnt << 8) | scsi->cmd[8];
574
575 mac_scsi_cmd_read (scsi, lba, cnt);
576}
577
578static
579void mac_scsi_cmd_write_finish (mac_scsi_t *scsi, unsigned long lba, unsigned long cnt)
580{
581 mac_scsi_dev_t *dev;
582 disk_t *dsk;
583
584 dev = mac_scsi_get_device (scsi);
585
586 if (dev == NULL) {
587 mac_scsi_set_phase_status (scsi, 0x02);
588 return;
589 }
590
591 switch (dev->type) {
592 case MAC_SCSI_DEV_DISK:
593 dsk = mac_scsi_get_disk (scsi);
594
595 if (dsk == NULL) {
596 mac_scsi_set_phase_status (scsi, 0x02);
597 return;
598 }
599
600 if ((512 * cnt) != scsi->buf_i) {
601 mac_log_deb ("scsi: write size mismatch (%u / %u)\n",
602 512 * cnt, scsi->buf_i
603 );
604 mac_scsi_set_phase_status (scsi, 0x02);
605 return;
606 }
607
608#ifdef DEBUG_SCSI
609 mac_log_deb ("scsi: write %u blocks at %lu\n", cnt, lba);
610#endif
611
612 if (dsk_write_lba (dsk, scsi->buf, lba, cnt)) {
613 mac_log_deb ("scsi: write error\n");
614 mac_scsi_set_phase_status (scsi, 0x02);
615 return;
616 }
617 break;
618 case MAC_SCSI_DEV_DAYNAPORT:
619 for (;;) {
620 if (scsi->cmd[5] == 0x80) {
621 cnt = (long)(scsi->buf[0] << 8) | scsi->buf[1];
622 mac_scsi_daynaport_write (dev, scsi->buf + 4, cnt);
623 } else {
624 /* XXX: do these non-preamble packets exist? */
625 mac_scsi_daynaport_write (dev, scsi->buf, cnt);
626 break;
627 }
628
629 /* trailing 2 bytes are size of next packet + flags */
630 cnt = (long)(scsi->buf[cnt + 4] << 8) |
631 scsi->buf[cnt + 5];
632 if (cnt == 0)
633 break;
634
635 /*
636 * setup scsi buffers to pretend this next packet in
637 * the same read(6) is actually a new transaction
638 */
639 scsi->cmd[3] = (cnt >> 8) & 0xff;
640 scsi->cmd[4] = cnt & 0xff;
641
642 scsi->buf[0] = (cnt >> 8) & 0xff;
643 scsi->buf[1] = cnt & 0xff;
644 scsi->buf[2] = 0;
645 scsi->buf[3] = 0;
646
647 scsi->buf_i = 4;
648 scsi->buf_n = 4 + cnt + 4;
649 return;
650 }
651 break;
652 }
653
654 scsi->buf_i = 0;
655 scsi->buf_n = 0;
656
657 scsi->cmd_finish = NULL;
658
659 mac_scsi_set_phase_status (scsi, 0x00);
660}
661
662void mac_scsi_cmd_write6_finish (mac_scsi_t *scsi)
663{
664 unsigned long lba;
665 unsigned long cnt;
666
667 /* lun = (scsi->cmd[1] >> 5) & 0x07; */
668
669 lba = scsi->cmd[1] & 0x1f;
670 lba = (lba << 8) | scsi->cmd[2];
671 lba = (lba << 8) | scsi->cmd[3];
672
673 cnt = scsi->cmd[4];
674 if (cnt == 0) {
675 cnt = 256;
676 }
677
678 mac_scsi_cmd_write_finish (scsi, lba, cnt);
679}
680
681static
682void mac_scsi_cmd_write6 (mac_scsi_t *scsi)
683{
684 mac_scsi_dev_t *dev;
685 unsigned long size;
686 unsigned cnt;
687
688 dev = mac_scsi_get_device (scsi);
689
690 if (dev == NULL) {
691 mac_scsi_set_phase_status (scsi, 0x02);
692 return;
693 }
694
695 cnt = scsi->cmd[4];
696
697 if (cnt == 0) {
698 cnt = 256;
699 }
700
701 switch (dev->type) {
702 case MAC_SCSI_DEV_DISK:
703 size = 512UL * cnt;
704 break;
705
706 case MAC_SCSI_DEV_DAYNAPORT:
707 size = ((long)(scsi->cmd[3]) << 8) + scsi->cmd[4];
708
709 if (scsi->cmd[5] == 0x80) {
710 /*
711 * multi-packet capable, include 4-byte header and
712 * 4-byte header of next packet
713 */
714 size += 4 + 4;
715 }
716 break;
717 }
718
719 if (mac_scsi_set_buf_max (scsi, size)) {
720 mac_log_deb ("scsi: write block count %u\n", cnt);
721 mac_scsi_set_phase_status (scsi, 0x02);
722 return;
723 }
724
725 scsi->buf_i = 0;
726 scsi->buf_n = size;
727
728 scsi->cmd_finish = mac_scsi_cmd_write6_finish;
729
730 mac_scsi_set_phase_data_out (scsi);
731}
732
733static
734void mac_scsi_cmd_write10_finish (mac_scsi_t *scsi)
735{
736 unsigned long lba;
737 unsigned cnt;
738
739 /* lun = (scsi->cmd[1] >> 5) & 0x07; */
740
741 lba = scsi->cmd[2];
742 lba = (lba << 8) | scsi->cmd[3];
743 lba = (lba << 8) | scsi->cmd[4];
744 lba = (lba << 8) | scsi->cmd[5];
745
746 cnt = (scsi->cmd[7] << 8) | scsi->cmd[8];
747
748 mac_scsi_cmd_write_finish (scsi, lba, cnt);
749}
750
751static
752void mac_scsi_cmd_write10 (mac_scsi_t *scsi)
753{
754 unsigned cnt;
755
756 cnt = (scsi->cmd[7] << 8) | scsi->cmd[8];
757
758 if (mac_scsi_set_buf_max (scsi, 512UL * cnt)) {
759 mac_log_deb ("scsi: write block count %u\n", cnt);
760 mac_scsi_set_phase_status (scsi, 0x02);
761 return;
762 }
763
764 scsi->buf_i = 0;
765 scsi->buf_n = 512 * cnt;
766
767 scsi->cmd_finish = mac_scsi_cmd_write10_finish;
768
769 mac_scsi_set_phase_data_out (scsi);
770}
771
772static
773void mac_scsi_cmd_verify10 (mac_scsi_t *scsi)
774{
775 mac_scsi_dev_t *dev;
776 unsigned long lba;
777 unsigned cnt;
778 disk_t *dsk;
779
780 dev = mac_scsi_get_device (scsi);
781
782 if (dev == NULL) {
783 mac_scsi_set_phase_status (scsi, 0x02);
784 return;
785 }
786
787 switch (dev->type) {
788 case MAC_SCSI_DEV_DISK:
789 dsk = mac_scsi_get_disk (scsi);
790
791 if (dsk == NULL) {
792 mac_scsi_set_phase_status (scsi, 0x02);
793 return;
794 }
795
796 /* lun = (scsi->cmd[1] >> 5) & 0x07; */
797
798 lba = scsi->cmd[2];
799 lba = (lba << 8) | scsi->cmd[3];
800 lba = (lba << 8) | scsi->cmd[4];
801 lba = (lba << 8) | scsi->cmd[5];
802
803 cnt = scsi->cmd[7];
804 cnt = (cnt << 8) | scsi->cmd[8];
805
806#ifdef DEBUG_SCSI
807 mac_log_deb ("scsi: verify %u blocks at %lu\n", cnt, lba);
808#endif
809 break;
810 case MAC_SCSI_DEV_DAYNAPORT:
811 break;
812 }
813
814 scsi->buf_i = 0;
815 scsi->buf_n = 0;
816
817 mac_scsi_set_phase_status (scsi, 0x00);
818}
819
820static
821void mac_scsi_cmd_inquiry (mac_scsi_t *scsi)
822{
823 mac_scsi_dev_t *dev;
824
825 dev = mac_scsi_get_device (scsi);
826
827 memset (scsi->buf, 0, 256);
828
829 if (dev != NULL) {
830 memcpy (scsi->buf + 8, dev->vendor, 8);
831 memcpy (scsi->buf + 16, dev->product, 16);
832 memcpy (scsi->buf + 32, dev->revision, 4);
833
834 switch (dev->type) {
835 case MAC_SCSI_DEV_DISK:
836 scsi->buf[0] = 0x00; /* direct-access device */
837 break;
838
839 case MAC_SCSI_DEV_DAYNAPORT:
840 scsi->buf[0] = 0x03; /* processor device */
841 scsi->buf[2] = 0x01;
842 break;
843 }
844 }
845
846 scsi->buf[4] = 32;
847
848 scsi->buf_i = 0;
849 scsi->buf_n = (scsi->cmd[4] < 36) ? scsi->cmd[4] : 36;
850
851 mac_scsi_set_phase_data_in (scsi);
852}
853
854static
855void mac_scsi_cmd_mode_select (mac_scsi_t *scsi)
856{
857 scsi->buf_i = 0;
858 scsi->buf_n = 0;
859
860 mac_scsi_set_phase_data_out (scsi);
861}
862
863static
864void mac_scsi_cmd_mode_sense (mac_scsi_t *scsi)
865{
866 mac_scsi_dev_t *dev;
867 disk_t *dsk;
868
869 dev = mac_scsi_get_device (scsi);
870
871 if (dev == NULL) {
872 mac_scsi_set_phase_status (scsi, 0x02);
873 return;
874 }
875
876 switch (dev->type) {
877 case MAC_SCSI_DEV_DISK:
878 dsk = mac_scsi_get_disk (scsi);
879
880 if (dsk == NULL) {
881 mac_scsi_set_phase_status (scsi, 0x02);
882 return;
883 }
884
885 memset (scsi->buf, 0, 512);
886
887 scsi->buf_i = 0;
888 scsi->buf_n = 0;
889
890 switch (scsi->cmd[2] & 0x3f) {
891 case 0x01: /* read-write error recovery page */
892 scsi->buf[0] = 0x01;
893 scsi->buf[1] = 10;
894 scsi->buf_n = 12;
895 break;
896
897 case 0x03: /* format device page */
898 scsi->buf[0] = 0x03;
899 scsi->buf[1] = 22;
900 scsi->buf_n = 24;
901 break;
902
903 case 0x04: /* rigid disk drive geometry page */
904 scsi->buf[0] = 0x04;
905 scsi->buf[1] = 22;
906 scsi->buf[2] = 0;
907 buf_set_uint16_be (scsi->buf, 3, dsk->c);
908 scsi->buf[5] = dsk->h;
909 buf_set_uint16_be (scsi->buf, 20, 3600);
910 scsi->buf_n = 32;
911 break;
912
913 case 0x30: /* vendor specific */
914 scsi->buf[0] = 0x30;
915 scsi->buf[1] = 33;
916 strcpy ((char *) scsi->buf + 14, "APPLE COMPUTER, INC");
917 scsi->buf_n = 34;
918 break;
919
920 default:
921 mac_log_deb ("scsi: mode sense: unknown mode page (%02X)\n",
922 scsi->cmd[2]
923 );
924 break;
925 }
926 break;
927
928 case MAC_SCSI_DEV_DAYNAPORT:
929 break;
930 }
931
932 if (scsi->buf_n > 0) {
933 mac_scsi_set_phase_data_in (scsi);
934 }
935 else {
936 mac_scsi_set_phase_status (scsi, 0x02);
937 }
938}
939
940static
941void mac_scsi_cmd_start_stop (mac_scsi_t *scsi)
942{
943 const char *str;
944
945 switch (scsi->cmd[4] & 3) {
946 case 0:
947 str = "stop motor";
948 break;
949 case 1:
950 str = "start motor";
951 break;
952 case 2:
953 str = "eject media";
954 break;
955 case 3:
956 str = "load media";
957 break;
958 }
959
960 mac_log_deb ("scsi: start/stop unit %u (%s)\n", scsi->sel_drv, str);
961
962 mac_scsi_set_phase_status (scsi, 0x00);
963}
964
965static
966void mac_scsi_cmd_read_capacity (mac_scsi_t *scsi)
967{
968 unsigned long cnt;
969 mac_scsi_dev_t *dev;
970 disk_t *dsk;
971
972 dev = mac_scsi_get_device (scsi);
973
974 if (dev == NULL) {
975 mac_scsi_set_phase_status (scsi, 0x02);
976 return;
977 }
978
979 switch (dev->type) {
980 case MAC_SCSI_DEV_DISK:
981 dsk = mac_scsi_get_disk (scsi);
982
983 if (dsk == NULL) {
984 mac_scsi_set_phase_status (scsi, 0x02);
985 return;
986 }
987
988 cnt = dsk_get_block_cnt (dsk);
989 buf_set_uint32_be (scsi->buf, 0, cnt - 1);
990 buf_set_uint32_be (scsi->buf, 4, 512);
991 break;
992
993 case MAC_SCSI_DEV_DAYNAPORT:
994 buf_set_uint32_be (scsi->buf, 0, 1);
995 buf_set_uint32_be (scsi->buf, 4, 512);
996 break;
997 }
998
999 scsi->buf_i = 0;
1000 scsi->buf_n = 8;
1001
1002 mac_scsi_set_phase_data_in (scsi);
1003}
1004
1005static
1006void mac_scsi_cmd_read_buffer (mac_scsi_t *scsi)
1007{
1008 memset (scsi->buf, 0, 512);
1009
1010 scsi->buf_i = 0;
1011 scsi->buf_n = 4;
1012
1013 mac_scsi_set_phase_data_in (scsi);
1014}
1015
1016
1017static
1018void mac_scsi_set_cmd (mac_scsi_t *scsi, unsigned cnt, void (*cmd) (mac_scsi_t *scsi))
1019{
1020 scsi->cmd_n = cnt;
1021 scsi->cmd_start = cmd;
1022}
1023
1024static
1025void mac_scsi_cmd_init (mac_scsi_t *scsi, unsigned char cmd)
1026{
1027 scsi->cmd_start = NULL;
1028 scsi->cmd_finish = NULL;
1029
1030 switch (cmd) {
1031 case 0x00:
1032 mac_scsi_set_cmd (scsi, 6, mac_scsi_cmd_test_unit_ready);
1033 break;
1034
1035 case 0x03:
1036 mac_scsi_set_cmd (scsi, 6, mac_scsi_cmd_sense);
1037 break;
1038
1039 case 0x04:
1040 mac_scsi_set_cmd (scsi, 6, mac_scsi_cmd_format_unit);
1041 break;
1042
1043 case 0x08:
1044 mac_scsi_set_cmd (scsi, 6, mac_scsi_cmd_read6);
1045 break;
1046
1047 case 0x0a:
1048 mac_scsi_set_cmd (scsi, 6, mac_scsi_cmd_write6);
1049 break;
1050
1051 case 0x12:
1052 mac_scsi_set_cmd (scsi, 6, mac_scsi_cmd_inquiry);
1053 break;
1054
1055 case 0x15:
1056 mac_scsi_set_cmd (scsi, 6, mac_scsi_cmd_mode_select);
1057 break;
1058
1059 case 0x1a:
1060 mac_scsi_set_cmd (scsi, 6, mac_scsi_cmd_mode_sense);
1061 break;
1062
1063 case 0x1b:
1064 mac_scsi_set_cmd (scsi, 6, mac_scsi_cmd_start_stop);
1065 break;
1066
1067 case 0x25:
1068 mac_scsi_set_cmd (scsi, 10, mac_scsi_cmd_read_capacity);
1069 break;
1070
1071 case 0x28:
1072 mac_scsi_set_cmd (scsi, 10, mac_scsi_cmd_read10);
1073 break;
1074
1075 case 0x2a:
1076 mac_scsi_set_cmd (scsi, 10, mac_scsi_cmd_write10);
1077 break;
1078
1079 case 0x2f:
1080 mac_scsi_set_cmd (scsi, 10, mac_scsi_cmd_verify10);
1081 break;
1082
1083 case 0x3c:
1084 mac_scsi_set_cmd (scsi, 6, mac_scsi_cmd_read_buffer);
1085 break;
1086
1087 /* DaynaPORT vendor commands */
1088
1089 case 0x09:
1090 mac_scsi_set_cmd (scsi, 6, mac_scsi_daynaport_cmd_read_stats);
1091 break;
1092
1093 case 0x0c:
1094 mac_scsi_set_cmd (scsi, 6, mac_scsi_daynaport_cmd_set_interface_mode);
1095 break;
1096
1097 case 0x0d:
1098 mac_scsi_set_cmd (scsi, 6, mac_scsi_daynaport_cmd_set_mcast_addr);
1099 break;
1100
1101 case 0x0e:
1102 mac_scsi_set_cmd (scsi, 6, mac_scsi_daynaport_cmd_enable_interface);
1103 break;
1104
1105 default:
1106 mac_log_deb ("scsi: unknown command (%02X)\n", cmd);
1107 mac_scsi_set_phase_status (scsi, 0x02);
1108 break;
1109 }
1110}
1111
1112
1113static
1114unsigned char mac_scsi_get_csd_dma (mac_scsi_t *scsi)
1115{
1116 unsigned char val;
1117
1118 if (scsi->phase != E5380_PHASE_DATA_IN) {
1119 return (0);
1120 }
1121
1122 if (scsi->buf_i >= scsi->buf_n) {
1123 return (0);
1124 }
1125
1126 val = scsi->buf[scsi->buf_i];
1127 scsi->buf_i += 1;
1128
1129 if (scsi->buf_i >= scsi->buf_n) {
1130 mac_scsi_set_phase_status (scsi, 0x00);
1131 }
1132
1133 return (val);
1134}
1135
1136static
1137unsigned char mac_scsi_get_icr (mac_scsi_t *scsi)
1138{
1139 return (scsi->icr);
1140}
1141
1142static
1143unsigned char mac_scsi_get_mr2 (mac_scsi_t *scsi)
1144{
1145 return (scsi->mr2);
1146}
1147
1148static
1149unsigned char mac_scsi_get_tcr (mac_scsi_t *scsi)
1150{
1151 return (scsi->tcr & 0x0f);
1152}
1153
1154static
1155unsigned char mac_scsi_get_csb (mac_scsi_t *scsi)
1156{
1157 return (scsi->csb);
1158}
1159
1160static
1161unsigned char mac_scsi_get_bsr (mac_scsi_t *scsi)
1162{
1163 return (scsi->bsr);
1164}
1165
1166unsigned char mac_scsi_get_uint8 (void *ext, unsigned long addr)
1167{
1168 unsigned char val;
1169 mac_scsi_t *scsi = ext;
1170
1171 addr = (addr & scsi->addr_mask) >> scsi->addr_shift;
1172
1173 switch (addr) {
1174 case 0x00: /* CSD */
1175 val = scsi->csd;
1176 break;
1177
1178 case 0x01: /* ICR */
1179 val = mac_scsi_get_icr (scsi);
1180 break;
1181
1182 case 0x02: /* MR2 */
1183 val = mac_scsi_get_mr2 (scsi);
1184 break;
1185
1186 case 0x03: /* TCR */
1187 val = mac_scsi_get_tcr (scsi);
1188 break;
1189
1190 case 0x04: /* CSB */
1191 val = mac_scsi_get_csb (scsi);
1192 break;
1193
1194 case 0x05: /* BSR */
1195 mac_scsi_check_phase (scsi);
1196 val = mac_scsi_get_bsr (scsi);
1197 break;
1198
1199 case 0x06: /* IDR */
1200 case 0x26:
1201 val = mac_scsi_get_csd_dma (scsi);
1202 break;
1203
1204 case 0x07: /* RPI */
1205 mac_scsi_set_int (scsi, 0);
1206 val = 0xff;
1207 break;
1208
1209 case 0x20: /* CSD with DACK */
1210 val = mac_scsi_get_csd_dma (scsi);
1211 break;
1212
1213 default:
1214 val = 0xff;
1215 mac_log_deb ("scsi: get 8: %04lX -> %02X\n", addr, val);
1216 break;
1217 }
1218
1219 return (val);
1220}
1221
1222unsigned short mac_scsi_get_uint16 (void *ext, unsigned long addr)
1223{
1224 mac_scsi_t *scsi = ext;
1225
1226 addr = (addr & scsi->addr_mask) >> scsi->addr_shift;
1227
1228#ifdef DEBUG_SCSI
1229 mac_log_deb ("scsi: set 16: %04lX -> %02X\n", addr, 0x00);
1230#endif
1231
1232 return (0);
1233}
1234
1235
1236static
1237void mac_scsi_set_odr (mac_scsi_t *scsi, unsigned char val)
1238{
1239 scsi->odr = val;
1240}
1241
1242static
1243void mac_scsi_set_odr_dma (mac_scsi_t *scsi, unsigned char val)
1244{
1245 if (scsi->phase != E5380_PHASE_DATA_OUT) {
1246 return;
1247 }
1248
1249 if (scsi->buf_i >= scsi->buf_n) {
1250 return;
1251 }
1252
1253 scsi->buf[scsi->buf_i] = val;
1254 scsi->buf_i += 1;
1255
1256 if (scsi->buf_i >= scsi->buf_n) {
1257 if (scsi->cmd_finish != NULL) {
1258 scsi->cmd_finish (scsi);
1259 }
1260 else {
1261 mac_scsi_set_phase_status (scsi, 0x02);
1262 }
1263 }
1264}
1265
1266static
1267void mac_scsi_set_icr (mac_scsi_t *scsi, unsigned char val)
1268{
1269 unsigned char dif;
1270
1271 val &= ~0x60;
1272
1273 dif = scsi->icr ^ val;
1274 scsi->icr = val;
1275
1276 switch (scsi->phase) {
1277 case E5380_PHASE_ARB:
1278 if (dif & val & E5380_ICR_SEL) {
1279 mac_scsi_set_phase_sel (scsi);
1280 }
1281 break;
1282
1283 case E5380_PHASE_CMD:
1284 if (dif & val & E5380_ICR_ACK) {
1285 if (scsi->cmd_i < scsi->cmd_n) {
1286 scsi->cmd[scsi->cmd_i] = scsi->odr;
1287 scsi->cmd_i += 1;
1288 }
1289
1290 if (scsi->cmd_i == 1) {
1291 mac_scsi_cmd_init (scsi, scsi->cmd[0]);
1292 }
1293
1294 scsi->csb &= ~E5380_CSB_REQ;
1295
1296#ifdef DEBUG_SCSI
1297 mac_log_deb ("scsi: command byte: %02X (%u/%u)\n",
1298 scsi->odr, scsi->cmd_i, scsi->cmd_n
1299 );
1300#endif
1301 }
1302
1303 if (dif & ~val & E5380_ICR_ACK) {
1304 if (scsi->cmd_i >= scsi->cmd_n) {
1305 if (scsi->cmd_start != NULL) {
1306#ifdef DEBUG_SCSI
1307 mac_log_deb (
1308 "scsi: command exec (%u) %02X %02X %02X %02X %02X %02X\n",
1309 scsi->cmd_i,
1310 scsi->cmd[0], scsi->cmd[1],
1311 scsi->cmd[2], scsi->cmd[3],
1312 scsi->cmd[4], scsi->cmd[5]
1313 );
1314#endif
1315
1316 scsi->cmd_start (scsi);
1317 }
1318 else {
1319 mac_scsi_set_phase_status (scsi, 0x02);
1320 }
1321 }
1322 else {
1323 scsi->csb |= E5380_CSB_REQ;
1324 }
1325 }
1326 break;
1327
1328 case E5380_PHASE_DATA_IN:
1329 if (dif & val & E5380_ICR_ACK) {
1330 scsi->csb &= ~E5380_CSB_REQ;
1331#ifdef DEBUG_SCSI
1332 mac_log_deb ("scsi: data ack (%02X)\n", scsi->csd);
1333#endif
1334 }
1335
1336 if (dif & ~val & E5380_ICR_ACK) {
1337 scsi->buf_i += 1;
1338 if (scsi->buf_i < scsi->buf_n) {
1339 scsi->csd = scsi->buf[scsi->buf_i];
1340 scsi->csb |= E5380_CSB_REQ;
1341 }
1342 else {
1343 mac_scsi_set_phase_status (scsi, 0x00);
1344 }
1345 }
1346 break;
1347
1348 case E5380_PHASE_DATA_OUT:
1349 if (dif & val & E5380_ICR_ACK) {
1350 if (scsi->buf_i < scsi->buf_n) {
1351 scsi->buf[scsi->buf_i] = scsi->odr;
1352 scsi->buf_i += 1;
1353 }
1354 scsi->csb &= ~E5380_CSB_REQ;
1355#ifdef DEBUG_SCSI
1356 mac_log_deb ("scsi: data out ack (%02X)\n", scsi->odr);
1357#endif
1358 }
1359
1360 if (dif & ~val & E5380_ICR_ACK) {
1361 if (scsi->buf_i >= scsi->buf_n) {
1362 /* command */
1363 mac_scsi_set_phase_status (scsi, 0x02);
1364 }
1365 else {
1366 scsi->csb |= E5380_CSB_REQ;
1367 }
1368 }
1369 break;
1370
1371 case E5380_PHASE_STATUS:
1372 if (dif & val & E5380_ICR_ACK) {
1373 scsi->csb &= ~E5380_CSB_REQ;
1374 }
1375
1376 if (dif & ~val & E5380_ICR_ACK) {
1377#ifdef DEBUG_SCSI
1378 mac_log_deb ("scsi: status ack\n");
1379#endif
1380 mac_scsi_set_phase_msg_in (scsi, 0x00);
1381 }
1382 break;
1383
1384 case E5380_PHASE_MSG_IN:
1385 if (dif & val & E5380_ICR_ACK) {
1386 scsi->csb &= ~E5380_CSB_REQ;
1387 }
1388
1389 if (dif & ~val & E5380_ICR_ACK) {
1390 mac_scsi_set_phase_free (scsi);
1391 }
1392 break;
1393 }
1394}
1395
1396static
1397void mac_scsi_set_mr2 (mac_scsi_t *scsi, unsigned char val)
1398{
1399 unsigned char dif;
1400
1401 dif = scsi->mr2 ^ val;
1402 scsi->mr2 = val;
1403
1404 switch (scsi->phase) {
1405 case E5380_PHASE_FREE:
1406 if (dif & val & E5380_MR2_ARB) {
1407 mac_scsi_set_phase_arb (scsi);
1408 }
1409 break;
1410
1411 case E5380_PHASE_SEL:
1412 if (dif & ~val & E5380_MR2_ARB) {
1413 mac_scsi_select (scsi, scsi->odr);
1414
1415 scsi->icr &= ~E5380_ICR_BSY;
1416
1417 if (mac_scsi_get_device (scsi) != NULL) {
1418 mac_scsi_set_phase_cmd (scsi);
1419 mac_scsi_set_int (scsi, 1);
1420 }
1421 else {
1422 mac_scsi_set_phase_free (scsi);
1423 }
1424 }
1425 break;
1426
1427 case E5380_PHASE_DATA_IN:
1428 if (dif & val & E5380_MR2_DMA) {
1429 if (scsi->buf_i < scsi->buf_n) {
1430 scsi->bsr |= E5380_BSR_DRQ;
1431 }
1432 }
1433 break;
1434
1435 case E5380_PHASE_DATA_OUT:
1436 if (dif & val & E5380_MR2_DMA) {
1437 if (scsi->buf_i < scsi->buf_n) {
1438 scsi->bsr |= E5380_BSR_DRQ;
1439 }
1440 }
1441 break;
1442 }
1443
1444 if (dif & ~val & E5380_MR2_DMA) {
1445 scsi->bsr &= ~E5380_BSR_DRQ;
1446 }
1447}
1448
1449static
1450void mac_scsi_set_tcr (mac_scsi_t *scsi, unsigned char val)
1451{
1452 unsigned char dif;
1453
1454 dif = scsi->tcr ^ val;
1455 scsi->tcr = val;
1456
1457 if (dif & val & E5380_TCR_CD) {
1458#ifdef DEBUG_SCSI
1459 mac_log_deb ("scsi: set c/d\n");
1460#endif
1461 if (scsi->phase == E5380_PHASE_DATA_IN) {
1462 mac_scsi_set_phase_status (scsi, 0x00);
1463 }
1464 if (scsi->phase == E5380_PHASE_DATA_OUT) {
1465 mac_scsi_set_phase_status (scsi, 0x00);
1466 }
1467 }
1468
1469#ifdef DEBUG_SCSI
1470 if (dif & ~val & E5380_TCR_CD) {
1471 mac_log_deb ("scsi: clear c/d\n");
1472 }
1473#endif
1474
1475#ifdef DEBUG_SCSI
1476 if (dif & val & E5380_TCR_IO) {
1477 mac_log_deb ("scsi: set i/o\n");
1478 }
1479#endif
1480
1481#ifdef DEBUG_SCSI
1482 if (dif & ~val & E5380_TCR_IO) {
1483 mac_log_deb ("scsi: clear i/o\n");
1484 }
1485#endif
1486
1487#ifdef DEBUG_SCSI
1488 if (dif & val & E5380_TCR_MSG) {
1489 mac_log_deb ("scsi: set msg\n");
1490 }
1491#endif
1492
1493#ifdef DEBUG_SCSI
1494 if (dif & ~val & E5380_TCR_MSG) {
1495 mac_log_deb ("scsi: clear msg\n");
1496 }
1497#endif
1498}
1499
1500static
1501void mac_scsi_set_ser (mac_scsi_t *scsi, unsigned char val)
1502{
1503 scsi->ser = val;
1504}
1505
1506void mac_scsi_set_uint8 (void *ext, unsigned long addr, unsigned char val)
1507{
1508 mac_scsi_t *scsi = ext;
1509
1510 addr = (addr & scsi->addr_mask) >> scsi->addr_shift;
1511
1512 switch (addr) {
1513 case 0x00: /* ODR */
1514 mac_scsi_set_odr (scsi, val);
1515 break;
1516
1517 case 0x01: /* ICR */
1518 mac_scsi_set_icr (scsi, val);
1519 break;
1520
1521 case 0x02: /* MR2 */
1522 mac_scsi_set_mr2 (scsi, val);
1523 break;
1524
1525 case 0x03: /* TCR */
1526 mac_scsi_set_tcr (scsi, val);
1527 break;
1528
1529 case 0x04: /* SER */
1530 mac_scsi_set_ser (scsi, val);
1531 break;
1532
1533 case 0x05: /* start dma send */
1534 scsi->bsr |= E5380_BSR_DRQ;
1535 break;
1536
1537 case 0x06: /* start dma target receive */
1538 break;
1539
1540 case 0x07: /* start dma initiator receive */
1541 break;
1542
1543 case 0x20: /* ODR with dma */
1544 mac_scsi_set_odr_dma (scsi, val);
1545 break;
1546
1547 default:
1548 mac_log_deb ("scsi: set 8: %04lX <- %02X\n", addr, val);
1549 break;
1550 }
1551}
1552
1553void mac_scsi_set_uint16 (void *ext, unsigned long addr, unsigned short val)
1554{
1555 mac_scsi_t *scsi = ext;
1556
1557 addr = (addr & scsi->addr_mask) >> scsi->addr_shift;
1558
1559#ifdef DEBUG_SCSI
1560 mac_log_deb ("scsi: set 16: %04lX <- %02X\n", addr, val);
1561#endif
1562}
1563
1564void mac_scsi_reset (mac_scsi_t *scsi)
1565{
1566#ifdef DEBUG_SCSI
1567 pce_log_deb ("scsi: reset\n");
1568#endif
1569
1570 scsi->phase = E5380_PHASE_FREE;
1571
1572 scsi->odr = 0x00;
1573 scsi->csd = 0x00;
1574 scsi->icr = 0x00;
1575 scsi->mr2 = 0x00;
1576 scsi->csb = 0x00;
1577 scsi->ser = 0x00;
1578 scsi->bsr = E5380_BSR_PHSM;
1579
1580 scsi->status = 0x00;
1581
1582 scsi->cmd_i = 0;
1583 scsi->cmd_n = 0;
1584
1585 scsi->buf_i = 0;
1586 scsi->buf_n = 0;
1587
1588 scsi->cmd_start = NULL;
1589 scsi->cmd_finish = NULL;
1590}