Quellcode durchsuchen

Use separate data-in and data-out buffers.

Increase code simplicity at the expense of around 64 bytes.
tags/v0.9.3
Michael Brown vor 19 Jahren
Ursprung
Commit
6f998cecb3
2 geänderte Dateien mit 67 neuen und 69 gelöschten Zeilen
  1. 30
    40
      src/drivers/block/ata.c
  2. 37
    29
      src/include/gpxe/ata.h

+ 30
- 40
src/drivers/block/ata.c Datei anzeigen

51
 }
51
 }
52
 
52
 
53
 /**
53
 /**
54
- * Read block from / write block to ATA device
54
+ * Read block from ATA device
55
  *
55
  *
56
- * @v write		Write flag (ATA_FL_WRITE or 0)
57
  * @v blockdev		Block device
56
  * @v blockdev		Block device
58
  * @v block		LBA block number
57
  * @v block		LBA block number
59
  * @v count		Block count
58
  * @v count		Block count
60
  * @v buffer		Data buffer
59
  * @v buffer		Data buffer
61
  * @ret rc		Return status code
60
  * @ret rc		Return status code
62
  */
61
  */
63
-static __attribute__ (( regparm ( 1 ) )) int
64
-ata_rw ( int write, struct block_device *blockdev, uint64_t block,
65
-	 unsigned long count, userptr_t buffer ) {
62
+static int ata_read ( struct block_device *blockdev, uint64_t block,
63
+		      unsigned long count, userptr_t buffer ) {
66
 	struct ata_device *ata = block_to_ata ( blockdev );
64
 	struct ata_device *ata = block_to_ata ( blockdev );
67
 	struct ata_command command;
65
 	struct ata_command command;
68
-	int lba48 = ( ata->flags & ATA_FL_LBA48 );
69
 
66
 
70
 	memset ( &command, 0, sizeof ( command ) );
67
 	memset ( &command, 0, sizeof ( command ) );
71
 	command.cb.lba.native = block;
68
 	command.cb.lba.native = block;
72
 	command.cb.count.native = count;
69
 	command.cb.count.native = count;
73
-	command.cb.device = ( ata->flags | ATA_DEV_OBSOLETE | ATA_DEV_LBA );
74
-	command.cb.flags = ( ata->flags | write );
75
-	command.cb.cmd_stat = ( write ? ATA_CMD_WRITE : ATA_CMD_READ );
76
-	if ( lba48 ) {
77
-		command.cb.cmd_stat |= ATA_CMD_EXT;
78
-	} else {
70
+	command.cb.device = ( ata->device | ATA_DEV_OBSOLETE | ATA_DEV_LBA );
71
+	command.cb.lba48 = ata->lba48;
72
+	if ( ! ata->lba48 )
79
 		command.cb.device |= command.cb.lba.bytes.low_prev;
73
 		command.cb.device |= command.cb.lba.bytes.low_prev;
80
-	}
81
-	command.data = buffer;
82
-	command.data_len = ( count * blockdev->blksize );
74
+	command.cb.cmd_stat = ( ata->lba48 ? ATA_CMD_READ_EXT : ATA_CMD_READ );
75
+	command.data_in = buffer;
76
+	command.data_in_len = ( count * blockdev->blksize );
83
 	return ata_command ( ata, &command );
77
 	return ata_command ( ata, &command );
84
 }
78
 }
85
 
79
 
86
-/**
87
- * Read block from ATA device
88
- *
89
- * @v blockdev		Block device
90
- * @v block		LBA block number
91
- * @v count		Block count
92
- * @v buffer		Data buffer
93
- * @ret rc		Return status code
94
- */
95
-static int ata_read ( struct block_device *blockdev, uint64_t block,
96
-		      unsigned long count, userptr_t buffer ) {
97
-	/* Pass through to ata_rw().  Since ata_rw is regparm(1), this
98
-	 * is extremely efficient; just a mov and a jmp.
99
-	 */
100
-	return ata_rw ( 0, blockdev, block, count, buffer );
101
-}
102
-
103
 /**
80
 /**
104
  * Write block to ATA device
81
  * Write block to ATA device
105
  *
82
  *
111
  */
88
  */
112
 static int ata_write ( struct block_device *blockdev, uint64_t block,
89
 static int ata_write ( struct block_device *blockdev, uint64_t block,
113
 		       unsigned long count, userptr_t buffer ) {
90
 		       unsigned long count, userptr_t buffer ) {
114
-	/* Pass through to ata_rw().  Since ata_rw is regparm(1), this
115
-	 * is extremely efficient; just a mov and a jmp.
116
-	 */
117
-	return ata_rw ( ATA_FL_WRITE, blockdev, block, count, buffer );
91
+	struct ata_device *ata = block_to_ata ( blockdev );
92
+	struct ata_command command;
93
+	
94
+	memset ( &command, 0, sizeof ( command ) );
95
+	command.cb.lba.native = block;
96
+	command.cb.count.native = count;
97
+	command.cb.device = ( ata->device | ATA_DEV_OBSOLETE | ATA_DEV_LBA );
98
+	command.cb.lba48 = ata->lba48;
99
+	if ( ! ata->lba48 )
100
+		command.cb.device |= command.cb.lba.bytes.low_prev;
101
+	command.cb.cmd_stat = ( ata->lba48 ?
102
+				ATA_CMD_WRITE_EXT : ATA_CMD_WRITE );
103
+	command.data_out = buffer;
104
+	command.data_out_len = ( count * blockdev->blksize );
105
+	return ata_command ( ata, &command );
118
 }
106
 }
119
 
107
 
120
 /**
108
 /**
131
 
119
 
132
 	/* Issue IDENTIFY */
120
 	/* Issue IDENTIFY */
133
 	memset ( &command, 0, sizeof ( command ) );
121
 	memset ( &command, 0, sizeof ( command ) );
134
-	command.cb.device = ( ata->flags | ATA_DEV_OBSOLETE | ATA_DEV_LBA );
122
+	command.cb.count.native = 1; /* n/a according to spec, but at least
123
+				      * AoE vblade devices require it. */
124
+	command.cb.device = ( ata->device | ATA_DEV_OBSOLETE | ATA_DEV_LBA );
135
 	command.cb.cmd_stat = ATA_CMD_IDENTIFY;
125
 	command.cb.cmd_stat = ATA_CMD_IDENTIFY;
136
-	command.data = virt_to_user ( &identity );
137
-	command.data_len = sizeof ( identity );
126
+	command.data_in = virt_to_user ( &identity );
127
+	command.data_in_len = sizeof ( identity );
138
 	if ( ( rc = ata_command ( ata, &command ) ) != 0 )
128
 	if ( ( rc = ata_command ( ata, &command ) ) != 0 )
139
 		return rc;
129
 		return rc;
140
 
130
 
141
 	/* Fill in block device parameters */
131
 	/* Fill in block device parameters */
142
 	blockdev->blksize = ATA_SECTOR_SIZE;
132
 	blockdev->blksize = ATA_SECTOR_SIZE;
143
 	if ( identity.supports_lba48 & cpu_to_le16 ( ATA_SUPPORTS_LBA48 ) ) {
133
 	if ( identity.supports_lba48 & cpu_to_le16 ( ATA_SUPPORTS_LBA48 ) ) {
144
-		ata->flags |= ATA_FL_LBA48;
134
+		ata->lba48 = 1;
145
 		blockdev->blocks = le64_to_cpu ( identity.lba48_sectors );
135
 		blockdev->blocks = le64_to_cpu ( identity.lba48_sectors );
146
 	} else {
136
 	} else {
147
 		blockdev->blocks = le32_to_cpu ( identity.lba_sectors );
137
 		blockdev->blocks = le32_to_cpu ( identity.lba_sectors );

+ 37
- 29
src/include/gpxe/ata.h Datei anzeigen

56
 		uint8_t low_prev;
56
 		uint8_t low_prev;
57
 		uint8_t mid_prev;
57
 		uint8_t mid_prev;
58
 		uint8_t high_prev;
58
 		uint8_t high_prev;
59
-		uint8_t pad[2];
59
+		uint16_t pad;
60
 #elif __BYTE_ORDER == __BIG_ENDIAN
60
 #elif __BYTE_ORDER == __BIG_ENDIAN
61
-		uint8_t pad[2];
61
+		uint16_t pad;
62
 		uint8_t high_prev;
62
 		uint8_t high_prev;
63
 		uint8_t mid_prev;
63
 		uint8_t mid_prev;
64
 		uint8_t low_prev;
64
 		uint8_t low_prev;
101
 	uint8_t device;
101
 	uint8_t device;
102
 	/** Command/status register */
102
 	/** Command/status register */
103
 	uint8_t cmd_stat;
103
 	uint8_t cmd_stat;
104
-	/** Flags
105
-	 *
106
-	 * This field does not correspond to any ATA register.
107
-	 */
108
-	uint8_t flags;
104
+	/** LBA48 addressing flag */
105
+	int lba48;
109
 };
106
 };
110
 
107
 
111
-/** LBA48 extended addressing */
112
-#define ATA_FL_LBA48 0x40
113
-
114
-/** Device 1 ("slave") */
115
-#define ATA_FL_SLAVE 0x10
116
-
117
-/** Write command */
118
-#define ATA_FL_WRITE 0x01
119
-
120
 /** Obsolete bits in the ATA device register */
108
 /** Obsolete bits in the ATA device register */
121
 #define ATA_DEV_OBSOLETE 0xa0
109
 #define ATA_DEV_OBSOLETE 0xa0
122
 
110
 
123
 /** LBA flag in the ATA device register */
111
 /** LBA flag in the ATA device register */
124
 #define ATA_DEV_LBA 0x40
112
 #define ATA_DEV_LBA 0x40
125
 
113
 
114
+/** Slave ("device 1") flag in the ATA device register */
115
+#define ATA_DEV_SLAVE 0x10
116
+
117
+/** Master ("device 0") flag in the ATA device register */
118
+#define ATA_DEV_MASTER 0x00
119
+
126
 /** "Read sectors" command */
120
 /** "Read sectors" command */
127
 #define ATA_CMD_READ 0x20
121
 #define ATA_CMD_READ 0x20
128
 
122
 
123
+/** "Read sectors (ext)" command */
124
+#define ATA_CMD_READ_EXT 0x24
125
+
129
 /** "Write sectors" command */
126
 /** "Write sectors" command */
130
 #define ATA_CMD_WRITE 0x30
127
 #define ATA_CMD_WRITE 0x30
131
 
128
 
129
+/** "Write sectors (ext)" command */
130
+#define ATA_CMD_WRITE_EXT 0x34
131
+
132
 /** "Identify" command */
132
 /** "Identify" command */
133
 #define ATA_CMD_IDENTIFY 0xec
133
 #define ATA_CMD_IDENTIFY 0xec
134
 
134
 
135
-/** "Extended (LBA48)" command modifier
136
- *
137
- * This doesn't apply to all ATA commands, but it does for @c
138
- * ATA_CMD_READ and @c ATA_CMD_WRITE.
139
- */
140
-#define ATA_CMD_EXT 0x04
141
-
142
 /** An ATA command */
135
 /** An ATA command */
143
 struct ata_command {
136
 struct ata_command {
144
 	/** ATA command block */
137
 	/** ATA command block */
145
 	struct ata_cb cb;
138
 	struct ata_cb cb;
146
-	/** Data buffer */
147
-	userptr_t data;
148
-	/** Data buffer length */
149
-	size_t data_len;
139
+	/** Data-out buffer (may be NULL) */
140
+	userptr_t data_out;
141
+	/** Data-out buffer length
142
+	 *
143
+	 * Must be zero if @c data_out is NULL
144
+	 */
145
+	size_t data_out_len;
146
+	/** Data-in buffer (may be NULL) */
147
+	userptr_t data_in;
148
+	/** Data-in buffer length
149
+	 *
150
+	 * Must be zero if @c data_in is NULL
151
+	 */
152
+	size_t data_in_len;
150
 };
153
 };
151
 
154
 
152
 /**
155
 /**
175
 struct ata_device {
178
 struct ata_device {
176
 	/** Block device interface */
179
 	/** Block device interface */
177
 	struct block_device blockdev;
180
 	struct block_device blockdev;
178
-	/** Flags */
179
-	int flags;
181
+	/** Device number
182
+	 *
183
+	 * Must be ATA_DEV_MASTER or ATA_DEV_SLAVE.
184
+	 */
185
+	int device;
186
+	/** LBA48 extended addressing */
187
+	int lba48;
180
 	/**
188
 	/**
181
 	 * Issue ATA command
189
 	 * Issue ATA command
182
 	 *
190
 	 *

Laden…
Abbrechen
Speichern