+/* Write sector SEC_NO to disk D from BUFFER, which must contain
+ DISK_SECTOR_SIZE bytes. Returns after the disk has
+ acknowledged receiving the data.
+ Internally synchronizes accesses to disks, so external
+ per-disk locking is unneeded. */
+void
+disk_write (struct disk *d, disk_sector_t sec_no, const void *buffer)
+{
+ struct channel *c;
+
+ ASSERT (d != NULL);
+ ASSERT (buffer != NULL);
+
+ c = d->channel;
+ lock_acquire (&c->lock);
+ select_sector (d, sec_no);
+ issue_pio_command (c, CMD_WRITE_SECTOR_RETRY);
+ if (!wait_while_busy (d))
+ PANIC ("%s: disk write failed, sector=%"PRDSNu, d->name, sec_no);
+ output_sector (c, buffer);
+ sema_down (&c->completion_wait);
+ d->write_cnt++;
+ lock_release (&c->lock);
+}
+\f
+/* Disk detection and identification. */
+
+static void print_ata_string (char *string, size_t size);
+
+/* Resets an ATA channel and waits for any devices present on it
+ to finish the reset. */