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