This source file includes following definitions.
- atascsi_attach
- atascsi_detach
- atascsi_probe
- ata_setup_identify
- ata_free_identify
- ata_complete_identify
- atascsi_cmd
- atascsi_disk_cmd
- atascsi_empty_done
- atascsi_disk_cmd_done
- atascsi_disk_inq
- atascsi_disk_inq_done
- atascsi_disk_sync
- atascsi_disk_sync_done
- atascsi_disk_capacity
- atascsi_disk_capacity_done
- atascsi_disk_sense
- atascsi_atapi_cmd
- atascsi_atapi_cmd_done
- atascsi_stuffup
- ata_exec
- ata_get_xfer
- ata_put_xfer
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #include <sys/param.h>
20 #include <sys/systm.h>
21 #include <sys/buf.h>
22 #include <sys/kernel.h>
23 #include <sys/malloc.h>
24 #include <sys/device.h>
25 #include <sys/proc.h>
26 #include <sys/queue.h>
27
28 #include <scsi/scsi_all.h>
29 #include <scsi/scsi_disk.h>
30 #include <scsi/scsiconf.h>
31
32 #include <dev/ata/atascsi.h>
33
34 struct atascsi {
35 struct device *as_dev;
36 void *as_cookie;
37
38 struct ata_port **as_ports;
39
40 struct atascsi_methods *as_methods;
41 struct scsi_adapter as_switch;
42 struct scsi_link as_link;
43 struct scsibus_softc *as_scsibus;
44
45 int as_capability;
46 };
47
48 int atascsi_cmd(struct scsi_xfer *);
49
50
51 struct scsi_adapter atascsi_switch = {
52 atascsi_cmd,
53 minphys,
54 NULL,
55 NULL,
56 NULL
57 };
58
59 struct scsi_device atascsi_device = {
60 NULL, NULL, NULL, NULL
61 };
62
63 int atascsi_probe(struct atascsi *, int);
64
65 struct ata_xfer *ata_setup_identify(struct ata_port *, int);
66 void ata_free_identify(struct ata_xfer *);
67 void ata_complete_identify(struct ata_xfer *,
68 struct ata_identify *);
69
70 int atascsi_disk_cmd(struct scsi_xfer *);
71 void atascsi_disk_cmd_done(struct ata_xfer *);
72 int atascsi_disk_inq(struct scsi_xfer *);
73 void atascsi_disk_inq_done(struct ata_xfer *);
74 int atascsi_disk_capacity(struct scsi_xfer *);
75 void atascsi_disk_capacity_done(struct ata_xfer *);
76 int atascsi_disk_sync(struct scsi_xfer *);
77 void atascsi_disk_sync_done(struct ata_xfer *);
78 int atascsi_disk_sense(struct scsi_xfer *);
79
80 void atascsi_empty_done(struct ata_xfer *);
81
82 int atascsi_atapi_cmd(struct scsi_xfer *);
83 void atascsi_atapi_cmd_done(struct ata_xfer *);
84
85 int atascsi_stuffup(struct scsi_xfer *);
86
87
88 int ata_running = 0;
89
90 int ata_exec(struct atascsi *, struct ata_xfer *);
91
92 struct ata_xfer *ata_get_xfer(struct ata_port *, int);
93 void ata_put_xfer(struct ata_xfer *);
94
95 struct atascsi *
96 atascsi_attach(struct device *self, struct atascsi_attach_args *aaa)
97 {
98 struct scsibus_attach_args saa;
99 struct atascsi *as;
100 int i;
101
102 as = malloc(sizeof(struct atascsi), M_DEVBUF, M_WAITOK);
103 bzero(as, sizeof(struct atascsi));
104
105 as->as_dev = self;
106 as->as_cookie = aaa->aaa_cookie;
107 as->as_methods = aaa->aaa_methods;
108 as->as_capability = aaa->aaa_capability;
109
110
111 as->as_switch = atascsi_switch;
112 as->as_switch.scsi_minphys = aaa->aaa_minphys;
113
114
115 as->as_link.device = &atascsi_device;
116 as->as_link.adapter = &as->as_switch;
117 as->as_link.adapter_softc = as;
118 as->as_link.adapter_buswidth = aaa->aaa_nports;
119 as->as_link.luns = 1;
120 as->as_link.adapter_target = aaa->aaa_nports;
121 as->as_link.openings = aaa->aaa_ncmds;
122 if (as->as_capability & ASAA_CAP_NEEDS_RESERVED)
123 as->as_link.openings--;
124
125 as->as_ports = malloc(sizeof(struct ata_port *) * aaa->aaa_nports,
126 M_DEVBUF, M_WAITOK);
127 bzero(as->as_ports, sizeof(struct ata_port *) * aaa->aaa_nports);
128
129
130 for (i = 0; i < as->as_link.adapter_buswidth; i++)
131 atascsi_probe(as, i);
132
133 bzero(&saa, sizeof(saa));
134 saa.saa_sc_link = &as->as_link;
135
136
137 as->as_scsibus = (struct scsibus_softc *)config_found(self, &saa,
138 scsiprint);
139
140 return (as);
141 }
142
143 int
144 atascsi_detach(struct atascsi *as)
145 {
146 return (0);
147 }
148
149 int
150 atascsi_probe(struct atascsi *as, int port)
151 {
152 struct ata_port *ap;
153 struct ata_xfer *xa;
154 int type, s;
155
156 if (port > as->as_link.adapter_buswidth)
157 return (ENXIO);
158
159 type = as->as_methods->probe(as->as_cookie, port);
160 switch (type) {
161 case ATA_PORT_T_DISK:
162 break;
163 case ATA_PORT_T_ATAPI:
164 as->as_link.flags |= SDEV_ATAPI;
165 as->as_link.quirks |= SDEV_ONLYBIG;
166 break;
167 default:
168 return (ENODEV);
169 }
170
171 ap = malloc(sizeof(struct ata_port), M_DEVBUF, M_WAITOK);
172 bzero(ap, sizeof(struct ata_port));
173 ap->ap_as = as;
174 ap->ap_port = port;
175 ap->ap_type = type;
176
177 as->as_ports[port] = ap;
178
179 s = splbio();
180 xa = ata_get_xfer(ap, 1);
181 splx(s);
182 if (xa == NULL)
183 return (EBUSY);
184
185
186
187
188
189
190
191
192 xa->fis->command = ATA_C_SEC_FREEZE_LOCK;
193 xa->fis->flags = ATA_H2D_FLAGS_CMD;
194 xa->complete = atascsi_empty_done;
195 xa->flags = ATA_F_POLL | ATA_F_PIO;
196 xa->timeout = 1000;
197 ata_exec(as, xa);
198
199 return (0);
200 }
201
202 struct ata_xfer *
203 ata_setup_identify(struct ata_port *ap, int nosleep)
204 {
205 struct ata_xfer *xa;
206 int s;
207
208 s = splbio();
209 xa = ata_get_xfer(ap, nosleep);
210 splx(s);
211 if (xa == NULL)
212 return (NULL);
213
214 xa->data = malloc(512, M_TEMP, nosleep ? M_NOWAIT : M_WAITOK);
215 if (xa->data == NULL) {
216 s = splbio();
217 xa->state = ATA_S_ERROR;
218 ata_put_xfer(xa);
219 splx(s);
220 return (NULL);
221 }
222 bzero(xa->data, 512);
223 xa->datalen = 512;
224
225 xa->fis->flags = ATA_H2D_FLAGS_CMD;
226 xa->fis->command = ATA_C_IDENTIFY;
227 xa->fis->device = 0;
228
229 xa->flags = ATA_F_READ | ATA_F_PIO;
230
231 return (xa);
232 }
233
234 void
235 ata_free_identify(struct ata_xfer *xa)
236 {
237 free(xa->data, M_TEMP);
238 ata_put_xfer(xa);
239 }
240
241 void
242 ata_complete_identify(struct ata_xfer *xa, struct ata_identify *id)
243 {
244 u_int16_t *swap;
245 int i;
246
247 bcopy(xa->data, id, sizeof(struct ata_identify));
248 ata_free_identify(xa);
249
250 swap = (u_int16_t *)id->serial;
251 for (i = 0; i < sizeof(id->serial) / sizeof(u_int16_t); i++)
252 swap[i] = swap16(swap[i]);
253
254 swap = (u_int16_t *)id->firmware;
255 for (i = 0; i < sizeof(id->firmware) / sizeof(u_int16_t); i++)
256 swap[i] = swap16(swap[i]);
257
258 swap = (u_int16_t *)id->model;
259 for (i = 0; i < sizeof(id->model) / sizeof(u_int16_t); i++)
260 swap[i] = swap16(swap[i]);
261 }
262
263 int
264 atascsi_cmd(struct scsi_xfer *xs)
265 {
266 struct scsi_link *link = xs->sc_link;
267 struct atascsi *as = link->adapter_softc;
268 struct ata_port *ap = as->as_ports[link->target];
269
270 if (ap == NULL)
271 return (atascsi_stuffup(xs));
272
273 switch (ap->ap_type) {
274 case ATA_PORT_T_DISK:
275 return (atascsi_disk_cmd(xs));
276 case ATA_PORT_T_ATAPI:
277 return (atascsi_atapi_cmd(xs));
278
279 case ATA_PORT_T_NONE:
280 default:
281 return (atascsi_stuffup(xs));
282 }
283 }
284
285 int
286 atascsi_disk_cmd(struct scsi_xfer *xs)
287 {
288 struct scsi_link *link = xs->sc_link;
289 struct atascsi *as = link->adapter_softc;
290 struct ata_port *ap = as->as_ports[link->target];
291 int s, flags = 0;
292 struct scsi_rw *rw;
293 struct scsi_rw_big *rwb;
294 struct ata_xfer *xa;
295 struct ata_fis_h2d *fis;
296 u_int64_t lba;
297 u_int32_t sector_count;
298
299 switch (xs->cmd->opcode) {
300 case READ_BIG:
301 case READ_COMMAND:
302 flags = ATA_F_READ;
303 break;
304 case WRITE_BIG:
305 case WRITE_COMMAND:
306 flags = ATA_F_WRITE;
307
308 break;
309
310 case SYNCHRONIZE_CACHE:
311 return (atascsi_disk_sync(xs));
312 case REQUEST_SENSE:
313 return (atascsi_disk_sense(xs));
314 case INQUIRY:
315 return (atascsi_disk_inq(xs));
316 case READ_CAPACITY:
317 return (atascsi_disk_capacity(xs));
318
319 case TEST_UNIT_READY:
320 case START_STOP:
321 case PREVENT_ALLOW:
322 return (COMPLETE);
323
324 default:
325 return (atascsi_stuffup(xs));
326 }
327
328 s = splbio();
329 xa = ata_get_xfer(ap, xs->flags & SCSI_NOSLEEP);
330 splx(s);
331 if (xa == NULL)
332 return (NO_CCB);
333
334 xa->flags = flags;
335 if (xs->cmdlen == 6) {
336 rw = (struct scsi_rw *)xs->cmd;
337 lba = _3btol(rw->addr) & (SRW_TOPADDR << 16 | 0xffff);
338 sector_count = rw->length ? rw->length : 0x100;
339 } else {
340 rwb = (struct scsi_rw_big *)xs->cmd;
341 lba = _4btol(rwb->addr);
342 sector_count = _2btol(rwb->length);
343 }
344
345 fis = xa->fis;
346
347 fis->flags = ATA_H2D_FLAGS_CMD;
348 fis->lba_low = lba & 0xff;
349 fis->lba_mid = (lba >> 8) & 0xff;
350 fis->lba_high = (lba >> 16) & 0xff;
351
352 if (ap->ap_ncqdepth && !(xs->flags & SCSI_POLL)) {
353
354 xa->flags |= ATA_F_NCQ;
355 fis->command = (xa->flags & ATA_F_WRITE) ?
356 ATA_C_WRITE_FPDMA : ATA_C_READ_FPDMA;
357 fis->device = ATA_H2D_DEVICE_LBA;
358 fis->lba_low_exp = (lba >> 24) & 0xff;
359 fis->lba_mid_exp = (lba >> 32) & 0xff;
360 fis->lba_high_exp = (lba >> 40) & 0xff;
361 fis->sector_count = xa->tag << 3;
362 fis->features = sector_count & 0xff;
363 fis->features_exp = (sector_count >> 8) & 0xff;
364 } else if (sector_count > 0x100 || lba > 0xfffffff) {
365
366 fis->command = (xa->flags & ATA_F_WRITE) ?
367 ATA_C_WRITEDMA_EXT : ATA_C_READDMA_EXT;
368 fis->device = ATA_H2D_DEVICE_LBA;
369 fis->lba_low_exp = (lba >> 24) & 0xff;
370 fis->lba_mid_exp = (lba >> 32) & 0xff;
371 fis->lba_high_exp = (lba >> 40) & 0xff;
372 fis->sector_count = sector_count & 0xff;
373 fis->sector_count_exp = (sector_count >> 8) & 0xff;
374 } else {
375
376 fis->command = (xa->flags & ATA_F_WRITE) ?
377 ATA_C_WRITEDMA : ATA_C_READDMA;
378 fis->device = ATA_H2D_DEVICE_LBA | ((lba >> 24) & 0x0f);
379 fis->sector_count = sector_count & 0xff;
380 }
381
382 xa->data = xs->data;
383 xa->datalen = xs->datalen;
384 xa->complete = atascsi_disk_cmd_done;
385 xa->timeout = xs->timeout;
386 xa->atascsi_private = xs;
387 if (xs->flags & SCSI_POLL)
388 xa->flags |= ATA_F_POLL;
389
390 return (ata_exec(as, xa));
391 }
392
393 void
394 atascsi_empty_done(struct ata_xfer *xa)
395 {
396 ata_put_xfer(xa);
397 }
398
399 void
400 atascsi_disk_cmd_done(struct ata_xfer *xa)
401 {
402 struct scsi_xfer *xs = xa->atascsi_private;
403
404 switch (xa->state) {
405 case ATA_S_COMPLETE:
406 xs->error = XS_NOERROR;
407 break;
408 case ATA_S_ERROR:
409
410 xs->error = XS_DRIVER_STUFFUP;
411 break;
412 case ATA_S_TIMEOUT:
413 xs->error = XS_TIMEOUT;
414 break;
415 default:
416 panic("atascsi_disk_cmd_done: unexpected ata_xfer state (%d)",
417 xa->state);
418 }
419
420 xs->resid = xa->resid;
421 ata_put_xfer(xa);
422
423 xs->flags |= ITSDONE;
424 scsi_done(xs);
425 }
426
427 int
428 atascsi_disk_inq(struct scsi_xfer *xs)
429 {
430 struct scsi_link *link = xs->sc_link;
431 struct atascsi *as = link->adapter_softc;
432 struct ata_port *ap = as->as_ports[link->target];
433 struct ata_xfer *xa;
434
435 xa = ata_setup_identify(ap, xs->flags & SCSI_NOSLEEP);
436 if (xa == NULL)
437 return (NO_CCB);
438
439 xa->complete = atascsi_disk_inq_done;
440 xa->timeout = xs->timeout;
441 xa->atascsi_private = xs;
442 if (xs->flags & SCSI_POLL)
443 xa->flags |= ATA_F_POLL;
444
445 return (ata_exec(as, xa));
446 }
447
448 void
449 atascsi_disk_inq_done(struct ata_xfer *xa)
450 {
451 struct scsi_xfer *xs = xa->atascsi_private;
452 struct scsi_link *link = xs->sc_link;
453 struct atascsi *as = link->adapter_softc;
454 struct ata_port *ap = as->as_ports[link->target];
455 struct ata_identify id;
456 struct scsi_inquiry_data inq;
457 int host_ncqdepth, complete = 0;
458
459 switch (xa->state) {
460 case ATA_S_COMPLETE:
461 ata_complete_identify(xa, &id);
462
463 bzero(&inq, sizeof(inq));
464
465 inq.device = T_DIRECT;
466 inq.version = 2;
467 inq.response_format = 2;
468 inq.additional_length = 32;
469 bcopy("ATA ", inq.vendor, sizeof(inq.vendor));
470 bcopy(id.model, inq.product, sizeof(inq.product));
471 bcopy(id.firmware, inq.revision, sizeof(inq.revision));
472
473 bcopy(&inq, xs->data, MIN(sizeof(inq), xs->datalen));
474 xs->error = XS_NOERROR;
475 complete = 1;
476 break;
477
478 case ATA_S_ERROR:
479 case ATA_S_TIMEOUT:
480 ata_free_identify(xa);
481 xs->error = (xa->state == ATA_S_TIMEOUT ? XS_TIMEOUT :
482 XS_DRIVER_STUFFUP);
483 break;
484
485 default:
486 panic("atascsi_disk_inq_done: unexpected ata_xfer state (%d)",
487 xa->state);
488 }
489
490 xs->flags |= ITSDONE;
491 scsi_done(xs);
492
493 if (!complete || (ap->ap_features & ATA_PORT_F_PROBED))
494 return;
495
496 ap->ap_features = ATA_PORT_F_PROBED;
497
498 if (as->as_capability & ASAA_CAP_NCQ && (letoh16(id.satacap) &
499 (1 << 8))) {
500
501
502
503
504
505
506 host_ncqdepth = link->openings + 1 + ((as->as_capability &
507 ASAA_CAP_NEEDS_RESERVED) ? 1 : 0);
508
509 ap->ap_ncqdepth = (letoh16(id.qdepth) & 0x1f) + 1;
510
511
512 if (host_ncqdepth > ap->ap_ncqdepth)
513 link->openings -= (host_ncqdepth - ap->ap_ncqdepth);
514
515
516
517
518
519 while (host_ncqdepth--) {
520 struct ata_xfer *xa;
521
522 xa = ata_get_xfer(ap, 1);
523 if (xa->tag < ap->ap_ncqdepth) {
524 xa->state = ATA_S_COMPLETE;
525 ata_put_xfer(xa);
526 }
527 }
528 }
529 }
530
531 int
532 atascsi_disk_sync(struct scsi_xfer *xs)
533 {
534 struct scsi_link *link = xs->sc_link;
535 struct atascsi *as = link->adapter_softc;
536 struct ata_port *ap = as->as_ports[link->target];
537 struct ata_xfer *xa;
538 int s;
539
540 s = splbio();
541 xa = ata_get_xfer(ap, xs->flags & SCSI_NOSLEEP);
542 splx(s);
543 if (xa == NULL)
544 return (NO_CCB);
545
546 xa->datalen = 0;
547 xa->flags = ATA_F_READ;
548 xa->complete = atascsi_disk_sync_done;
549
550 xa->timeout = (xs->timeout < 45000) ? 45000 : xs->timeout;
551 xa->atascsi_private = xs;
552 if (xs->flags & SCSI_POLL)
553 xa->flags |= ATA_F_POLL;
554
555 xa->fis->flags = ATA_H2D_FLAGS_CMD;
556 xa->fis->command = ATA_C_FLUSH_CACHE;
557 xa->fis->device = 0;
558
559 return (ata_exec(as, xa));
560 }
561
562 void
563 atascsi_disk_sync_done(struct ata_xfer *xa)
564 {
565 struct scsi_xfer *xs = xa->atascsi_private;
566
567 switch (xa->state) {
568 case ATA_S_COMPLETE:
569 xs->error = XS_NOERROR;
570 break;
571
572 case ATA_S_ERROR:
573 case ATA_S_TIMEOUT:
574 printf("atascsi_disk_sync_done: %s\n",
575 xa->state == ATA_S_TIMEOUT ? "timeout" : "error");
576 xs->error = (xa->state == ATA_S_TIMEOUT ? XS_TIMEOUT :
577 XS_DRIVER_STUFFUP);
578 break;
579
580 default:
581 panic("atascsi_disk_sync_done: unexpected ata_xfer state (%d)",
582 xa->state);
583 }
584
585 ata_put_xfer(xa);
586
587 xs->flags |= ITSDONE;
588 scsi_done(xs);
589 }
590
591 int
592 atascsi_disk_capacity(struct scsi_xfer *xs)
593 {
594 struct scsi_link *link = xs->sc_link;
595 struct atascsi *as = link->adapter_softc;
596 struct ata_port *ap = as->as_ports[link->target];
597 struct ata_xfer *xa;
598
599 xa = ata_setup_identify(ap, xs->flags & SCSI_NOSLEEP);
600 if (xa == NULL)
601 return (NO_CCB);
602
603 xa->complete = atascsi_disk_capacity_done;
604 xa->timeout = xs->timeout;
605 xa->atascsi_private = xs;
606 if (xs->flags & SCSI_POLL)
607 xa->flags |= ATA_F_POLL;
608
609 return (ata_exec(as, xa));
610 }
611
612 void
613 atascsi_disk_capacity_done(struct ata_xfer *xa)
614 {
615 struct scsi_xfer *xs = xa->atascsi_private;
616 struct ata_identify id;
617 struct scsi_read_cap_data rcd;
618 u_int64_t capacity;
619 int i;
620
621 switch (xa->state) {
622 case ATA_S_COMPLETE:
623 ata_complete_identify(xa, &id);
624
625 bzero(&rcd, sizeof(rcd));
626 if (letoh16(id.cmdset83) & 0x0400) {
627
628 for (i = 3; i >= 0; --i) {
629 capacity <<= 16;
630 capacity += letoh16(id.addrsecxt[i]);
631 }
632 } else {
633 capacity = letoh16(id.addrsec[1]);
634 capacity <<= 16;
635 capacity += letoh16(id.addrsec[0]);
636 }
637
638
639 if (capacity > 0xffffffff)
640 capacity = 0xffffffff;
641
642 _lto4b(capacity - 1, rcd.addr);
643 _lto4b(512, rcd.length);
644
645 bcopy(&rcd, xs->data, MIN(sizeof(rcd), xs->datalen));
646 xs->error = XS_NOERROR;
647 break;
648
649 case ATA_S_ERROR:
650 case ATA_S_TIMEOUT:
651 ata_free_identify(xa);
652 xs->error = (xa->state == ATA_S_TIMEOUT ? XS_TIMEOUT :
653 XS_DRIVER_STUFFUP);
654 break;
655
656 default:
657 panic("atascsi_disk_capacity_done: "
658 "unexpected ata_xfer state (%d)", xa->state);
659 }
660
661 xs->flags |= ITSDONE;
662 scsi_done(xs);
663 }
664
665 int
666 atascsi_disk_sense(struct scsi_xfer *xs)
667 {
668 struct scsi_sense_data *sd = (struct scsi_sense_data *)xs->data;
669 int s;
670
671 bzero(xs->data, xs->datalen);
672
673 sd->error_code = 0x70;
674 sd->flags = SKEY_NO_SENSE;
675
676 xs->error = XS_NOERROR;
677 xs->flags |= ITSDONE;
678
679 s = splbio();
680 scsi_done(xs);
681 splx(s);
682 return (COMPLETE);
683 }
684
685 int
686 atascsi_atapi_cmd(struct scsi_xfer *xs)
687 {
688 struct scsi_link *link = xs->sc_link;
689 struct atascsi *as = link->adapter_softc;
690 struct ata_port *ap = as->as_ports[link->target];
691 int s;
692 struct ata_xfer *xa;
693 struct ata_fis_h2d *fis;
694
695 s = splbio();
696 xa = ata_get_xfer(ap, xs->flags & SCSI_NOSLEEP);
697 splx(s);
698 if (xa == NULL)
699 return (NO_CCB);
700
701 switch (xs->flags & (SCSI_DATA_IN | SCSI_DATA_OUT)) {
702 case SCSI_DATA_IN:
703 xa->flags = ATA_F_PACKET | ATA_F_READ;
704 break;
705 case SCSI_DATA_OUT:
706 xa->flags = ATA_F_PACKET | ATA_F_WRITE;
707 break;
708 default:
709 xa->flags = ATA_F_PACKET;
710 }
711
712 xa->data = xs->data;
713 xa->datalen = xs->datalen;
714 xa->complete = atascsi_atapi_cmd_done;
715 xa->timeout = xs->timeout;
716 xa->atascsi_private = xs;
717 if (xs->flags & SCSI_POLL)
718 xa->flags |= ATA_F_POLL;
719
720 fis = xa->fis;
721 fis->flags = ATA_H2D_FLAGS_CMD;
722 fis->command = ATA_C_PACKET;
723 fis->device = 0;
724 fis->sector_count = xa->tag << 3;
725 fis->features = ATA_H2D_FEATURES_DMA | ((xa->flags & ATA_F_WRITE) ?
726 ATA_H2D_FEATURES_DIR_WRITE : ATA_H2D_FEATURES_DIR_READ);
727 fis->lba_mid = 0x00;
728 fis->lba_high = 0x20;
729
730
731 memcpy(xa->packetcmd, xs->cmd, xs->cmdlen);
732
733 return (ata_exec(as, xa));
734 }
735
736 void
737 atascsi_atapi_cmd_done(struct ata_xfer *xa)
738 {
739 struct scsi_xfer *xs = xa->atascsi_private;
740 struct scsi_sense_data *sd = &xs->sense;
741
742 switch (xa->state) {
743 case ATA_S_COMPLETE:
744 xs->error = XS_NOERROR;
745 break;
746 case ATA_S_ERROR:
747
748 sd->error_code = SSD_ERRCODE_CURRENT;
749 sd->flags = (xa->rfis.error & 0xf0) >> 4;
750 if (xa->rfis.error & 0x04)
751 sd->flags = SKEY_ILLEGAL_REQUEST;
752 if (xa->rfis.error & 0x02)
753 sd->flags |= SSD_EOM;
754 if (xa->rfis.error & 0x01)
755 sd->flags |= SSD_ILI;
756 xs->error = XS_SENSE;
757 break;
758 case ATA_S_TIMEOUT:
759 printf("atascsi_atapi_cmd_done, timeout\n");
760 xs->error = XS_TIMEOUT;
761 break;
762 default:
763 panic("atascsi_atapi_cmd_done: unexpected ata_xfer state (%d)",
764 xa->state);
765 }
766
767 xs->resid = xa->resid;
768 ata_put_xfer(xa);
769
770 xs->flags |= ITSDONE;
771 scsi_done(xs);
772 }
773
774 int
775 atascsi_stuffup(struct scsi_xfer *xs)
776 {
777 int s;
778
779 xs->error = XS_DRIVER_STUFFUP;
780 xs->flags |= ITSDONE;
781
782 s = splbio();
783 scsi_done(xs);
784 splx(s);
785 return (COMPLETE);
786 }
787
788 int
789 ata_exec(struct atascsi *as, struct ata_xfer *xa)
790 {
791 int polled = xa->flags & ATA_F_POLL;
792
793 switch (as->as_methods->ata_cmd(xa)) {
794 case ATA_COMPLETE:
795 case ATA_ERROR:
796 return (COMPLETE);
797 case ATA_QUEUED:
798 if (!polled)
799 return (SUCCESSFULLY_QUEUED);
800 default:
801 panic("unexpected return from ata_exec");
802 }
803 }
804
805 struct ata_xfer *
806 ata_get_xfer(struct ata_port *ap, int nosleep )
807 {
808 struct atascsi *as = ap->ap_as;
809 struct ata_xfer *xa;
810
811 xa = as->as_methods->ata_get_xfer(as->as_cookie, ap->ap_port);
812 if (xa != NULL)
813 xa->fis->type = ATA_FIS_TYPE_H2D;
814
815 return (xa);
816 }
817
818 void
819 ata_put_xfer(struct ata_xfer *xa)
820 {
821 xa->ata_put_xfer(xa);
822 }