This source file includes following definitions.
- wdc_log
- wdc_get_log
- wdc_default_read_reg
- wdc_default_write_reg
- wdc_default_lba48_write_reg
- wdc_default_read_raw_multi_2
- wdc_default_write_raw_multi_2
- wdc_default_write_raw_multi_4
- wdc_default_read_raw_multi_4
- wdprint
- wdc_disable_intr
- wdc_enable_intr
- wdc_set_drive
- wdc_floating_bus
- wdc_preata_drive
- wdc_ata_present
- wdcprobe
- wdcactivate
- wdcattach
- wdcstart
- wdcdetach
- wdcintr
- wdc_reset_channel
- wdcreset
- wdc_do_reset
- __wdcwait_reset
- wdc_wait_for_status
- wdc_dmawait
- wdctimeout
- wdc_probe_caps
- wdc_output_bytes
- wdc_input_bytes
- wdc_print_caps
- wdc_print_current_modes
- wdc_downgrade_mode
- wdc_exec_command
- __wdccommand_start
- __wdccommand_intr
- __wdccommand_done
- wdccommand
- wdccommandext
- wdccommandshort
- wdc_exec_xfer
- wdc_get_xfer
- wdc_free_xfer
- wdc_kill_pending
- __wdcerror
- wdcbit_bucket
- LIST_HEAD
- wdc_ioctl_free
- wdc_ioctl_find
- wdc_ioctl_strategy
- wdc_ioctl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70 #include <sys/param.h>
71 #include <sys/systm.h>
72 #include <sys/kernel.h>
73 #include <sys/conf.h>
74 #include <sys/buf.h>
75 #include <sys/device.h>
76 #include <sys/malloc.h>
77 #include <sys/syslog.h>
78 #include <sys/proc.h>
79 #include <sys/pool.h>
80 #include <uvm/uvm_extern.h>
81
82 #include <machine/intr.h>
83 #include <machine/bus.h>
84
85 #include <dev/ata/atavar.h>
86 #include <dev/ata/atareg.h>
87 #include <dev/ic/wdcreg.h>
88 #include <dev/ic/wdcvar.h>
89 #include <dev/ic/wdcevent.h>
90
91 #include "atapiscsi.h"
92
93 #define WDCDELAY 100
94 #define WDCNDELAY_RST (WDC_RESET_WAIT * 1000 / WDCDELAY)
95 #if 0
96
97 #define WDCNDELAY_DEBUG 50
98 #endif
99
100 struct pool wdc_xfer_pool;
101
102 void __wdcerror(struct channel_softc *, char *);
103 int __wdcwait_reset(struct channel_softc *, int);
104 void __wdccommand_done(struct channel_softc *, struct wdc_xfer *);
105 void __wdccommand_start(struct channel_softc *, struct wdc_xfer *);
106 int __wdccommand_intr(struct channel_softc *, struct wdc_xfer *, int);
107 int wdprint(void *, const char *);
108 void wdc_kill_pending(struct channel_softc *);
109
110 #define DEBUG_INTR 0x01
111 #define DEBUG_XFERS 0x02
112 #define DEBUG_STATUS 0x04
113 #define DEBUG_FUNCS 0x08
114 #define DEBUG_PROBE 0x10
115 #define DEBUG_STATUSX 0x20
116 #define DEBUG_SDRIVE 0x40
117 #define DEBUG_DETACH 0x80
118
119 #ifdef WDCDEBUG
120 #ifndef WDCDEBUG_MASK
121 #define WDCDEBUG_MASK 0x00
122 #endif
123 int wdcdebug_mask = WDCDEBUG_MASK;
124 int wdc_nxfer = 0;
125 #define WDCDEBUG_PRINT(args, level) do { \
126 if ((wdcdebug_mask & (level)) != 0) \
127 printf args; \
128 } while (0)
129 #else
130 #define WDCDEBUG_PRINT(args, level)
131 #endif
132
133 int at_poll = AT_POLL;
134
135 int wdc_floating_bus(struct channel_softc *, int);
136 int wdc_preata_drive(struct channel_softc *, int);
137 int wdc_ata_present(struct channel_softc *, int);
138
139 struct channel_softc_vtbl wdc_default_vtbl = {
140 wdc_default_read_reg,
141 wdc_default_write_reg,
142 wdc_default_lba48_write_reg,
143 wdc_default_read_raw_multi_2,
144 wdc_default_write_raw_multi_2,
145 wdc_default_read_raw_multi_4,
146 wdc_default_write_raw_multi_4
147 };
148
149 static char *wdc_log_buf = NULL;
150 static unsigned int wdc_tail = 0;
151 static unsigned int wdc_head = 0;
152 static unsigned int wdc_log_cap = 16 * 1024;
153 static int chp_idx = 1;
154
155 void
156 wdc_log(struct channel_softc *chp, enum wdcevent_type type,
157 unsigned int size, char val[])
158 {
159 unsigned int request_size;
160 char *ptr;
161 int log_size;
162 unsigned int head = wdc_head;
163 unsigned int tail = wdc_tail;
164
165 #ifdef DIAGNOSTIC
166 if (head < 0 || head > wdc_log_cap ||
167 tail < 0 || tail > wdc_log_cap) {
168 printf ("wdc_log: head %x wdc_tail %x\n", head,
169 tail);
170 return;
171 }
172
173 if (size > wdc_log_cap / 2) {
174 printf ("wdc_log: type %d size %x\n", type, size);
175 return;
176 }
177 #endif
178
179 if (wdc_log_buf == NULL) {
180 wdc_log_buf = malloc(wdc_log_cap, M_DEVBUF, M_NOWAIT);
181 if (wdc_log_buf == NULL)
182 return;
183 }
184 if (chp->ch_log_idx == 0)
185 chp->ch_log_idx = chp_idx++;
186
187 request_size = size + 2;
188
189
190 log_size = head - tail;
191 if (log_size < 0) log_size += wdc_log_cap;
192
193 if (log_size + request_size >= wdc_log_cap) {
194 int nb = 0;
195 int rec_size;
196
197 while (nb <= (request_size * 2)) {
198 if (wdc_log_buf[tail] == 0)
199 rec_size = 1;
200 else
201 rec_size = (wdc_log_buf[tail + 1] & 0x1f) + 2;
202 tail = (tail + rec_size) % wdc_log_cap;
203 nb += rec_size;
204 }
205 }
206
207
208 if (head + request_size >= wdc_log_cap) {
209 memset(&wdc_log_buf[head], 0, wdc_log_cap - head);
210 head = 0;
211 }
212
213 ptr = &wdc_log_buf[head];
214 *ptr++ = type & 0xff;
215 *ptr++ = ((chp->ch_log_idx & 0x7) << 5) | (size & 0x1f);
216 memcpy(ptr, val, size);
217
218 wdc_head = (head + request_size) % wdc_log_cap;
219 wdc_tail = tail;
220 }
221
222 char *wdc_get_log(unsigned int *, unsigned int *);
223
224 char *
225 wdc_get_log(unsigned int * size, unsigned int *left)
226 {
227 int log_size;
228 char *retbuf = NULL;
229 int nb, tocopy;
230 int s;
231 unsigned int head = wdc_head;
232 unsigned int tail = wdc_tail;
233
234 s = splbio();
235
236 log_size = (head - tail);
237 if (left != NULL)
238 *left = 0;
239
240 if (log_size < 0)
241 log_size += wdc_log_cap;
242
243 tocopy = log_size;
244 if ((u_int)tocopy > *size)
245 tocopy = *size;
246
247 if (wdc_log_buf == NULL) {
248 *size = 0;
249 *left = 0;
250 goto out;
251 }
252
253 #ifdef DIAGNOSTIC
254 if (head < 0 || head > wdc_log_cap ||
255 tail < 0 || tail > wdc_log_cap) {
256 printf ("wdc_log: head %x tail %x\n", head,
257 tail);
258 *size = 0;
259 *left = 0;
260 goto out;
261 }
262 #endif
263
264 retbuf = malloc(tocopy, M_TEMP, M_NOWAIT);
265 if (retbuf == NULL) {
266 *size = 0;
267 *left = log_size;
268 goto out;
269 }
270
271 nb = 0;
272 for (;;) {
273 int rec_size;
274
275 if (wdc_log_buf[tail] == 0)
276 rec_size = 1;
277 else
278 rec_size = (wdc_log_buf[tail + 1] & 0x1f) + 2;
279
280 if ((nb + rec_size) >= tocopy)
281 break;
282
283 memcpy(&retbuf[nb], &wdc_log_buf[tail], rec_size);
284 tail = (tail + rec_size) % wdc_log_cap;
285 nb += rec_size;
286 }
287
288 wdc_tail = tail;
289 *size = nb;
290 *left = log_size - nb;
291
292 out:
293 splx(s);
294 return (retbuf);
295 }
296
297
298 u_int8_t
299 wdc_default_read_reg(chp, reg)
300 struct channel_softc *chp;
301 enum wdc_regs reg;
302 {
303 #ifdef DIAGNOSTIC
304 if (reg & _WDC_WRONLY) {
305 printf ("wdc_default_read_reg: reading from a write-only register %d\n", reg);
306 }
307 #endif
308
309 if (reg & _WDC_AUX)
310 return (bus_space_read_1(chp->ctl_iot, chp->ctl_ioh,
311 reg & _WDC_REGMASK));
312 else
313 return (bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
314 reg & _WDC_REGMASK));
315 }
316
317 void
318 wdc_default_write_reg(chp, reg, val)
319 struct channel_softc *chp;
320 enum wdc_regs reg;
321 u_int8_t val;
322 {
323 #ifdef DIAGNOSTIC
324 if (reg & _WDC_RDONLY) {
325 printf ("wdc_default_write_reg: writing to a read-only register %d\n", reg);
326 }
327 #endif
328
329 if (reg & _WDC_AUX)
330 bus_space_write_1(chp->ctl_iot, chp->ctl_ioh,
331 reg & _WDC_REGMASK, val);
332 else
333 bus_space_write_1(chp->cmd_iot, chp->cmd_ioh,
334 reg & _WDC_REGMASK, val);
335 }
336
337 void
338 wdc_default_lba48_write_reg(chp, reg, val)
339 struct channel_softc *chp;
340 enum wdc_regs reg;
341 u_int16_t val;
342 {
343
344 CHP_WRITE_REG(chp, reg, val >> 8);
345 CHP_WRITE_REG(chp, reg, val);
346 }
347
348 void
349 wdc_default_read_raw_multi_2(chp, data, nbytes)
350 struct channel_softc *chp;
351 void *data;
352 unsigned int nbytes;
353 {
354 if (data == NULL) {
355 unsigned int i;
356
357 for (i = 0; i < nbytes; i += 2) {
358 bus_space_read_2(chp->cmd_iot, chp->cmd_ioh, 0);
359 }
360
361 return;
362 }
363
364 bus_space_read_raw_multi_2(chp->cmd_iot, chp->cmd_ioh, 0,
365 data, nbytes);
366 }
367
368
369 void
370 wdc_default_write_raw_multi_2(chp, data, nbytes)
371 struct channel_softc *chp;
372 void *data;
373 unsigned int nbytes;
374 {
375 if (data == NULL) {
376 unsigned int i;
377
378 for (i = 0; i < nbytes; i += 2) {
379 bus_space_write_2(chp->cmd_iot, chp->cmd_ioh, 0, 0);
380 }
381
382 return;
383 }
384
385 bus_space_write_raw_multi_2(chp->cmd_iot, chp->cmd_ioh, 0,
386 data, nbytes);
387 }
388
389
390 void
391 wdc_default_write_raw_multi_4(chp, data, nbytes)
392 struct channel_softc *chp;
393 void *data;
394 unsigned int nbytes;
395 {
396 if (data == NULL) {
397 unsigned int i;
398
399 for (i = 0; i < nbytes; i += 4) {
400 bus_space_write_4(chp->cmd_iot, chp->cmd_ioh, 0, 0);
401 }
402
403 return;
404 }
405
406 bus_space_write_raw_multi_4(chp->cmd_iot, chp->cmd_ioh, 0,
407 data, nbytes);
408 }
409
410
411 void
412 wdc_default_read_raw_multi_4(chp, data, nbytes)
413 struct channel_softc *chp;
414 void *data;
415 unsigned int nbytes;
416 {
417 if (data == NULL) {
418 unsigned int i;
419
420 for (i = 0; i < nbytes; i += 4) {
421 bus_space_read_4(chp->cmd_iot, chp->cmd_ioh, 0);
422 }
423
424 return;
425 }
426
427 bus_space_read_raw_multi_4(chp->cmd_iot, chp->cmd_ioh, 0,
428 data, nbytes);
429 }
430
431
432 int
433 wdprint(aux, pnp)
434 void *aux;
435 const char *pnp;
436 {
437 struct ata_atapi_attach *aa_link = aux;
438 if (pnp)
439 printf("drive at %s", pnp);
440 printf(" channel %d drive %d", aa_link->aa_channel,
441 aa_link->aa_drv_data->drive);
442 return (UNCONF);
443 }
444
445 void
446 wdc_disable_intr(chp)
447 struct channel_softc *chp;
448 {
449 CHP_WRITE_REG(chp, wdr_ctlr, WDCTL_IDS);
450 }
451
452 void
453 wdc_enable_intr(chp)
454 struct channel_softc *chp;
455 {
456 CHP_WRITE_REG(chp, wdr_ctlr, WDCTL_4BIT);
457 }
458
459 void
460 wdc_set_drive(struct channel_softc *chp, int drive)
461 {
462 CHP_WRITE_REG(chp, wdr_sdh, (drive << 4) | WDSD_IBM);
463 WDC_LOG_SET_DRIVE(chp, drive);
464 }
465
466 int
467 wdc_floating_bus(chp, drive)
468 struct channel_softc *chp;
469 int drive;
470
471 {
472 u_int8_t cumulative_status, status;
473 int iter;
474
475 wdc_set_drive(chp, drive);
476 delay(10);
477
478
479 cumulative_status = 0;
480 for (iter = 0; iter < 100; iter++) {
481 CHP_WRITE_REG(chp, wdr_seccnt, 0x7f);
482 delay (1);
483
484 status = CHP_READ_REG(chp, wdr_status);
485
486
487 if (status & WDCS_BSY)
488 continue;
489
490 cumulative_status |= status;
491
492 #define BAD_BIT_COMBO (WDCS_DRDY | WDCS_DSC | WDCS_DRQ | WDCS_ERR)
493 if ((cumulative_status & BAD_BIT_COMBO) == BAD_BIT_COMBO)
494 return 1;
495 }
496
497
498 return 0;
499 }
500
501
502 int
503 wdc_preata_drive(chp, drive)
504 struct channel_softc *chp;
505 int drive;
506
507 {
508 if (wdc_floating_bus(chp, drive)) {
509 WDCDEBUG_PRINT(("%s:%d:%d: floating bus detected\n",
510 chp->wdc->sc_dev.dv_xname,
511 chp->channel, drive), DEBUG_PROBE);
512 return 0;
513 }
514
515 wdc_set_drive(chp, drive);
516 delay(100);
517 if (wdcwait(chp, WDCS_DRDY | WDCS_DRQ, WDCS_DRDY, 10000) != 0) {
518 WDCDEBUG_PRINT(("%s:%d:%d: not ready\n",
519 chp->wdc->sc_dev.dv_xname,
520 chp->channel, drive), DEBUG_PROBE);
521 return 0;
522 }
523
524 CHP_WRITE_REG(chp, wdr_command, WDCC_RECAL);
525 WDC_LOG_ATA_CMDSHORT(chp, WDCC_RECAL);
526 if (wdcwait(chp, WDCS_DRDY | WDCS_DRQ, WDCS_DRDY, 10000) != 0) {
527 WDCDEBUG_PRINT(("%s:%d:%d: WDCC_RECAL failed\n",
528 chp->wdc->sc_dev.dv_xname,
529 chp->channel, drive), DEBUG_PROBE);
530 return 0;
531 }
532
533 return 1;
534 }
535
536 int
537 wdc_ata_present(chp, drive)
538 struct channel_softc *chp;
539 int drive;
540 {
541 int time_to_done;
542 int retry_cnt = 0;
543
544 wdc_set_drive(chp, drive);
545 delay(10);
546
547 retry:
548
549
550
551
552
553
554
555
556
557 time_to_done = wdc_wait_for_status(chp,
558 (WDCS_DRDY | WDCS_DSC | WDCS_DRQ),
559 (WDCS_DRDY | WDCS_DSC), 1000);
560 if (time_to_done == -1) {
561 if (retry_cnt == 0 && chp->ch_status == 0x00) {
562
563 wdccommandshort(chp, drive, WDCC_CHECK_PWR);
564 retry_cnt++;
565 goto retry;
566 }
567 WDCDEBUG_PRINT(("%s:%d:%d: DRDY test timed out with status"
568 " %02x\n",
569 chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe",
570 chp->channel, drive, chp->ch_status),
571 DEBUG_PROBE);
572 return 0;
573 }
574
575 if ((chp->ch_status & 0xfc) != (WDCS_DRDY | WDCS_DSC)) {
576 WDCDEBUG_PRINT(("%s:%d:%d: status test for 0x50 failed with"
577 " %02x\n",
578 chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe",
579 chp->channel, drive, chp->ch_status),
580 DEBUG_PROBE);
581
582 return 0;
583 }
584
585 WDCDEBUG_PRINT(("%s:%d:%d: waiting for ready %d msec\n",
586 chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe",
587 chp->channel, drive, time_to_done), DEBUG_PROBE);
588
589
590
591
592 CHP_WRITE_REG(chp, wdr_cyl_lo, 0xaa);
593 CHP_WRITE_REG(chp, wdr_cyl_hi, 0x55);
594 CHP_WRITE_REG(chp, wdr_seccnt, 0xff);
595 DELAY(10);
596
597 if (CHP_READ_REG(chp, wdr_cyl_lo) != 0xaa &&
598 CHP_READ_REG(chp, wdr_cyl_hi) != 0x55) {
599 WDCDEBUG_PRINT(("%s:%d:%d: register writability failed\n",
600 chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe",
601 chp->channel, drive), DEBUG_PROBE);
602 return 0;
603 }
604
605 return 1;
606 }
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624 int
625 wdcprobe(chp)
626 struct channel_softc *chp;
627 {
628 u_int8_t st0, st1, sc, sn, cl, ch;
629 u_int8_t ret_value = 0x03;
630 u_int8_t drive;
631 #ifdef WDCDEBUG
632 int savedmask = wdcdebug_mask;
633 #endif
634
635 if (chp->_vtbl == 0) {
636 int s = splbio();
637 chp->_vtbl = &wdc_default_vtbl;
638 splx(s);
639 }
640
641 #ifdef WDCDEBUG
642 if ((chp->ch_flags & WDCF_VERBOSE_PROBE) ||
643 (chp->wdc &&
644 (chp->wdc->sc_dev.dv_cfdata->cf_flags & WDC_OPTION_PROBE_VERBOSE)))
645 wdcdebug_mask |= DEBUG_PROBE;
646 #endif
647
648 if (chp->wdc == NULL ||
649 (chp->wdc->cap & WDC_CAPABILITY_NO_EXTRA_RESETS) == 0) {
650
651 wdc_set_drive(chp, 0);
652 delay(10);
653 st0 = CHP_READ_REG(chp, wdr_status);
654 WDC_LOG_STATUS(chp, st0);
655 wdc_set_drive(chp, 1);
656 delay(10);
657 st1 = CHP_READ_REG(chp, wdr_status);
658 WDC_LOG_STATUS(chp, st1);
659
660 WDCDEBUG_PRINT(("%s:%d: before reset, st0=0x%b, st1=0x%b\n",
661 chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe",
662 chp->channel, st0, WDCS_BITS, st1, WDCS_BITS),
663 DEBUG_PROBE);
664
665 if (st0 == 0xff || st0 == WDSD_IBM)
666 ret_value &= ~0x01;
667 if (st1 == 0xff || st1 == (WDSD_IBM | 0x10))
668 ret_value &= ~0x02;
669 if (ret_value == 0)
670 return 0;
671 }
672
673
674 wdc_do_reset(chp);
675
676 ret_value = __wdcwait_reset(chp, ret_value);
677 WDCDEBUG_PRINT(("%s:%d: after reset, ret_value=0x%d\n",
678 chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe", chp->channel,
679 ret_value), DEBUG_PROBE);
680
681 if (ret_value == 0)
682 return 0;
683
684
685
686
687 for (drive = 0; drive < 2; drive++) {
688 if ((ret_value & (0x01 << drive)) == 0)
689 continue;
690 wdc_set_drive(chp, drive);
691 delay(10);
692
693 st0 = CHP_READ_REG(chp, wdr_status);
694 sc = CHP_READ_REG(chp, wdr_seccnt);
695 sn = CHP_READ_REG(chp, wdr_sector);
696 cl = CHP_READ_REG(chp, wdr_cyl_lo);
697 ch = CHP_READ_REG(chp, wdr_cyl_hi);
698 WDC_LOG_REG(chp, wdr_cyl_lo, (ch << 8) | cl);
699
700 WDCDEBUG_PRINT(("%s:%d:%d: after reset, st=0x%b, sc=0x%x"
701 " sn=0x%x cl=0x%x ch=0x%x\n",
702 chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe",
703 chp->channel, drive, st0, WDCS_BITS, sc, sn, cl, ch),
704 DEBUG_PROBE);
705
706
707
708
709
710 if (cl == 0x14 && ch == 0xeb)
711 chp->ch_drive[drive].drive_flags |= DRIVE_ATAPI;
712 }
713
714
715
716
717 for (drive = 0; drive < 2; drive++) {
718 if ((ret_value & (0x01 << drive)) == 0)
719 continue;
720 if (chp->ch_drive[drive].drive_flags & DRIVE_ATAPI)
721 continue;
722
723 wdc_disable_intr(chp);
724
725 if (wdc_ata_present(chp, drive)) {
726 chp->ch_drive[drive].drive_flags |= DRIVE_ATA;
727 if (chp->wdc == NULL ||
728 (chp->wdc->cap & WDC_CAPABILITY_PREATA) != 0)
729 chp->ch_drive[drive].drive_flags |= DRIVE_OLD;
730 } else {
731 ret_value &= ~(1 << drive);
732 }
733 wdc_enable_intr(chp);
734 }
735
736 #ifdef WDCDEBUG
737 wdcdebug_mask = savedmask;
738 #endif
739 return (ret_value);
740 }
741
742
743
744
745 int
746 wdcactivate(self, act)
747 struct device *self;
748 enum devact act;
749 {
750 int error = 0;
751 int s;
752
753 s = splbio();
754 config_activate_children(self, act);
755 splx(s);
756
757 return (error);
758 }
759
760 void
761 wdcattach(chp)
762 struct channel_softc *chp;
763 {
764 int channel_flags, ctrl_flags, i;
765 #ifndef __OpenBSD__
766 int error;
767 #endif
768 struct ata_atapi_attach aa_link;
769 static int inited = 0;
770 #ifdef WDCDEBUG
771 int savedmask = wdcdebug_mask;
772 #endif
773
774 if (!cold)
775 at_poll = AT_WAIT;
776
777 if (chp->wdc->reset == NULL)
778 chp->wdc->reset = wdc_do_reset;
779
780 timeout_set(&chp->ch_timo, wdctimeout, chp);
781
782 #ifndef __OpenBSD__
783 if ((error = wdc_addref(chp)) != 0) {
784 printf("%s: unable to enable controller\n",
785 chp->wdc->sc_dev.dv_xname);
786 return;
787 }
788 #endif
789 if (!chp->_vtbl)
790 chp->_vtbl = &wdc_default_vtbl;
791
792 if (chp->wdc->drv_probe != NULL) {
793 chp->wdc->drv_probe(chp);
794 } else {
795 if (wdcprobe(chp) == 0) {
796
797 #ifndef __OpenBSD__
798 wdc_delref(chp);
799 #endif
800 return;
801 }
802 }
803
804
805 if ((chp->ch_drive[0].drive_flags & DRIVE_ATAPI) ||
806 (chp->ch_drive[1].drive_flags & DRIVE_ATAPI)) {
807 delay(250 * 1000);
808 }
809
810 #ifdef WDCDEBUG
811 if (chp->wdc->sc_dev.dv_cfdata->cf_flags & WDC_OPTION_PROBE_VERBOSE)
812 wdcdebug_mask |= DEBUG_PROBE;
813
814 if ((chp->ch_drive[0].drive_flags & DRIVE_ATAPI) ||
815 (chp->ch_drive[1].drive_flags & DRIVE_ATAPI)) {
816 wdcdebug_mask = DEBUG_PROBE;
817 }
818 #endif
819
820
821 if (inited == 0) {
822
823 pool_init(&wdc_xfer_pool, sizeof(struct wdc_xfer), 0,
824 0, 0, "wdcspl", NULL);
825 inited++;
826 }
827 TAILQ_INIT(&chp->ch_queue->sc_xfer);
828
829 for (i = 0; i < 2; i++) {
830 struct ata_drive_datas *drvp = &chp->ch_drive[i];
831
832 drvp->chnl_softc = chp;
833 drvp->drive = i;
834
835 if ((chp->wdc->cap &
836 (WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32)) ==
837 WDC_CAPABILITY_DATA32)
838 drvp->drive_flags |= DRIVE_CAP32;
839
840 if ((drvp->drive_flags & DRIVE) == 0)
841 continue;
842
843 if (i == 1 && ((chp->ch_drive[0].drive_flags & DRIVE) == 0))
844 chp->ch_flags |= WDCF_ONESLAVE;
845
846
847
848
849 delay(5000);
850 if (ata_get_params(&chp->ch_drive[i], at_poll, &drvp->id) ==
851 CMD_OK) {
852
853 drvp->drive_flags &= ~DRIVE_OLD;
854 } else {
855 bzero(&drvp->id, sizeof(struct ataparams));
856 drvp->drive_flags &=
857 ~(DRIVE_ATA | DRIVE_ATAPI);
858 WDCDEBUG_PRINT(("%s:%d:%d: IDENTIFY failed\n",
859 chp->wdc->sc_dev.dv_xname,
860 chp->channel, i), DEBUG_PROBE);
861
862 if ((drvp->drive_flags & DRIVE_OLD) &&
863 !wdc_preata_drive(chp, i))
864 drvp->drive_flags &= ~DRIVE_OLD;
865 }
866 }
867 ctrl_flags = chp->wdc->sc_dev.dv_cfdata->cf_flags;
868 channel_flags = (ctrl_flags >> (NBBY * chp->channel)) & 0xff;
869
870 WDCDEBUG_PRINT(("wdcattach: ch_drive_flags 0x%x 0x%x\n",
871 chp->ch_drive[0].drive_flags, chp->ch_drive[1].drive_flags),
872 DEBUG_PROBE);
873
874
875 if ((chp->ch_drive[0].drive_flags & DRIVE) == 0 &&
876 (chp->ch_drive[1].drive_flags & DRIVE) == 0)
877 goto exit;
878
879 for (i = 0; i < 2; i++) {
880 if ((chp->ch_drive[i].drive_flags & DRIVE) == 0) {
881 continue;
882 }
883 bzero(&aa_link, sizeof(struct ata_atapi_attach));
884 if (chp->ch_drive[i].drive_flags & DRIVE_ATAPI)
885 aa_link.aa_type = T_ATAPI;
886 else
887 aa_link.aa_type = T_ATA;
888 aa_link.aa_channel = chp->channel;
889 aa_link.aa_openings = 1;
890 aa_link.aa_drv_data = &chp->ch_drive[i];
891 config_found(&chp->wdc->sc_dev, (void *)&aa_link, wdprint);
892 }
893
894
895
896
897
898 for (i = 0; i < 2; i++) {
899 if (chp->ch_drive[i].drive_name[0] == 0)
900 chp->ch_drive[i].drive_flags = 0;
901 }
902
903 #ifndef __OpenBSD__
904 wdc_delref(chp);
905 #endif
906
907 exit:
908 #ifdef WDCDEBUG
909 wdcdebug_mask = savedmask;
910 #endif
911 return;
912 }
913
914
915
916
917
918
919 void
920 wdcstart(chp)
921 struct channel_softc *chp;
922 {
923 struct wdc_xfer *xfer;
924
925 splassert(IPL_BIO);
926
927
928 if ((xfer = TAILQ_FIRST(&chp->ch_queue->sc_xfer)) == NULL) {
929 return;
930 }
931
932
933 chp = xfer->chp;
934
935 if ((chp->ch_flags & WDCF_ACTIVE) != 0 ) {
936 return;
937 }
938 #ifdef DIAGNOSTIC
939 if ((chp->ch_flags & WDCF_IRQ_WAIT) != 0)
940 panic("wdcstart: channel waiting for irq");
941 #endif
942 if (chp->wdc->cap & WDC_CAPABILITY_HWLOCK)
943 if (!(chp->wdc->claim_hw)(chp, 0))
944 return;
945
946 WDCDEBUG_PRINT(("wdcstart: xfer %p channel %d drive %d\n", xfer,
947 chp->channel, xfer->drive), DEBUG_XFERS);
948 chp->ch_flags |= WDCF_ACTIVE;
949 if (chp->ch_drive[xfer->drive].drive_flags & DRIVE_RESET) {
950 chp->ch_drive[xfer->drive].drive_flags &= ~DRIVE_RESET;
951 chp->ch_drive[xfer->drive].state = 0;
952 }
953 xfer->c_start(chp, xfer);
954 }
955
956 int
957 wdcdetach(chp, flags)
958 struct channel_softc *chp;
959 int flags;
960 {
961 int s, rv;
962
963 s = splbio();
964 wdc_kill_pending(chp);
965
966 rv = config_detach_children((struct device *)chp->wdc, flags);
967 splx(s);
968
969 return (rv);
970 }
971
972
973
974
975
976
977
978 int
979 wdcintr(arg)
980 void *arg;
981 {
982 struct channel_softc *chp = arg;
983 struct wdc_xfer *xfer;
984 int ret;
985
986 if ((chp->ch_flags & WDCF_IRQ_WAIT) == 0) {
987
988 if (chp->_vtbl == 0) {
989 bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
990 wdr_status & _WDC_REGMASK);
991 } else {
992 CHP_READ_REG(chp, wdr_status);
993 }
994
995 WDCDEBUG_PRINT(("wdcintr: inactive controller\n"), DEBUG_INTR);
996 return 0;
997 }
998
999 WDCDEBUG_PRINT(("wdcintr\n"), DEBUG_INTR);
1000 xfer = TAILQ_FIRST(&chp->ch_queue->sc_xfer);
1001 if (chp->ch_flags & WDCF_DMA_WAIT) {
1002 chp->wdc->dma_status =
1003 (*chp->wdc->dma_finish)(chp->wdc->dma_arg, chp->channel,
1004 xfer->drive, 0);
1005 if (chp->wdc->dma_status & WDC_DMAST_NOIRQ) {
1006
1007 return 0;
1008 }
1009 chp->ch_flags &= ~WDCF_DMA_WAIT;
1010 }
1011 chp->ch_flags &= ~WDCF_IRQ_WAIT;
1012 ret = xfer->c_intr(chp, xfer, 1);
1013 if (ret == 0)
1014 chp->ch_flags |= WDCF_IRQ_WAIT;
1015 return (ret);
1016 }
1017
1018
1019 void wdc_reset_channel(drvp)
1020 struct ata_drive_datas *drvp;
1021 {
1022 struct channel_softc *chp = drvp->chnl_softc;
1023 int drive;
1024 WDCDEBUG_PRINT(("ata_reset_channel %s:%d for drive %d\n",
1025 chp->wdc->sc_dev.dv_xname, chp->channel, drvp->drive),
1026 DEBUG_FUNCS);
1027 (void) wdcreset(chp, VERBOSE);
1028 for (drive = 0; drive < 2; drive++) {
1029 chp->ch_drive[drive].state = 0;
1030 }
1031 }
1032
1033 int
1034 wdcreset(chp, verb)
1035 struct channel_softc *chp;
1036 int verb;
1037 {
1038 int drv_mask1, drv_mask2;
1039
1040 if (!chp->_vtbl)
1041 chp->_vtbl = &wdc_default_vtbl;
1042
1043 chp->wdc->reset(chp);
1044
1045 drv_mask1 = (chp->ch_drive[0].drive_flags & DRIVE) ? 0x01:0x00;
1046 drv_mask1 |= (chp->ch_drive[1].drive_flags & DRIVE) ? 0x02:0x00;
1047 drv_mask2 = __wdcwait_reset(chp, drv_mask1);
1048 if (verb && drv_mask2 != drv_mask1) {
1049 printf("%s channel %d: reset failed for",
1050 chp->wdc->sc_dev.dv_xname, chp->channel);
1051 if ((drv_mask1 & 0x01) != 0 && (drv_mask2 & 0x01) == 0)
1052 printf(" drive 0");
1053 if ((drv_mask1 & 0x02) != 0 && (drv_mask2 & 0x02) == 0)
1054 printf(" drive 1");
1055 printf("\n");
1056 }
1057
1058 return (drv_mask1 != drv_mask2) ? 1 : 0;
1059 }
1060
1061 void
1062 wdc_do_reset(struct channel_softc *chp)
1063 {
1064 wdc_set_drive(chp, 0);
1065 DELAY(10);
1066 CHP_WRITE_REG(chp, wdr_ctlr, WDCTL_4BIT | WDCTL_RST);
1067 delay(10000);
1068 CHP_WRITE_REG(chp, wdr_ctlr, WDCTL_4BIT);
1069 delay(10000);
1070 }
1071
1072 int
1073 __wdcwait_reset(chp, drv_mask)
1074 struct channel_softc *chp;
1075 int drv_mask;
1076 {
1077 int timeout;
1078 u_int8_t st0, er0, st1, er1;
1079
1080
1081 for (timeout = 0; timeout < WDCNDELAY_RST; timeout++) {
1082 wdc_set_drive(chp, 0);
1083 delay(10);
1084 st0 = CHP_READ_REG(chp, wdr_status);
1085 er0 = CHP_READ_REG(chp, wdr_error);
1086 wdc_set_drive(chp, 1);
1087 delay(10);
1088 st1 = CHP_READ_REG(chp, wdr_status);
1089 er1 = CHP_READ_REG(chp, wdr_error);
1090
1091 if ((drv_mask & 0x01) == 0) {
1092
1093 if ((drv_mask & 0x02) != 0 && (st1 & WDCS_BSY) == 0) {
1094
1095 goto end;
1096 }
1097 } else if ((drv_mask & 0x02) == 0) {
1098
1099 if ((drv_mask & 0x01) != 0 && (st0 & WDCS_BSY) == 0) {
1100
1101 goto end;
1102 }
1103 } else {
1104
1105 if ((st0 & WDCS_BSY) == 0 && (st1 & WDCS_BSY) == 0) {
1106 goto end;
1107 }
1108 }
1109 delay(WDCDELAY);
1110 }
1111
1112 if (st0 & WDCS_BSY)
1113 drv_mask &= ~0x01;
1114 if (st1 & WDCS_BSY)
1115 drv_mask &= ~0x02;
1116 end:
1117 WDCDEBUG_PRINT(("%s:%d: wdcwait_reset() end, st0=0x%b, er0=0x%x, "
1118 "st1=0x%b, er1=0x%x, reset time=%d msec\n",
1119 chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe", chp->channel,
1120 st0, WDCS_BITS, er0, st1, WDCS_BITS, er1,
1121 timeout * WDCDELAY / 1000), DEBUG_PROBE);
1122
1123 return drv_mask;
1124 }
1125
1126
1127
1128
1129
1130 int
1131 wdc_wait_for_status(chp, mask, bits, timeout)
1132 struct channel_softc *chp;
1133 int mask, bits, timeout;
1134 {
1135 u_char status;
1136 int time = 0;
1137
1138 WDCDEBUG_PRINT(("wdcwait %s:%d\n", chp->wdc ?chp->wdc->sc_dev.dv_xname
1139 :"none", chp->channel), DEBUG_STATUS);
1140 chp->ch_error = 0;
1141
1142 timeout = timeout * 1000 / WDCDELAY;
1143
1144 for (;;) {
1145 chp->ch_status = status = CHP_READ_REG(chp, wdr_status);
1146 WDC_LOG_STATUS(chp, chp->ch_status);
1147
1148 if (status == 0xff && (chp->ch_flags & WDCF_ONESLAVE)) {
1149 wdc_set_drive(chp, 1);
1150 chp->ch_status = status =
1151 CHP_READ_REG(chp, wdr_status);
1152 WDC_LOG_STATUS(chp, chp->ch_status);
1153 }
1154 if ((status & WDCS_BSY) == 0 && (status & mask) == bits)
1155 break;
1156 if (++time > timeout) {
1157 WDCDEBUG_PRINT(("wdcwait: timeout, status 0x%b "
1158 "error 0x%x\n", status, WDCS_BITS,
1159 CHP_READ_REG(chp, wdr_error)),
1160 DEBUG_STATUSX | DEBUG_STATUS);
1161 return -1;
1162 }
1163 delay(WDCDELAY);
1164 }
1165 if (status & WDCS_ERR) {
1166 chp->ch_error = CHP_READ_REG(chp, wdr_error);
1167 WDC_LOG_ERROR(chp, chp->ch_error);
1168
1169 WDCDEBUG_PRINT(("wdcwait: error %x\n", chp->ch_error),
1170 DEBUG_STATUSX | DEBUG_STATUS);
1171 }
1172
1173 #ifdef WDCNDELAY_DEBUG
1174
1175 if (!cold && time > WDCNDELAY_DEBUG) {
1176 struct wdc_xfer *xfer = TAILQ_FIRST(&chp->ch_queue->sc_xfer);
1177 if (xfer == NULL)
1178 printf("%s channel %d: warning: busy-wait took %dus\n",
1179 chp->wdc->sc_dev.dv_xname, chp->channel,
1180 WDCDELAY * time);
1181 else
1182 printf("%s:%d:%d: warning: busy-wait took %dus\n",
1183 chp->wdc->sc_dev.dv_xname, chp->channel,
1184 xfer->drive,
1185 WDCDELAY * time);
1186 }
1187 #endif
1188 return time;
1189 }
1190
1191
1192
1193
1194 int
1195 wdc_dmawait(chp, xfer, timeout)
1196 struct channel_softc *chp;
1197 struct wdc_xfer *xfer;
1198 int timeout;
1199 {
1200 int time;
1201 for (time = 0; time < timeout * 1000 / WDCDELAY; time++) {
1202 chp->wdc->dma_status =
1203 (*chp->wdc->dma_finish)(chp->wdc->dma_arg,
1204 chp->channel, xfer->drive, 0);
1205 if ((chp->wdc->dma_status & WDC_DMAST_NOIRQ) == 0)
1206 return 0;
1207 delay(WDCDELAY);
1208 }
1209
1210 chp->wdc->dma_status = (*chp->wdc->dma_finish)(chp->wdc->dma_arg,
1211 chp->channel, xfer->drive, 1);
1212 return 1;
1213 }
1214
1215 void
1216 wdctimeout(arg)
1217 void *arg;
1218 {
1219 struct channel_softc *chp = (struct channel_softc *)arg;
1220 struct wdc_xfer *xfer;
1221 int s;
1222
1223 WDCDEBUG_PRINT(("wdctimeout\n"), DEBUG_FUNCS);
1224
1225 s = splbio();
1226 xfer = TAILQ_FIRST(&chp->ch_queue->sc_xfer);
1227
1228
1229 if (xfer == NULL ||
1230 !timeout_triggered(&chp->ch_timo)) {
1231 splx(s);
1232 return;
1233 }
1234 if ((chp->ch_flags & WDCF_IRQ_WAIT) != 0) {
1235 __wdcerror(chp, "timeout");
1236 printf("\ttype: %s\n", (xfer->c_flags & C_ATAPI) ?
1237 "atapi":"ata");
1238 printf("\tc_bcount: %d\n", xfer->c_bcount);
1239 printf("\tc_skip: %d\n", xfer->c_skip);
1240 if (chp->ch_flags & WDCF_DMA_WAIT) {
1241 chp->wdc->dma_status =
1242 (*chp->wdc->dma_finish)(chp->wdc->dma_arg,
1243 chp->channel, xfer->drive, 1);
1244 chp->ch_flags &= ~WDCF_DMA_WAIT;
1245 }
1246
1247
1248
1249
1250
1251 xfer->c_flags |= C_TIMEOU;
1252 chp->ch_flags &= ~WDCF_IRQ_WAIT;
1253 xfer->c_intr(chp, xfer, 1);
1254 } else
1255 __wdcerror(chp, "missing untimeout");
1256 splx(s);
1257 }
1258
1259
1260
1261
1262
1263
1264 void
1265 wdc_probe_caps(drvp, params)
1266 struct ata_drive_datas *drvp;
1267 struct ataparams *params;
1268 {
1269 struct channel_softc *chp = drvp->chnl_softc;
1270 struct wdc_softc *wdc = chp->wdc;
1271 int i, valid_mode_found;
1272 int cf_flags = drvp->cf_flags;
1273
1274 if ((wdc->cap & WDC_CAPABILITY_SATA) != 0 &&
1275 (params->atap_sata_caps != 0x0000 &&
1276 params->atap_sata_caps != 0xffff)) {
1277 WDCDEBUG_PRINT(("%s: atap_sata_caps=0x%x\n", __func__,
1278 params->atap_sata_caps), DEBUG_PROBE);
1279
1280
1281 drvp->PIO_mode = drvp->PIO_cap = 4;
1282 drvp->DMA_mode = drvp->DMA_cap = 2;
1283 drvp->UDMA_mode = drvp->UDMA_cap = 5;
1284 drvp->drive_flags |= DRIVE_SATA | DRIVE_MODE | DRIVE_UDMA;
1285 drvp->ata_vers = 4;
1286 return;
1287 }
1288
1289 if ((wdc->cap & (WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32)) ==
1290 (WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32)) {
1291 struct ataparams params2;
1292
1293
1294
1295
1296
1297
1298 drvp->drive_flags |= DRIVE_CAP32;
1299 ata_get_params(drvp, at_poll, ¶ms2);
1300 if (bcmp(params, ¶ms2, sizeof(struct ataparams)) != 0) {
1301
1302 drvp->drive_flags &= ~DRIVE_CAP32;
1303 }
1304 }
1305 #if 0
1306 if (params->atap_ata_major > 0x01 &&
1307 params->atap_ata_major != 0xffff) {
1308 for (i = 14; i > 0; i--) {
1309 if (params->atap_ata_major & (1 << i)) {
1310 printf("%sATA version %d\n", sep, i);
1311 drvp->ata_vers = i;
1312 break;
1313 }
1314 }
1315 } else
1316 #endif
1317
1318 if (drvp->drive_flags & DRIVE_ATAPI)
1319 drvp->PIO_mode = 3;
1320
1321 WDCDEBUG_PRINT(("wdc_probe_caps: wdc_cap 0x%x cf_flags 0x%x\n",
1322 wdc->cap, cf_flags), DEBUG_PROBE);
1323
1324 valid_mode_found = 0;
1325
1326 WDCDEBUG_PRINT(("%s: atap_oldpiotiming=%d\n", __func__,
1327 params->atap_oldpiotiming), DEBUG_PROBE);
1328
1329
1330
1331
1332 if (params->atap_oldpiotiming <= 2) {
1333 drvp->PIO_cap = params->atap_oldpiotiming;
1334 valid_mode_found = 1;
1335 drvp->drive_flags |= DRIVE_MODE;
1336 } else if (params->atap_oldpiotiming > 180) {
1337
1338
1339
1340
1341
1342
1343
1344
1345 if (params->atap_oldpiotiming <= 240) {
1346 drvp->PIO_cap = 2;
1347 } else {
1348 drvp->PIO_cap = 1;
1349 }
1350 valid_mode_found = 1;
1351 drvp->drive_flags |= DRIVE_MODE;
1352 }
1353 if (valid_mode_found)
1354 drvp->PIO_mode = drvp->PIO_cap;
1355
1356 WDCDEBUG_PRINT(("%s: atap_extensions=0x%x, atap_piomode_supp=0x%x, "
1357 "atap_dmamode_supp=0x%x, atap_udmamode_supp=0x%x\n",
1358 __func__, params->atap_extensions, params->atap_piomode_supp,
1359 params->atap_dmamode_supp, params->atap_udmamode_supp),
1360 DEBUG_PROBE);
1361
1362
1363
1364
1365
1366 if (params->atap_extensions != 0xffff &&
1367 (params->atap_extensions & WDC_EXT_MODES)) {
1368
1369
1370
1371
1372
1373
1374 for (i = 7; i >= 0; i--) {
1375 if ((params->atap_piomode_supp & (1 << i)) == 0)
1376 continue;
1377 if (i > 4)
1378 return;
1379
1380 valid_mode_found = 1;
1381
1382 if ((wdc->cap & WDC_CAPABILITY_MODE) == 0) {
1383 drvp->PIO_cap = i + 3;
1384 continue;
1385 }
1386
1387
1388
1389
1390
1391
1392 if (ata_set_mode(drvp, 0x08 | (i + 3),
1393 at_poll) != CMD_OK)
1394 continue;
1395
1396
1397
1398
1399
1400 if (wdc->PIO_cap >= i + 3) {
1401 drvp->PIO_mode = i + 3;
1402 drvp->PIO_cap = i + 3;
1403 break;
1404 }
1405 }
1406 if (!valid_mode_found) {
1407
1408
1409
1410
1411 return;
1412 }
1413 drvp->drive_flags |= DRIVE_MODE;
1414
1415
1416 if ((drvp->drive_flags & DRIVE_ATAPI) &&
1417 (wdc->cap & WDC_CAPABILITY_NO_ATAPI_DMA))
1418 return;
1419
1420 valid_mode_found = 0;
1421 for (i = 7; i >= 0; i--) {
1422 if ((params->atap_dmamode_supp & (1 << i)) == 0)
1423 continue;
1424 if ((wdc->cap & WDC_CAPABILITY_DMA) &&
1425 (wdc->cap & WDC_CAPABILITY_MODE))
1426 if (ata_set_mode(drvp, 0x20 | i, at_poll)
1427 != CMD_OK)
1428 continue;
1429
1430 valid_mode_found = 1;
1431
1432 if (wdc->cap & WDC_CAPABILITY_DMA) {
1433 if ((wdc->cap & WDC_CAPABILITY_MODE) &&
1434 wdc->DMA_cap < i)
1435 continue;
1436 drvp->DMA_mode = i;
1437 drvp->DMA_cap = i;
1438 drvp->drive_flags |= DRIVE_DMA;
1439 }
1440 break;
1441 }
1442 if (params->atap_extensions & WDC_EXT_UDMA_MODES) {
1443 for (i = 7; i >= 0; i--) {
1444 if ((params->atap_udmamode_supp & (1 << i))
1445 == 0)
1446 continue;
1447 if ((wdc->cap & WDC_CAPABILITY_MODE) &&
1448 (wdc->cap & WDC_CAPABILITY_UDMA))
1449 if (ata_set_mode(drvp, 0x40 | i,
1450 at_poll) != CMD_OK)
1451 continue;
1452 if (wdc->cap & WDC_CAPABILITY_UDMA) {
1453 if ((wdc->cap & WDC_CAPABILITY_MODE) &&
1454 wdc->UDMA_cap < i)
1455 continue;
1456 drvp->UDMA_mode = i;
1457 drvp->UDMA_cap = i;
1458 drvp->drive_flags |= DRIVE_UDMA;
1459 }
1460 break;
1461 }
1462 }
1463 }
1464
1465
1466 if (drvp->ata_vers == 0) {
1467 if (drvp->drive_flags & DRIVE_UDMA)
1468 drvp->ata_vers = 4;
1469 else if (drvp->PIO_cap > 2)
1470 drvp->ata_vers = 2;
1471 }
1472 if (cf_flags & ATA_CONFIG_PIO_SET) {
1473 drvp->PIO_mode =
1474 (cf_flags & ATA_CONFIG_PIO_MODES) >> ATA_CONFIG_PIO_OFF;
1475 drvp->drive_flags |= DRIVE_MODE;
1476 }
1477 if ((wdc->cap & WDC_CAPABILITY_DMA) == 0) {
1478
1479 return;
1480 }
1481 if (cf_flags & ATA_CONFIG_DMA_SET) {
1482 if ((cf_flags & ATA_CONFIG_DMA_MODES) ==
1483 ATA_CONFIG_DMA_DISABLE) {
1484 drvp->drive_flags &= ~DRIVE_DMA;
1485 } else {
1486 drvp->DMA_mode = (cf_flags & ATA_CONFIG_DMA_MODES) >>
1487 ATA_CONFIG_DMA_OFF;
1488 drvp->drive_flags |= DRIVE_DMA | DRIVE_MODE;
1489 }
1490 }
1491 if ((wdc->cap & WDC_CAPABILITY_UDMA) == 0) {
1492
1493 return;
1494 }
1495 if (cf_flags & ATA_CONFIG_UDMA_SET) {
1496 if ((cf_flags & ATA_CONFIG_UDMA_MODES) ==
1497 ATA_CONFIG_UDMA_DISABLE) {
1498 drvp->drive_flags &= ~DRIVE_UDMA;
1499 } else {
1500 drvp->UDMA_mode = (cf_flags & ATA_CONFIG_UDMA_MODES) >>
1501 ATA_CONFIG_UDMA_OFF;
1502 drvp->drive_flags |= DRIVE_UDMA | DRIVE_MODE;
1503 }
1504 }
1505 }
1506
1507 void
1508 wdc_output_bytes(drvp, bytes, buflen)
1509 struct ata_drive_datas *drvp;
1510 void *bytes;
1511 unsigned int buflen;
1512 {
1513 struct channel_softc *chp = drvp->chnl_softc;
1514 unsigned int off = 0;
1515 unsigned int len = buflen, roundlen;
1516
1517 if (drvp->drive_flags & DRIVE_CAP32) {
1518 roundlen = len & ~3;
1519
1520 CHP_WRITE_RAW_MULTI_4(chp,
1521 (void *)((u_int8_t *)bytes + off), roundlen);
1522
1523 off += roundlen;
1524 len -= roundlen;
1525 }
1526
1527 if (len > 0) {
1528 roundlen = (len + 1) & ~0x1;
1529
1530 CHP_WRITE_RAW_MULTI_2(chp,
1531 (void *)((u_int8_t *)bytes + off), roundlen);
1532 }
1533 }
1534
1535 void
1536 wdc_input_bytes(drvp, bytes, buflen)
1537 struct ata_drive_datas *drvp;
1538 void *bytes;
1539 unsigned int buflen;
1540 {
1541 struct channel_softc *chp = drvp->chnl_softc;
1542 unsigned int off = 0;
1543 unsigned int len = buflen, roundlen;
1544
1545 if (drvp->drive_flags & DRIVE_CAP32) {
1546 roundlen = len & ~3;
1547
1548 CHP_READ_RAW_MULTI_4(chp,
1549 (void *)((u_int8_t *)bytes + off), roundlen);
1550
1551 off += roundlen;
1552 len -= roundlen;
1553 }
1554
1555 if (len > 0) {
1556 roundlen = (len + 1) & ~0x1;
1557
1558 CHP_READ_RAW_MULTI_2(chp,
1559 (void *)((u_int8_t *)bytes + off), roundlen);
1560 }
1561 }
1562
1563 void
1564 wdc_print_caps(drvp)
1565 struct ata_drive_datas *drvp;
1566 {
1567
1568
1569 #if 0
1570 printf("%s: can use ", drvp->drive_name);
1571
1572 if (drvp->drive_flags & DRIVE_CAP32) {
1573 printf("32-bit");
1574 } else
1575 printf("16-bit");
1576
1577 printf(", PIO mode %d", drvp->PIO_cap);
1578
1579 if (drvp->drive_flags & DRIVE_DMA) {
1580 printf(", DMA mode %d", drvp->DMA_cap);
1581 }
1582
1583 if (drvp->drive_flags & DRIVE_UDMA) {
1584 printf(", Ultra-DMA mode %d", drvp->UDMA_cap);
1585 }
1586
1587 printf("\n");
1588 #endif
1589 }
1590
1591 void
1592 wdc_print_current_modes(chp)
1593 struct channel_softc *chp;
1594 {
1595 int drive;
1596 struct ata_drive_datas *drvp;
1597
1598 for (drive = 0; drive < 2; drive++) {
1599 drvp = &chp->ch_drive[drive];
1600 if ((drvp->drive_flags & DRIVE) == 0)
1601 continue;
1602
1603 printf("%s(%s:%d:%d):",
1604 drvp->drive_name,
1605 chp->wdc->sc_dev.dv_xname, chp->channel, drive);
1606
1607 if ((chp->wdc->cap & WDC_CAPABILITY_MODE) == 0 &&
1608 !(drvp->cf_flags & ATA_CONFIG_PIO_SET))
1609 printf(" using BIOS timings");
1610 else
1611 printf(" using PIO mode %d", drvp->PIO_mode);
1612 if (drvp->drive_flags & DRIVE_DMA)
1613 printf(", DMA mode %d", drvp->DMA_mode);
1614 if (drvp->drive_flags & DRIVE_UDMA)
1615 printf(", Ultra-DMA mode %d", drvp->UDMA_mode);
1616 printf("\n");
1617 }
1618 }
1619
1620
1621
1622
1623
1624 int
1625 wdc_downgrade_mode(drvp)
1626 struct ata_drive_datas *drvp;
1627 {
1628 struct channel_softc *chp = drvp->chnl_softc;
1629 struct wdc_softc *wdc = chp->wdc;
1630 int cf_flags = drvp->cf_flags;
1631
1632
1633 if ((drvp->drive_flags & DRIVE_MODE) == 0 ||
1634 (wdc->cap & WDC_CAPABILITY_MODE) == 0)
1635 return 0;
1636
1637 if ((cf_flags & ATA_CONFIG_PIO_SET) ||
1638 (cf_flags & ATA_CONFIG_DMA_SET) ||
1639 (cf_flags & ATA_CONFIG_UDMA_SET))
1640 return 0;
1641
1642
1643
1644
1645
1646
1647 if ((drvp->drive_flags & DRIVE_UDMA) && drvp->UDMA_mode > 0) {
1648 drvp->UDMA_mode = drvp->UDMA_mode - 1;
1649 printf("%s: transfer error, downgrading to Ultra-DMA mode %d\n",
1650 drvp->drive_name, drvp->UDMA_mode);
1651 } else if ((drvp->drive_flags & DRIVE_UDMA) &&
1652 (drvp->drive_flags & DRIVE_DMAERR) == 0) {
1653
1654
1655
1656
1657
1658
1659
1660 drvp->drive_flags &= ~DRIVE_UDMA;
1661 drvp->drive_flags |= DRIVE_DMA;
1662 drvp->DMA_mode = drvp->DMA_cap;
1663 printf("%s: transfer error, downgrading to DMA mode %d\n",
1664 drvp->drive_name, drvp->DMA_mode);
1665 } else if (drvp->drive_flags & (DRIVE_DMA | DRIVE_UDMA)) {
1666 drvp->drive_flags &= ~(DRIVE_DMA | DRIVE_UDMA);
1667 drvp->PIO_mode = drvp->PIO_cap;
1668 printf("%s: transfer error, downgrading to PIO mode %d\n",
1669 drvp->drive_name, drvp->PIO_mode);
1670 } else
1671 return 0;
1672
1673 wdc->set_modes(chp);
1674
1675 wdc_reset_channel(drvp);
1676 return 1;
1677 }
1678
1679 int
1680 wdc_exec_command(drvp, wdc_c)
1681 struct ata_drive_datas *drvp;
1682 struct wdc_command *wdc_c;
1683 {
1684 struct channel_softc *chp = drvp->chnl_softc;
1685 struct wdc_xfer *xfer;
1686 int s, ret;
1687
1688 WDCDEBUG_PRINT(("wdc_exec_command %s:%d:%d\n",
1689 chp->wdc->sc_dev.dv_xname, chp->channel, drvp->drive),
1690 DEBUG_FUNCS);
1691
1692
1693 xfer = wdc_get_xfer(wdc_c->flags & AT_WAIT ? WDC_CANSLEEP :
1694 WDC_NOSLEEP);
1695 if (xfer == NULL) {
1696 return WDC_TRY_AGAIN;
1697 }
1698
1699 if (wdc_c->flags & AT_POLL)
1700 xfer->c_flags |= C_POLL;
1701 xfer->drive = drvp->drive;
1702 xfer->databuf = wdc_c->data;
1703 xfer->c_bcount = wdc_c->bcount;
1704 xfer->cmd = wdc_c;
1705 xfer->c_start = __wdccommand_start;
1706 xfer->c_intr = __wdccommand_intr;
1707 xfer->c_kill_xfer = __wdccommand_done;
1708
1709 s = splbio();
1710 wdc_exec_xfer(chp, xfer);
1711 #ifdef DIAGNOSTIC
1712 if ((wdc_c->flags & AT_POLL) != 0 &&
1713 (wdc_c->flags & AT_DONE) == 0)
1714 panic("wdc_exec_command: polled command not done");
1715 #endif
1716 if (wdc_c->flags & AT_DONE) {
1717 ret = WDC_COMPLETE;
1718 } else {
1719 if (wdc_c->flags & AT_WAIT) {
1720 WDCDEBUG_PRINT(("wdc_exec_command sleeping\n"),
1721 DEBUG_FUNCS);
1722
1723 while ((wdc_c->flags & AT_DONE) == 0) {
1724 tsleep(wdc_c, PRIBIO, "wdccmd", 0);
1725 }
1726 ret = WDC_COMPLETE;
1727 } else {
1728 ret = WDC_QUEUED;
1729 }
1730 }
1731 splx(s);
1732 return ret;
1733 }
1734
1735 void
1736 __wdccommand_start(chp, xfer)
1737 struct channel_softc *chp;
1738 struct wdc_xfer *xfer;
1739 {
1740 int drive = xfer->drive;
1741 struct wdc_command *wdc_c = xfer->cmd;
1742
1743 WDCDEBUG_PRINT(("__wdccommand_start %s:%d:%d\n",
1744 chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive),
1745 DEBUG_FUNCS);
1746
1747
1748
1749
1750 if (xfer->c_flags & C_POLL) {
1751 wdc_disable_intr(chp);
1752 }
1753
1754 wdc_set_drive(chp, drive);
1755 DELAY(1);
1756
1757
1758
1759
1760
1761 if (wdc_c->r_command != ATAPI_SOFT_RESET) {
1762 if (wdcwait(chp, wdc_c->r_st_bmask | WDCS_DRQ,
1763 wdc_c->r_st_bmask, wdc_c->timeout) != 0) {
1764 goto timeout;
1765 }
1766 } else
1767 DELAY(10);
1768
1769 wdccommand(chp, drive, wdc_c->r_command, wdc_c->r_cyl, wdc_c->r_head,
1770 wdc_c->r_sector, wdc_c->r_count, wdc_c->r_precomp);
1771
1772 if ((wdc_c->flags & AT_WRITE) == AT_WRITE) {
1773
1774 DELAY(10);
1775 if (wait_for_unbusy(chp, wdc_c->timeout) != 0)
1776 goto timeout;
1777
1778 if ((chp->ch_status & (WDCS_DRQ | WDCS_ERR)) == WDCS_ERR) {
1779 __wdccommand_done(chp, xfer);
1780 return;
1781 }
1782
1783 if (wait_for_drq(chp, wdc_c->timeout) != 0)
1784 goto timeout;
1785
1786 wdc_output_bytes(&chp->ch_drive[drive],
1787 wdc_c->data, wdc_c->bcount);
1788 }
1789
1790 if ((wdc_c->flags & AT_POLL) == 0) {
1791 chp->ch_flags |= WDCF_IRQ_WAIT;
1792 timeout_add(&chp->ch_timo, wdc_c->timeout / 1000 * hz);
1793 return;
1794 }
1795
1796
1797
1798
1799
1800 delay(10);
1801 __wdccommand_intr(chp, xfer, 0);
1802 return;
1803
1804 timeout:
1805 wdc_c->flags |= AT_TIMEOU;
1806 __wdccommand_done(chp, xfer);
1807 }
1808
1809 int
1810 __wdccommand_intr(chp, xfer, irq)
1811 struct channel_softc *chp;
1812 struct wdc_xfer *xfer;
1813 int irq;
1814 {
1815 struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive];
1816 struct wdc_command *wdc_c = xfer->cmd;
1817 int bcount = wdc_c->bcount;
1818 char *data = wdc_c->data;
1819
1820 WDCDEBUG_PRINT(("__wdccommand_intr %s:%d:%d\n",
1821 chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive), DEBUG_INTR);
1822 if (wdcwait(chp, wdc_c->r_st_pmask, wdc_c->r_st_pmask,
1823 (irq == 0) ? wdc_c->timeout : 0)) {
1824 if (irq && (xfer->c_flags & C_TIMEOU) == 0)
1825 return 0;
1826 wdc_c->flags |= AT_TIMEOU;
1827 goto out;
1828 }
1829 if (chp->wdc->cap & WDC_CAPABILITY_IRQACK)
1830 chp->wdc->irqack(chp);
1831 if (wdc_c->flags & AT_READ) {
1832 if ((chp->ch_status & WDCS_DRQ) == 0) {
1833 wdc_c->flags |= AT_TIMEOU;
1834 goto out;
1835 }
1836 wdc_input_bytes(drvp, data, bcount);
1837
1838 }
1839 out:
1840 __wdccommand_done(chp, xfer);
1841 WDCDEBUG_PRINT(("__wdccommand_intr returned\n"), DEBUG_INTR);
1842 return 1;
1843 }
1844
1845 void
1846 __wdccommand_done(chp, xfer)
1847 struct channel_softc *chp;
1848 struct wdc_xfer *xfer;
1849 {
1850 struct wdc_command *wdc_c = xfer->cmd;
1851
1852 WDCDEBUG_PRINT(("__wdccommand_done %s:%d:%d %02x\n",
1853 chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive,
1854 chp->ch_status), DEBUG_FUNCS);
1855 if (chp->ch_status & WDCS_DWF)
1856 wdc_c->flags |= AT_DF;
1857 if (chp->ch_status & WDCS_ERR) {
1858 wdc_c->flags |= AT_ERROR;
1859 wdc_c->r_error = chp->ch_error;
1860 }
1861 wdc_c->flags |= AT_DONE;
1862 if ((wdc_c->flags & AT_READREG) != 0 &&
1863 (wdc_c->flags & (AT_ERROR | AT_DF)) == 0) {
1864 wdc_c->r_head = CHP_READ_REG(chp, wdr_sdh);
1865 wdc_c->r_cyl = CHP_READ_REG(chp, wdr_cyl_hi) << 8;
1866 wdc_c->r_cyl |= CHP_READ_REG(chp, wdr_cyl_lo);
1867 wdc_c->r_sector = CHP_READ_REG(chp, wdr_sector);
1868 wdc_c->r_count = CHP_READ_REG(chp, wdr_seccnt);
1869 wdc_c->r_error = CHP_READ_REG(chp, wdr_error);
1870 wdc_c->r_precomp = wdc_c->r_error;
1871
1872
1873 }
1874
1875 if (xfer->c_flags & C_POLL) {
1876 wdc_enable_intr(chp);
1877 }
1878
1879 wdc_free_xfer(chp, xfer);
1880 WDCDEBUG_PRINT(("__wdccommand_done before callback\n"), DEBUG_INTR);
1881
1882 if (wdc_c->flags & AT_WAIT)
1883 wakeup(wdc_c);
1884 else
1885 if (wdc_c->callback)
1886 wdc_c->callback(wdc_c->callback_arg);
1887 wdcstart(chp);
1888 WDCDEBUG_PRINT(("__wdccommand_done returned\n"), DEBUG_INTR);
1889 }
1890
1891
1892
1893
1894
1895 void
1896 wdccommand(chp, drive, command, cylin, head, sector, count, precomp)
1897 struct channel_softc *chp;
1898 u_int8_t drive;
1899 u_int8_t command;
1900 u_int16_t cylin;
1901 u_int8_t head, sector, count, precomp;
1902 {
1903 WDCDEBUG_PRINT(("wdccommand %s:%d:%d: command=0x%x cylin=%d head=%d "
1904 "sector=%d count=%d precomp=%d\n", chp->wdc->sc_dev.dv_xname,
1905 chp->channel, drive, command, cylin, head, sector, count, precomp),
1906 DEBUG_FUNCS);
1907 WDC_LOG_ATA_CMDLONG(chp, head, precomp, cylin, cylin >> 8, sector,
1908 count, command);
1909
1910
1911 CHP_WRITE_REG(chp, wdr_sdh, WDSD_IBM | (drive << 4) | head);
1912
1913
1914 CHP_WRITE_REG(chp, wdr_precomp, precomp);
1915 CHP_WRITE_REG(chp, wdr_cyl_lo, cylin);
1916 CHP_WRITE_REG(chp, wdr_cyl_hi, cylin >> 8);
1917 CHP_WRITE_REG(chp, wdr_sector, sector);
1918 CHP_WRITE_REG(chp, wdr_seccnt, count);
1919
1920
1921 CHP_WRITE_REG(chp, wdr_command, command);
1922 }
1923
1924
1925
1926
1927
1928 void
1929 wdccommandext(chp, drive, command, blkno, count)
1930 struct channel_softc *chp;
1931 u_int8_t drive;
1932 u_int8_t command;
1933 u_int64_t blkno;
1934 u_int16_t count;
1935 {
1936 WDCDEBUG_PRINT(("wdccommandext %s:%d:%d: command=0x%x blkno=%llu "
1937 "count=%d\n", chp->wdc->sc_dev.dv_xname,
1938 chp->channel, drive, command, blkno, count),
1939 DEBUG_FUNCS);
1940 WDC_LOG_ATA_CMDEXT(chp, blkno >> 40, blkno >> 16, blkno >> 32,
1941 blkno >> 8, blkno >> 24, blkno, count >> 8, count, command);
1942
1943
1944 CHP_WRITE_REG(chp, wdr_sdh, (drive << 4) | WDSD_LBA);
1945
1946
1947 CHP_LBA48_WRITE_REG(chp, wdr_lba_hi,
1948 ((blkno >> 32) & 0xff00) | ((blkno >> 16) & 0xff));
1949 CHP_LBA48_WRITE_REG(chp, wdr_lba_mi,
1950 ((blkno >> 24) & 0xff00) | ((blkno >> 8) & 0xff));
1951 CHP_LBA48_WRITE_REG(chp, wdr_lba_lo,
1952 ((blkno >> 16) & 0xff00) | (blkno & 0xff));
1953 CHP_LBA48_WRITE_REG(chp, wdr_seccnt, count);
1954
1955
1956 CHP_WRITE_REG(chp, wdr_command, command);
1957 }
1958
1959
1960
1961
1962
1963 void
1964 wdccommandshort(chp, drive, command)
1965 struct channel_softc *chp;
1966 int drive;
1967 int command;
1968 {
1969
1970 WDCDEBUG_PRINT(("wdccommandshort %s:%d:%d command 0x%x\n",
1971 chp->wdc->sc_dev.dv_xname, chp->channel, drive, command),
1972 DEBUG_FUNCS);
1973 WDC_LOG_ATA_CMDSHORT(chp, command);
1974
1975
1976 CHP_WRITE_REG(chp, wdr_sdh, WDSD_IBM | (drive << 4));
1977 CHP_WRITE_REG(chp, wdr_command, command);
1978 }
1979
1980
1981
1982 void
1983 wdc_exec_xfer(chp, xfer)
1984 struct channel_softc *chp;
1985 struct wdc_xfer *xfer;
1986 {
1987 WDCDEBUG_PRINT(("wdc_exec_xfer %p flags 0x%x channel %d drive %d\n",
1988 xfer, xfer->c_flags, chp->channel, xfer->drive), DEBUG_XFERS);
1989
1990
1991 xfer->chp = chp;
1992
1993
1994
1995
1996
1997
1998 if ((xfer->c_flags & C_POLL) != 0 &&
1999 !TAILQ_EMPTY(&chp->ch_queue->sc_xfer)) {
2000 TAILQ_INIT(&chp->ch_queue->sc_xfer);
2001 }
2002
2003 TAILQ_INSERT_TAIL(&chp->ch_queue->sc_xfer,xfer , c_xferchain);
2004 WDCDEBUG_PRINT(("wdcstart from wdc_exec_xfer, flags 0x%x\n",
2005 chp->ch_flags), DEBUG_XFERS);
2006 wdcstart(chp);
2007 }
2008
2009 struct wdc_xfer *
2010 wdc_get_xfer(flags)
2011 int flags;
2012 {
2013 struct wdc_xfer *xfer;
2014 int s;
2015
2016 s = splbio();
2017 xfer = pool_get(&wdc_xfer_pool,
2018 ((flags & WDC_NOSLEEP) != 0 ? PR_NOWAIT : PR_WAITOK));
2019 splx(s);
2020 if (xfer != NULL)
2021 memset(xfer, 0, sizeof(struct wdc_xfer));
2022 return xfer;
2023 }
2024
2025 void
2026 wdc_free_xfer(chp, xfer)
2027 struct channel_softc *chp;
2028 struct wdc_xfer *xfer;
2029 {
2030 struct wdc_softc *wdc = chp->wdc;
2031 int s;
2032
2033 if (wdc->cap & WDC_CAPABILITY_HWLOCK)
2034 (*wdc->free_hw)(chp);
2035 s = splbio();
2036 chp->ch_flags &= ~WDCF_ACTIVE;
2037 TAILQ_REMOVE(&chp->ch_queue->sc_xfer, xfer, c_xferchain);
2038 pool_put(&wdc_xfer_pool, xfer);
2039 splx(s);
2040 }
2041
2042
2043
2044
2045
2046
2047
2048 void
2049 wdc_kill_pending(chp)
2050 struct channel_softc *chp;
2051 {
2052 struct wdc_xfer *xfer;
2053
2054 while ((xfer = TAILQ_FIRST(&chp->ch_queue->sc_xfer)) != NULL) {
2055 chp = xfer->chp;
2056 (*xfer->c_kill_xfer)(chp, xfer);
2057 }
2058 }
2059
2060 void
2061 __wdcerror(chp, msg)
2062 struct channel_softc *chp;
2063 char *msg;
2064 {
2065 struct wdc_xfer *xfer = TAILQ_FIRST(&chp->ch_queue->sc_xfer);
2066 if (xfer == NULL)
2067 printf("%s:%d: %s\n", chp->wdc->sc_dev.dv_xname, chp->channel,
2068 msg);
2069 else
2070 printf("%s(%s:%d:%d): %s\n",
2071 chp->ch_drive[xfer->drive].drive_name,
2072 chp->wdc->sc_dev.dv_xname,
2073 chp->channel, xfer->drive, msg);
2074 }
2075
2076
2077
2078
2079 void
2080 wdcbit_bucket(chp, size)
2081 struct channel_softc *chp;
2082 int size;
2083 {
2084 CHP_READ_RAW_MULTI_2(chp, NULL, size);
2085 }
2086
2087
2088 #include <sys/ataio.h>
2089 #include <sys/file.h>
2090 #include <sys/buf.h>
2091
2092
2093
2094
2095
2096 struct wdc_ioctl {
2097 LIST_ENTRY(wdc_ioctl) wi_list;
2098 struct buf wi_bp;
2099 struct uio wi_uio;
2100 struct iovec wi_iov;
2101 atareq_t wi_atareq;
2102 struct ata_drive_datas *wi_drvp;
2103 };
2104
2105 struct wdc_ioctl *wdc_ioctl_find(struct buf *);
2106 void wdc_ioctl_free(struct wdc_ioctl *);
2107 struct wdc_ioctl *wdc_ioctl_get(void);
2108 void wdc_ioctl_strategy(struct buf *);
2109
2110 LIST_HEAD(, wdc_ioctl) wi_head;
2111
2112
2113
2114
2115
2116 struct wdc_ioctl *
2117 wdc_ioctl_get()
2118 {
2119 struct wdc_ioctl *wi;
2120 int s;
2121
2122 wi = malloc(sizeof(struct wdc_ioctl), M_TEMP, M_WAITOK);
2123 bzero(wi, sizeof (struct wdc_ioctl));
2124 s = splbio();
2125 LIST_INSERT_HEAD(&wi_head, wi, wi_list);
2126 splx(s);
2127 return (wi);
2128 }
2129
2130
2131
2132
2133
2134 void
2135 wdc_ioctl_free(wi)
2136 struct wdc_ioctl *wi;
2137 {
2138 int s;
2139
2140 s = splbio();
2141 LIST_REMOVE(wi, wi_list);
2142 splx(s);
2143 free(wi, M_TEMP);
2144 }
2145
2146
2147
2148
2149
2150 struct wdc_ioctl *
2151 wdc_ioctl_find(bp)
2152 struct buf *bp;
2153 {
2154 struct wdc_ioctl *wi;
2155 int s;
2156
2157 s = splbio();
2158 LIST_FOREACH(wi, &wi_head, wi_list)
2159 if (bp == &wi->wi_bp)
2160 break;
2161 splx(s);
2162 return (wi);
2163 }
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187 void
2188 wdc_ioctl_strategy(bp)
2189 struct buf *bp;
2190 {
2191 struct wdc_ioctl *wi;
2192 struct wdc_command wdc_c;
2193 int error = 0;
2194 int s;
2195
2196 wi = wdc_ioctl_find(bp);
2197 if (wi == NULL) {
2198 printf("user_strat: No ioctl\n");
2199 error = EINVAL;
2200 goto bad;
2201 }
2202
2203 bzero(&wdc_c, sizeof(wdc_c));
2204
2205
2206
2207
2208
2209 if ((u_long)bp->b_bcount != wi->wi_atareq.datalen) {
2210 printf("physio split wd ioctl request... cannot proceed\n");
2211 error = EIO;
2212 goto bad;
2213 }
2214
2215
2216
2217
2218
2219 if (wi->wi_atareq.timeout == 0) {
2220 error = EINVAL;
2221 goto bad;
2222 }
2223
2224 if (wi->wi_atareq.flags & ATACMD_READ)
2225 wdc_c.flags |= AT_READ;
2226 else if (wi->wi_atareq.flags & ATACMD_WRITE)
2227 wdc_c.flags |= AT_WRITE;
2228
2229 if (wi->wi_atareq.flags & ATACMD_READREG)
2230 wdc_c.flags |= AT_READREG;
2231
2232 wdc_c.flags |= AT_WAIT;
2233
2234 wdc_c.timeout = wi->wi_atareq.timeout;
2235 wdc_c.r_command = wi->wi_atareq.command;
2236 wdc_c.r_head = wi->wi_atareq.head & 0x0f;
2237 wdc_c.r_cyl = wi->wi_atareq.cylinder;
2238 wdc_c.r_sector = wi->wi_atareq.sec_num;
2239 wdc_c.r_count = wi->wi_atareq.sec_count;
2240 wdc_c.r_precomp = wi->wi_atareq.features;
2241 if (wi->wi_drvp->drive_flags & DRIVE_ATAPI) {
2242 wdc_c.r_st_bmask = 0;
2243 wdc_c.r_st_pmask = 0;
2244 if (wdc_c.r_command == WDCC_IDENTIFY)
2245 wdc_c.r_command = ATAPI_IDENTIFY_DEVICE;
2246 } else {
2247 wdc_c.r_st_bmask = WDCS_DRDY;
2248 wdc_c.r_st_pmask = WDCS_DRDY;
2249 }
2250 wdc_c.data = wi->wi_bp.b_data;
2251 wdc_c.bcount = wi->wi_bp.b_bcount;
2252
2253 if (wdc_exec_command(wi->wi_drvp, &wdc_c) != WDC_COMPLETE) {
2254 wi->wi_atareq.retsts = ATACMD_ERROR;
2255 goto bad;
2256 }
2257
2258 if (wdc_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
2259 if (wdc_c.flags & AT_ERROR) {
2260 wi->wi_atareq.retsts = ATACMD_ERROR;
2261 wi->wi_atareq.error = wdc_c.r_error;
2262 } else if (wdc_c.flags & AT_DF)
2263 wi->wi_atareq.retsts = ATACMD_DF;
2264 else
2265 wi->wi_atareq.retsts = ATACMD_TIMEOUT;
2266 } else {
2267 wi->wi_atareq.retsts = ATACMD_OK;
2268 if (wi->wi_atareq.flags & ATACMD_READREG) {
2269 wi->wi_atareq.head = wdc_c.r_head ;
2270 wi->wi_atareq.cylinder = wdc_c.r_cyl;
2271 wi->wi_atareq.sec_num = wdc_c.r_sector;
2272 wi->wi_atareq.sec_count = wdc_c.r_count;
2273 wi->wi_atareq.features = wdc_c.r_precomp;
2274 wi->wi_atareq.error = wdc_c.r_error;
2275 }
2276 }
2277
2278 bp->b_error = 0;
2279 s = splbio();
2280 biodone(bp);
2281 splx(s);
2282 return;
2283 bad:
2284 bp->b_flags |= B_ERROR;
2285 bp->b_error = error;
2286 s = splbio();
2287 biodone(bp);
2288 splx(s);
2289 }
2290
2291 int
2292 wdc_ioctl(drvp, xfer, addr, flag, p)
2293 struct ata_drive_datas *drvp;
2294 u_long xfer;
2295 caddr_t addr;
2296 int flag;
2297 struct proc *p;
2298 {
2299 int error = 0;
2300
2301 switch (xfer) {
2302 case ATAIOGETTRACE: {
2303 atagettrace_t *agt = (atagettrace_t *)addr;
2304 unsigned int size = 0;
2305 char *log_to_copy;
2306
2307 size = agt->buf_size;
2308 if (size > 65536) {
2309 size = 65536;
2310 }
2311
2312 log_to_copy = wdc_get_log(&size, &agt->bytes_left);
2313
2314 if (log_to_copy != NULL) {
2315 error = copyout(log_to_copy, agt->buf, size);
2316 free(log_to_copy, M_TEMP);
2317 }
2318
2319 agt->bytes_copied = size;
2320 break;
2321 }
2322
2323 case ATAIOCCOMMAND:
2324
2325
2326
2327 if ((((atareq_t *) addr)->flags & ATACMD_READ) == 0 &&
2328 (flag & FWRITE) == 0) {
2329 error = EBADF;
2330 goto exit;
2331 }
2332 {
2333 struct wdc_ioctl *wi;
2334 atareq_t *atareq = (atareq_t *) addr;
2335
2336 wi = wdc_ioctl_get();
2337 wi->wi_drvp = drvp;
2338 wi->wi_atareq = *atareq;
2339
2340 if (atareq->datalen && atareq->flags &
2341 (ATACMD_READ | ATACMD_WRITE)) {
2342 wi->wi_iov.iov_base = atareq->databuf;
2343 wi->wi_iov.iov_len = atareq->datalen;
2344 wi->wi_uio.uio_iov = &wi->wi_iov;
2345 wi->wi_uio.uio_iovcnt = 1;
2346 wi->wi_uio.uio_resid = atareq->datalen;
2347 wi->wi_uio.uio_offset = 0;
2348 wi->wi_uio.uio_segflg = UIO_USERSPACE;
2349 wi->wi_uio.uio_rw =
2350 (atareq->flags & ATACMD_READ) ? B_READ : B_WRITE;
2351 wi->wi_uio.uio_procp = curproc;
2352 error = physio(wdc_ioctl_strategy, &wi->wi_bp, 0,
2353 (atareq->flags & ATACMD_READ) ? B_READ : B_WRITE,
2354 minphys, &wi->wi_uio);
2355 } else {
2356
2357
2358 wi->wi_bp.b_flags = 0;
2359 wi->wi_bp.b_data = 0;
2360 wi->wi_bp.b_bcount = 0;
2361 wi->wi_bp.b_dev = 0;
2362 wi->wi_bp.b_proc = curproc;
2363 LIST_INIT(&wi->wi_bp.b_dep);
2364 wdc_ioctl_strategy(&wi->wi_bp);
2365 error = wi->wi_bp.b_error;
2366 }
2367 *atareq = wi->wi_atareq;
2368 wdc_ioctl_free(wi);
2369 goto exit;
2370 }
2371 default:
2372 error = ENOTTY;
2373 goto exit;
2374 }
2375
2376 exit:
2377 return (error);
2378 }