Changes in uspace/drv/bus/isa/i8237.c [3e6a98c5:1558d85] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/isa/i8237.c
r3e6a98c5 r1558d85 38 38 #include <stdbool.h> 39 39 #include <errno.h> 40 #include <fibril_synch.h>41 40 #include <ddi.h> 42 41 #include <ddf/log.h> 42 #include <fibril_synch.h> 43 43 #include "i8237.h" 44 44 … … 198 198 .channels = { 199 199 /* The first chip 8-bit */ 200 { 201 (uint8_t *) 0x00,202 (uint8_t *) 0x01,203 (uint8_t *) 0x87,204 (uint8_t *) 0x0a,205 (uint8_t *) 0x0b,206 (uint8_t *) 0x0c,207 }, 208 { 209 (uint8_t *) 0x02,210 (uint8_t *) 0x03,211 (uint8_t *) 0x83,212 (uint8_t *) 0x0a,213 (uint8_t *) 0x0b,214 (uint8_t *) 0x0c,215 }, 216 { 217 (uint8_t *) 0x04,218 (uint8_t *) 0x05,219 (uint8_t *) 0x81,220 (uint8_t *) 0x0a,221 (uint8_t *) 0x0b,222 (uint8_t *) 0x0c,223 }, 224 { 225 (uint8_t *) 0x06,226 (uint8_t *) 0x07,227 (uint8_t *) 0x82,228 (uint8_t *) 0x0a,229 (uint8_t *) 0x0b,230 (uint8_t *) 0x0c,200 { /* Channel 0 - Unusable*/ 201 .offset_reg_address = (uint8_t *) 0x00, 202 .size_reg_address = (uint8_t *) 0x01, 203 .page_reg_address = (uint8_t *) 0x87, 204 .single_mask_address = (uint8_t *) 0x0a, 205 .mode_address = (uint8_t *) 0x0b, 206 .flip_flop_address = (uint8_t *) 0x0c, 207 }, 208 { /* Channel 1 */ 209 .offset_reg_address = (uint8_t *) 0x02, 210 .size_reg_address = (uint8_t *) 0x03, 211 .page_reg_address = (uint8_t *) 0x83, 212 .single_mask_address = (uint8_t *) 0x0a, 213 .mode_address = (uint8_t *) 0x0b, 214 .flip_flop_address = (uint8_t *) 0x0c, 215 }, 216 { /* Channel 2 */ 217 .offset_reg_address = (uint8_t *) 0x04, 218 .size_reg_address = (uint8_t *) 0x05, 219 .page_reg_address = (uint8_t *) 0x81, 220 .single_mask_address = (uint8_t *) 0x0a, 221 .mode_address = (uint8_t *) 0x0b, 222 .flip_flop_address = (uint8_t *) 0x0c, 223 }, 224 { /* Channel 3 */ 225 .offset_reg_address = (uint8_t *) 0x06, 226 .size_reg_address = (uint8_t *) 0x07, 227 .page_reg_address = (uint8_t *) 0x82, 228 .single_mask_address = (uint8_t *) 0x0a, 229 .mode_address = (uint8_t *) 0x0b, 230 .flip_flop_address = (uint8_t *) 0x0c, 231 231 }, 232 232 233 233 /* The second chip 16-bit */ 234 { 235 (uint8_t *) 0xc0,236 (uint8_t *) 0xc2,237 (uint8_t *) 0x8f,238 (uint8_t *) 0xd4,239 (uint8_t *) 0xd6,240 (uint8_t *) 0xd8,241 }, 242 { 243 (uint8_t *) 0xc4,244 (uint8_t *) 0xc6,245 (uint8_t *) 0x8b,246 (uint8_t *) 0xd4,247 (uint8_t *) 0xd6,248 (uint8_t *) 0xd8,249 }, 250 { 251 (uint8_t *) 0xc8,252 (uint8_t *) 0xca,253 (uint8_t *) 0x89,254 (uint8_t *) 0xd4,255 (uint8_t *) 0xd6,256 (uint8_t *) 0xd8,257 }, 258 { 259 (uint8_t *) 0xcc,260 (uint8_t *) 0xce,261 (uint8_t *) 0x8a,262 (uint8_t *) 0xd4,263 (uint8_t *) 0xd6,264 (uint8_t *) 0xd8,234 { /* Channel 4 - Unusable */ 235 .offset_reg_address = (uint8_t *) 0xc0, 236 .size_reg_address = (uint8_t *) 0xc2, 237 .page_reg_address = (uint8_t *) 0x8f, 238 .single_mask_address = (uint8_t *) 0xd4, 239 .mode_address = (uint8_t *) 0xd6, 240 .flip_flop_address = (uint8_t *) 0xd8, 241 }, 242 { /* Channel 5 */ 243 .offset_reg_address = (uint8_t *) 0xc4, 244 .size_reg_address = (uint8_t *) 0xc6, 245 .page_reg_address = (uint8_t *) 0x8b, 246 .single_mask_address = (uint8_t *) 0xd4, 247 .mode_address = (uint8_t *) 0xd6, 248 .flip_flop_address = (uint8_t *) 0xd8, 249 }, 250 { /* Channel 6 */ 251 .offset_reg_address = (uint8_t *) 0xc8, 252 .size_reg_address = (uint8_t *) 0xca, 253 .page_reg_address = (uint8_t *) 0x89, 254 .single_mask_address = (uint8_t *) 0xd4, 255 .mode_address = (uint8_t *) 0xd6, 256 .flip_flop_address = (uint8_t *) 0xd8, 257 }, 258 { /* Channel 7 */ 259 .offset_reg_address = (uint8_t *) 0xcc, 260 .size_reg_address = (uint8_t *) 0xce, 261 .page_reg_address = (uint8_t *) 0x8a, 262 .single_mask_address = (uint8_t *) 0xd4, 263 .mode_address = (uint8_t *) 0xd6, 264 .flip_flop_address = (uint8_t *) 0xd8, 265 265 }, 266 266 }, … … 272 272 }; 273 273 274 /* Initialize I/O access to DMA controller I/O ports.274 /** Initialize I/O access to DMA controller I/O ports. 275 275 * 276 276 * @param controller DMA Controller structure to initialize. … … 304 304 305 305 return EOK; 306 } 307 308 /** Helper function. Channels 4,5,6, and 7 are 8 bit DMA. 309 * @pram channel DMA channel. 310 * @reutrn True, if channel is 4,5,6, or 7, false otherwise. 311 */ 312 static inline bool is_dma16(unsigned channel) 313 { 314 return (channel >= 4) && (channel < 8); 315 } 316 317 /** Helper function. Channels 0,1,2, and 3 are 8 bit DMA. 318 * @pram channel DMA channel. 319 * @reutrn True, if channel is 0,1,2, or 3, false otherwise. 320 */ 321 static inline bool is_dma8(unsigned channel) 322 { 323 return (channel < 4); 306 324 } 307 325 … … 320 338 * 321 339 * @return Error code. 322 * 323 */ 324 int dma_setup_channel(unsigned int channel, uint32_t pa, uint16_t size, 340 */ 341 int dma_channel_setup(unsigned int channel, uint32_t pa, uint32_t size, 325 342 uint8_t mode) 326 343 { 344 if (!is_dma8(channel) && !is_dma16(channel)) 345 return ENOENT; 346 327 347 if ((channel == 0) || (channel == 4)) 328 348 return ENOTSUP; 329 330 if (channel > 7)331 return ENOENT;332 349 333 350 /* DMA is limited to 24bit addresses. */ … … 336 353 337 354 /* 8 bit channels use only 4 bits from the page register. */ 338 if ((channel > 0) && (channel < 4) && (pa >= (1 << 20))) 355 if (is_dma8(channel) && (pa >= (1 << 20))) 356 return EINVAL; 357 358 /* Buffers cannot cross 64K page boundaries */ 359 if ((pa & 0xffff0000) != ((pa + size - 1) & 0xffff0000)) 339 360 return EINVAL; 340 361 … … 352 373 ddf_msg(LVL_DEBUG, "Unspoiled address %#" PRIx32 " (size %" PRIu16 ")", 353 374 pa, size); 354 if ( channel > 4) {375 if (is_dma16(channel)) { 355 376 /* Size must be aligned to 16 bits */ 356 377 if ((size & 1) != 0) { … … 358 379 return EINVAL; 359 380 } 360 381 /* Size is in 2byte words */ 361 382 size >>= 1; 362 363 383 /* Address is fun: lower 16 bits need to be shifted by 1 */ 364 384 pa = ((pa & 0xffff) >> 1) | (pa & 0xff0000); … … 426 446 } 427 447 448 /** Query remaining buffer size. 449 * 450 * @param channel DMA Channel 1, 2, 3 for 8 bit transfers, 451 * 5, 6, 7 for 16 bit. 452 * @param size Place to store number of bytes pending in the assigned buffer. 453 * 454 * @return Error code. 455 */ 456 int dma_channel_remain(unsigned channel, size_t *size) 457 { 458 assert(size); 459 if (!is_dma8(channel) && !is_dma16(channel)) 460 return ENOENT; 461 462 if ((channel == 0) || (channel == 4)) 463 return ENOTSUP; 464 465 fibril_mutex_lock(&guard); 466 if (!controller_8237.initialized) { 467 fibril_mutex_unlock(&guard); 468 return EIO; 469 } 470 471 const dma_channel_t dma_channel = controller_8237.channels[channel]; 472 /* Get size - reset flip-flop */ 473 pio_write_8(dma_channel.flip_flop_address, 0); 474 475 /* Low byte */ 476 const uint8_t value_low = pio_read_8(dma_channel.size_reg_address); 477 ddf_msg(LVL_DEBUG2, "Read size low byte: %p:%x.", 478 dma_channel.size_reg_address, value_low); 479 480 /* High byte */ 481 const uint8_t value_high = pio_read_8(dma_channel.size_reg_address); 482 ddf_msg(LVL_DEBUG2, "Read size high byte: %p:%x.", 483 dma_channel.size_reg_address, value_high); 484 fibril_mutex_unlock(&guard); 485 486 uint16_t remain = (value_high << 8 | value_low) ; 487 /* 16 bit DMA size is in words, 488 * the upper bits are bogus for 16bit transfers so we need to get 489 * rid of them. Using limited type works well.*/ 490 if (is_dma16(channel)) 491 remain <<= 1; 492 *size = is_dma16(channel) ? remain + 2: remain + 1; 493 return EOK; 494 } 428 495 /** 429 496 * @}
Note:
See TracChangeset
for help on using the changeset viewer.