[Krafton Jungle] PintOS 2.0.0
크래프톤 정글 PintOS
 
Loading...
Searching...
No Matches
disk.c File Reference
#include "devices/disk.h"
#include <ctype.h>
#include <debug.h>
#include <stdbool.h>
#include <stdio.h>
#include "devices/timer.h"
#include "threads/io.h"
#include "threads/interrupt.h"
#include "threads/synch.h"
Include dependency graph for disk.c:

Classes

struct  disk
 
struct  channel
 

Macros

#define reg_data(CHANNEL)   ((CHANNEL)->reg_base + 0) /* Data. */
 
#define reg_error(CHANNEL)   ((CHANNEL)->reg_base + 1) /* Error. */
 
#define reg_nsect(CHANNEL)   ((CHANNEL)->reg_base + 2) /* Sector Count. */
 
#define reg_lbal(CHANNEL)   ((CHANNEL)->reg_base + 3) /* LBA 0:7. */
 
#define reg_lbam(CHANNEL)   ((CHANNEL)->reg_base + 4) /* LBA 15:8. */
 
#define reg_lbah(CHANNEL)   ((CHANNEL)->reg_base + 5) /* LBA 23:16. */
 
#define reg_device(CHANNEL)   ((CHANNEL)->reg_base + 6) /* Device/LBA 27:24. */
 
#define reg_status(CHANNEL)   ((CHANNEL)->reg_base + 7) /* Status (r/o). */
 
#define reg_command(CHANNEL)   reg_status (CHANNEL) /* Command (w/o). */
 
#define reg_ctl(CHANNEL)   ((CHANNEL)->reg_base + 0x206) /* Control (w/o). */
 
#define reg_alt_status(CHANNEL)   reg_ctl (CHANNEL) /* Alt Status (r/o). */
 
#define STA_BSY   0x80 /* Busy. */
 
#define STA_DRDY   0x40 /* Device Ready. */
 
#define STA_DRQ   0x08 /* Data Request. */
 
#define CTL_SRST   0x04 /* Software Reset. */
 
#define DEV_MBS   0xa0 /* Must be set. */
 
#define DEV_LBA   0x40 /* Linear based addressing. */
 
#define DEV_DEV   0x10 /* Select device: 0=master, 1=slave. */
 
#define CMD_IDENTIFY_DEVICE   0xec /* IDENTIFY DEVICE. */
 
#define CMD_READ_SECTOR_RETRY   0x20 /* READ SECTOR with retries. */
 
#define CMD_WRITE_SECTOR_RETRY   0x30 /* WRITE SECTOR with retries. */
 
#define CHANNEL_CNT   2
 

Functions

static void reset_channel (struct channel *)
 
static bool check_device_type (struct disk *)
 
static void identify_ata_device (struct disk *)
 
static void select_sector (struct disk *, disk_sector_t)
 
static void issue_pio_command (struct channel *, uint8_t command)
 
static void input_sector (struct channel *, void *)
 
static void output_sector (struct channel *, const void *)
 
static void wait_until_idle (const struct disk *)
 
static bool wait_while_busy (const struct disk *)
 
static void select_device (const struct disk *)
 
static void select_device_wait (const struct disk *)
 
static void interrupt_handler (struct intr_frame *)
 
void disk_init (void)
 
void disk_print_stats (void)
 
struct diskdisk_get (int chan_no, int dev_no)
 
disk_sector_t disk_size (struct disk *d)
 
void disk_read (struct disk *d, disk_sector_t sec_no, void *buffer)
 
void disk_write (struct disk *d, disk_sector_t sec_no, const void *buffer)
 
static void print_ata_string (char *string, size_t size)
 
static void inspect_read_cnt (struct intr_frame *f)
 
static void inspect_write_cnt (struct intr_frame *f)
 
void register_disk_inspect_intr (void)
 

Variables

static struct channel channels [CHANNEL_CNT]
 

Macro Definition Documentation

◆ CHANNEL_CNT

#define CHANNEL_CNT   2

◆ CMD_IDENTIFY_DEVICE

#define CMD_IDENTIFY_DEVICE   0xec /* IDENTIFY DEVICE. */

◆ CMD_READ_SECTOR_RETRY

#define CMD_READ_SECTOR_RETRY   0x20 /* READ SECTOR with retries. */

◆ CMD_WRITE_SECTOR_RETRY

#define CMD_WRITE_SECTOR_RETRY   0x30 /* WRITE SECTOR with retries. */

◆ CTL_SRST

#define CTL_SRST   0x04 /* Software Reset. */

◆ DEV_DEV

#define DEV_DEV   0x10 /* Select device: 0=master, 1=slave. */

◆ DEV_LBA

#define DEV_LBA   0x40 /* Linear based addressing. */

◆ DEV_MBS

#define DEV_MBS   0xa0 /* Must be set. */

◆ reg_alt_status

#define reg_alt_status (   CHANNEL)    reg_ctl (CHANNEL) /* Alt Status (r/o). */

◆ reg_command

#define reg_command (   CHANNEL)    reg_status (CHANNEL) /* Command (w/o). */

◆ reg_ctl

#define reg_ctl (   CHANNEL)    ((CHANNEL)->reg_base + 0x206) /* Control (w/o). */

◆ reg_data

#define reg_data (   CHANNEL)    ((CHANNEL)->reg_base + 0) /* Data. */

◆ reg_device

#define reg_device (   CHANNEL)    ((CHANNEL)->reg_base + 6) /* Device/LBA 27:24. */

◆ reg_error

#define reg_error (   CHANNEL)    ((CHANNEL)->reg_base + 1) /* Error. */

◆ reg_lbah

#define reg_lbah (   CHANNEL)    ((CHANNEL)->reg_base + 5) /* LBA 23:16. */

◆ reg_lbal

#define reg_lbal (   CHANNEL)    ((CHANNEL)->reg_base + 3) /* LBA 0:7. */

◆ reg_lbam

#define reg_lbam (   CHANNEL)    ((CHANNEL)->reg_base + 4) /* LBA 15:8. */

◆ reg_nsect

#define reg_nsect (   CHANNEL)    ((CHANNEL)->reg_base + 2) /* Sector Count. */

◆ reg_status

#define reg_status (   CHANNEL)    ((CHANNEL)->reg_base + 7) /* Status (r/o). */

◆ STA_BSY

#define STA_BSY   0x80 /* Busy. */

◆ STA_DRDY

#define STA_DRDY   0x40 /* Device Ready. */

◆ STA_DRQ

#define STA_DRQ   0x08 /* Data Request. */

Function Documentation

◆ check_device_type()

static bool check_device_type ( struct disk d)
static
320 {
321 struct channel *c = d->channel;
322 uint8_t error, lbam, lbah, status;
323
324 select_device (d);
325
326 error = inb (reg_error (c));
327 lbam = inb (reg_lbam (c));
328 lbah = inb (reg_lbah (c));
329 status = inb (reg_status (c));
330
331 if ((error != 1 && (error != 0x81 || d->dev_no == 1))
332 || (status & STA_DRDY) == 0
333 || (status & STA_BSY) != 0) {
334 d->is_ata = false;
335 return error != 0x81;
336 } else {
337 d->is_ata = (lbam == 0 && lbah == 0) || (lbam == 0x3c && lbah == 0xc3);
338 return true;
339 }
340}
#define reg_lbah(CHANNEL)
Definition: disk.c:20
#define reg_status(CHANNEL)
Definition: disk.c:22
#define STA_DRDY
Definition: disk.c:33
#define STA_BSY
Definition: disk.c:32
#define reg_error(CHANNEL)
Definition: disk.c:16
static void select_device(const struct disk *)
Definition: disk.c:495
#define reg_lbam(CHANNEL)
Definition: disk.c:19
static uint8_t inb(uint16_t port)
Definition: io.h:49
unsigned char uint8_t
Definition: stdint.h:20
Definition: disk.c:66
int dev_no
Definition: disk.c:55
bool is_ata
Definition: disk.c:57
struct channel * channel
Definition: disk.c:54
Here is the call graph for this function:
Here is the caller graph for this function:

◆ disk_get()

struct disk * disk_get ( int  chan_no,
int  dev_no 
)
186 {
187 ASSERT (dev_no == 0 || dev_no == 1);
188
189 if (chan_no < (int) CHANNEL_CNT) {
190 struct disk *d = &channels[chan_no].devices[dev_no];
191 if (d->is_ata)
192 return d;
193 }
194 return NULL;
195}
#define ASSERT(CONDITION)
Definition: debug.h:30
static struct channel channels[CHANNEL_CNT]
Definition: disk.c:81
#define CHANNEL_CNT
Definition: disk.c:80
#define NULL
Definition: stddef.h:4
struct disk devices[2]
Definition: disk.c:76
Definition: disk.c:52
Here is the caller graph for this function:

◆ disk_init()

void disk_init ( void  )
101 {
102 size_t chan_no;
103
104 for (chan_no = 0; chan_no < CHANNEL_CNT; chan_no++) {
105 struct channel *c = &channels[chan_no];
106 int dev_no;
107
108 /* Initialize channel. */
109 snprintf (c->name, sizeof c->name, "hd%zu", chan_no);
110 switch (chan_no) {
111 case 0:
112 c->reg_base = 0x1f0;
113 c->irq = 14 + 0x20;
114 break;
115 case 1:
116 c->reg_base = 0x170;
117 c->irq = 15 + 0x20;
118 break;
119 default:
120 NOT_REACHED ();
121 }
122 lock_init (&c->lock);
123 c->expecting_interrupt = false;
124 sema_init (&c->completion_wait, 0);
125
126 /* Initialize devices. */
127 for (dev_no = 0; dev_no < 2; dev_no++) {
128 struct disk *d = &c->devices[dev_no];
129 snprintf (d->name, sizeof d->name, "%s:%d", c->name, dev_no);
130 d->channel = c;
131 d->dev_no = dev_no;
132
133 d->is_ata = false;
134 d->capacity = 0;
135
136 d->read_cnt = d->write_cnt = 0;
137 }
138
139 /* Register interrupt handler. */
141
142 /* Reset hardware. */
143 reset_channel (c);
144
145 /* Distinguish ATA hard disks from other devices. */
146 if (check_device_type (&c->devices[0]))
147 check_device_type (&c->devices[1]);
148
149 /* Read hard disk identity information. */
150 for (dev_no = 0; dev_no < 2; dev_no++)
151 if (c->devices[dev_no].is_ata)
153 }
154
155 /* DO NOT MODIFY BELOW LINES. */
157}
#define NOT_REACHED()
Definition: debug.h:34
static void identify_ata_device(struct disk *)
Definition: disk.c:346
void register_disk_inspect_intr(void)
Definition: disk.c:551
static void reset_channel(struct channel *)
Definition: disk.c:260
static bool check_device_type(struct disk *)
Definition: disk.c:320
static void interrupt_handler(struct intr_frame *)
Definition: disk.c:516
void intr_register_ext(uint8_t vec, intr_handler_func *, const char *name)
Definition: interrupt.c:228
int int snprintf(char *, size_t, const char *,...) PRINTF_FORMAT(3
bool expecting_interrupt
Definition: disk.c:72
struct semaphore completion_wait
Definition: disk.c:74
char name[8]
Definition: disk.c:67
uint16_t reg_base
Definition: disk.c:68
uint8_t irq
Definition: disk.c:69
struct lock lock
Definition: disk.c:71
disk_sector_t capacity
Definition: disk.c:58
long long write_cnt
Definition: disk.c:61
long long read_cnt
Definition: disk.c:60
char name[8]
Definition: disk.c:53
void sema_init(struct semaphore *, unsigned value)
Definition: synch.c:52
void lock_init(struct lock *)
Definition: synch.c:186
Here is the call graph for this function:
Here is the caller graph for this function:

◆ disk_print_stats()

void disk_print_stats ( void  )
161 {
162 int chan_no;
163
164 for (chan_no = 0; chan_no < CHANNEL_CNT; chan_no++) {
165 int dev_no;
166
167 for (dev_no = 0; dev_no < 2; dev_no++) {
168 struct disk *d = disk_get (chan_no, dev_no);
169 if (d != NULL && d->is_ata)
170 printf ("%s: %lld reads, %lld writes\n",
171 d->name, d->read_cnt, d->write_cnt);
172 }
173 }
174}
struct disk * disk_get(int chan_no, int dev_no)
Definition: disk.c:186
int printf(const char *,...) PRINTF_FORMAT(1
Here is the call graph for this function:
Here is the caller graph for this function:

◆ disk_read()

void disk_read ( struct disk d,
disk_sector_t  sec_no,
void *  buffer 
)
211 {
212 struct channel *c;
213
214 ASSERT (d != NULL);
215 ASSERT (buffer != NULL);
216
217 c = d->channel;
218 lock_acquire (&c->lock);
219 select_sector (d, sec_no);
222 if (!wait_while_busy (d))
223 PANIC ("%s: disk read failed, sector=%"PRDSNu, d->name, sec_no);
224 input_sector (c, buffer);
225 d->read_cnt++;
226 lock_release (&c->lock);
227}
#define PANIC(...)
Definition: debug.h:14
static bool wait_while_busy(const struct disk *)
Definition: disk.c:474
static void issue_pio_command(struct channel *, uint8_t command)
Definition: disk.c:426
static void input_sector(struct channel *, void *)
Definition: disk.c:438
static void select_sector(struct disk *, disk_sector_t)
Definition: disk.c:408
#define CMD_READ_SECTOR_RETRY
Definition: disk.c:48
#define PRDSNu
Definition: disk.h:16
static struct intq buffer
Definition: input.c:7
void lock_release(struct lock *)
Definition: synch.c:243
void sema_down(struct semaphore *)
Definition: synch.c:68
void lock_acquire(struct lock *)
Definition: synch.c:202
Here is the call graph for this function:
Here is the caller graph for this function:

◆ disk_size()

disk_sector_t disk_size ( struct disk d)
200 {
201 ASSERT (d != NULL);
202
203 return d->capacity;
204}
Here is the caller graph for this function:

◆ disk_write()

void disk_write ( struct disk d,
disk_sector_t  sec_no,
const void *  buffer 
)
235 {
236 struct channel *c;
237
238 ASSERT (d != NULL);
239 ASSERT (buffer != NULL);
240
241 c = d->channel;
242 lock_acquire (&c->lock);
243 select_sector (d, sec_no);
245 if (!wait_while_busy (d))
246 PANIC ("%s: disk write failed, sector=%"PRDSNu, d->name, sec_no);
249 d->write_cnt++;
250 lock_release (&c->lock);
251}
#define CMD_WRITE_SECTOR_RETRY
Definition: disk.c:49
static void output_sector(struct channel *, const void *)
Definition: disk.c:445
Here is the call graph for this function:
Here is the caller graph for this function:

◆ identify_ata_device()

static void identify_ata_device ( struct disk d)
static
346 {
347 struct channel *c = d->channel;
349
350 ASSERT (d->is_ata);
351
352 /* Send the IDENTIFY DEVICE command, wait for an interrupt
353 indicating the device's response is ready, and read the data
354 into our buffer. */
358 if (!wait_while_busy (d)) {
359 d->is_ata = false;
360 return;
361 }
362 input_sector (c, id);
363
364 /* Calculate capacity. */
365 d->capacity = id[60] | ((uint32_t) id[61] << 16);
366
367 /* Print identification message. */
368 printf ("%s: detected %'"PRDSNu" sector (", d->name, d->capacity);
369 if (d->capacity > 1024 / DISK_SECTOR_SIZE * 1024 * 1024)
370 printf ("%"PRDSNu" GB",
371 d->capacity / (1024 / DISK_SECTOR_SIZE * 1024 * 1024));
372 else if (d->capacity > 1024 / DISK_SECTOR_SIZE * 1024)
373 printf ("%"PRDSNu" MB", d->capacity / (1024 / DISK_SECTOR_SIZE * 1024));
374 else if (d->capacity > 1024 / DISK_SECTOR_SIZE)
375 printf ("%"PRDSNu" kB", d->capacity / (1024 / DISK_SECTOR_SIZE));
376 else
377 printf ("%"PRDSNu" byte", d->capacity * DISK_SECTOR_SIZE);
378 printf (") disk, model \"");
379 print_ata_string ((char *) &id[27], 40);
380 printf ("\", serial \"");
381 print_ata_string ((char *) &id[10], 20);
382 printf ("\"\n");
383}
#define CMD_IDENTIFY_DEVICE
Definition: disk.c:47
static void print_ata_string(char *string, size_t size)
Definition: disk.c:389
static void select_device_wait(const struct disk *)
Definition: disk.c:508
#define DISK_SECTOR_SIZE
Definition: disk.h:8
unsigned int uint32_t
Definition: stdint.h:26
unsigned short int uint16_t
Definition: stdint.h:23
Here is the call graph for this function:
Here is the caller graph for this function:

◆ input_sector()

static void input_sector ( struct channel c,
void *  sector 
)
static
438 {
439 insw (reg_data (c), sector, DISK_SECTOR_SIZE / 2);
440}
#define reg_data(CHANNEL)
Definition: disk.c:15
static void insw(uint16_t port, void *addr, size_t cnt)
Definition: io.h:79
Here is the call graph for this function:
Here is the caller graph for this function:

◆ inspect_read_cnt()

static void inspect_read_cnt ( struct intr_frame f)
static
533 {
534 struct disk * d = disk_get (f->R.rdx, f->R.rcx);
535 f->R.rax = d->read_cnt;
536}
uint64_t rax
Definition: interrupt.h:34
uint64_t rdx
Definition: interrupt.h:31
uint64_t rcx
Definition: interrupt.h:32
struct gp_registers R
Definition: interrupt.h:40
Here is the call graph for this function:
Here is the caller graph for this function:

◆ inspect_write_cnt()

static void inspect_write_cnt ( struct intr_frame f)
static
539 {
540 struct disk * d = disk_get (f->R.rdx, f->R.rcx);
541 f->R.rax = d->write_cnt;
542}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ interrupt_handler()

static void interrupt_handler ( struct intr_frame f)
static
516 {
517 struct channel *c;
518
519 for (c = channels; c < channels + CHANNEL_CNT; c++)
520 if (f->vec_no == c->irq) {
521 if (c->expecting_interrupt) {
522 inb (reg_status (c)); /* Acknowledge interrupt. */
523 sema_up (&c->completion_wait); /* Wake up waiter. */
524 } else
525 printf ("%s: unexpected interrupt\n", c->name);
526 return;
527 }
528
529 NOT_REACHED ();
530}
uint64_t vec_no
Definition: interrupt.h:48
void sema_up(struct semaphore *)
Definition: synch.c:114
Here is the call graph for this function:
Here is the caller graph for this function:

◆ issue_pio_command()

static void issue_pio_command ( struct channel c,
uint8_t  command 
)
static
426 {
427 /* Interrupts must be enabled or our semaphore will never be
428 up'd by the completion handler. */
430
431 c->expecting_interrupt = true;
432 outb (reg_command (c), command);
433}
#define reg_command(CHANNEL)
Definition: disk.c:23
@ INTR_ON
Definition: interrupt.h:10
enum intr_level intr_get_level(void)
Definition: interrupt.c:115
static void outb(uint16_t port, uint8_t data)
Definition: io.h:109
Here is the call graph for this function:
Here is the caller graph for this function:

◆ output_sector()

static void output_sector ( struct channel c,
const void *  sector 
)
static
445 {
446 outsw (reg_data (c), sector, DISK_SECTOR_SIZE / 2);
447}
static void outsw(uint16_t port, const void *addr, size_t cnt)
Definition: io.h:135
Here is the call graph for this function:
Here is the caller graph for this function:

◆ print_ata_string()

static void print_ata_string ( char *  string,
size_t  size 
)
static
389 {
390 size_t i;
391
392 /* Find the last non-white, non-null character. */
393 for (; size > 0; size--) {
394 int c = string[(size - 1) ^ 1];
395 if (c != '\0' && !isspace (c))
396 break;
397 }
398
399 /* Print. */
400 for (i = 0; i < size; i++)
401 printf ("%c", string[i ^ 1]);
402}
static int isspace(int c)
Definition: ctype.h:12
uint16_t size
Definition: mmu.h:0
Here is the call graph for this function:
Here is the caller graph for this function:

◆ register_disk_inspect_intr()

void register_disk_inspect_intr ( void  )
551 {
552 intr_register_int (0x43, 3, INTR_OFF, inspect_read_cnt, "Inspect Disk Read Count");
553 intr_register_int (0x44, 3, INTR_OFF, inspect_write_cnt, "Inspect Disk Write Count");
554}
static void inspect_write_cnt(struct intr_frame *f)
Definition: disk.c:539
static void inspect_read_cnt(struct intr_frame *f)
Definition: disk.c:533
@ INTR_OFF
Definition: interrupt.h:9
void intr_register_int(uint8_t vec, int dpl, enum intr_level, intr_handler_func *, const char *name)
Definition: interrupt.c:248
Here is the call graph for this function:
Here is the caller graph for this function:

◆ reset_channel()

static void reset_channel ( struct channel c)
static
260 {
261 bool present[2];
262 int dev_no;
263
264 /* The ATA reset sequence depends on which devices are present,
265 so we start by detecting device presence. */
266 for (dev_no = 0; dev_no < 2; dev_no++) {
267 struct disk *d = &c->devices[dev_no];
268
269 select_device (d);
270
271 outb (reg_nsect (c), 0x55);
272 outb (reg_lbal (c), 0xaa);
273
274 outb (reg_nsect (c), 0xaa);
275 outb (reg_lbal (c), 0x55);
276
277 outb (reg_nsect (c), 0x55);
278 outb (reg_lbal (c), 0xaa);
279
280 present[dev_no] = (inb (reg_nsect (c)) == 0x55
281 && inb (reg_lbal (c)) == 0xaa);
282 }
283
284 /* Issue soft reset sequence, which selects device 0 as a side effect.
285 Also enable interrupts. */
286 outb (reg_ctl (c), 0);
287 timer_usleep (10);
288 outb (reg_ctl (c), CTL_SRST);
289 timer_usleep (10);
290 outb (reg_ctl (c), 0);
291
292 timer_msleep (150);
293
294 /* Wait for device 0 to clear BSY. */
295 if (present[0]) {
296 select_device (&c->devices[0]);
297 wait_while_busy (&c->devices[0]);
298 }
299
300 /* Wait for device 1 to clear BSY. */
301 if (present[1]) {
302 int i;
303
304 select_device (&c->devices[1]);
305 for (i = 0; i < 3000; i++) {
306 if (inb (reg_nsect (c)) == 1 && inb (reg_lbal (c)) == 1)
307 break;
308 timer_msleep (10);
309 }
310 wait_while_busy (&c->devices[1]);
311 }
312}
#define reg_ctl(CHANNEL)
Definition: disk.c:28
#define CTL_SRST
Definition: disk.c:37
#define reg_lbal(CHANNEL)
Definition: disk.c:18
#define reg_nsect(CHANNEL)
Definition: disk.c:17
void timer_msleep(int64_t ms)
Definition: timer.c:110
void timer_usleep(int64_t us)
Definition: timer.c:116
Here is the call graph for this function:
Here is the caller graph for this function:

◆ select_device()

static void select_device ( const struct disk d)
static
495 {
496 struct channel *c = d->channel;
497 uint8_t dev = DEV_MBS;
498 if (d->dev_no == 1)
499 dev |= DEV_DEV;
500 outb (reg_device (c), dev);
501 inb (reg_alt_status (c));
502 timer_nsleep (400);
503}
#define reg_device(CHANNEL)
Definition: disk.c:21
#define DEV_DEV
Definition: disk.c:42
#define reg_alt_status(CHANNEL)
Definition: disk.c:29
#define DEV_MBS
Definition: disk.c:40
void timer_nsleep(int64_t ns)
Definition: timer.c:122
Here is the call graph for this function:
Here is the caller graph for this function:

◆ select_device_wait()

static void select_device_wait ( const struct disk d)
static
508 {
509 wait_until_idle (d);
510 select_device (d);
511 wait_until_idle (d);
512}
static void wait_until_idle(const struct disk *)
Definition: disk.c:457
Here is the call graph for this function:
Here is the caller graph for this function:

◆ select_sector()

static void select_sector ( struct disk d,
disk_sector_t  sec_no 
)
static
408 {
409 struct channel *c = d->channel;
410
411 ASSERT (sec_no < d->capacity);
412 ASSERT (sec_no < (1UL << 28));
413
415 outb (reg_nsect (c), 1);
416 outb (reg_lbal (c), sec_no);
417 outb (reg_lbam (c), sec_no >> 8);
418 outb (reg_lbah (c), (sec_no >> 16));
419 outb (reg_device (c),
420 DEV_MBS | DEV_LBA | (d->dev_no == 1 ? DEV_DEV : 0) | (sec_no >> 24));
421}
#define DEV_LBA
Definition: disk.c:41
Here is the call graph for this function:
Here is the caller graph for this function:

◆ wait_until_idle()

static void wait_until_idle ( const struct disk d)
static
457 {
458 int i;
459
460 for (i = 0; i < 1000; i++) {
461 if ((inb (reg_status (d->channel)) & (STA_BSY | STA_DRQ)) == 0)
462 return;
463 timer_usleep (10);
464 }
465
466 printf ("%s: idle timeout\n", d->name);
467}
#define STA_DRQ
Definition: disk.c:34
Here is the call graph for this function:
Here is the caller graph for this function:

◆ wait_while_busy()

static bool wait_while_busy ( const struct disk d)
static
474 {
475 struct channel *c = d->channel;
476 int i;
477
478 for (i = 0; i < 3000; i++) {
479 if (i == 700)
480 printf ("%s: busy, waiting...", d->name);
481 if (!(inb (reg_alt_status (c)) & STA_BSY)) {
482 if (i >= 700)
483 printf ("ok\n");
484 return (inb (reg_alt_status (c)) & STA_DRQ) != 0;
485 }
486 timer_msleep (10);
487 }
488
489 printf ("failed\n");
490 return false;
491}
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ channels

struct channel channels[CHANNEL_CNT]
static