Changes in uspace/drv/bus/isa/i8237.c [1558d85:3e6a98c5] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/isa/i8237.c
r1558d85 r3e6a98c5 38 38 #include <stdbool.h> 39 39 #include <errno.h> 40 #include <fibril_synch.h> 40 41 #include <ddi.h> 41 42 #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 { /* 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,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, 231 231 }, 232 232 233 233 /* The second chip 16-bit */ 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,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, 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);324 306 } 325 307 … … 338 320 * 339 321 * @return Error code. 340 */ 341 int dma_channel_setup(unsigned int channel, uint32_t pa, uint32_t size, 322 * 323 */ 324 int dma_setup_channel(unsigned int channel, uint32_t pa, uint16_t size, 342 325 uint8_t mode) 343 326 { 344 if (!is_dma8(channel) && !is_dma16(channel))345 return ENOENT;346 347 327 if ((channel == 0) || (channel == 4)) 348 328 return ENOTSUP; 329 330 if (channel > 7) 331 return ENOENT; 349 332 350 333 /* DMA is limited to 24bit addresses. */ … … 353 336 354 337 /* 8 bit channels use only 4 bits from the page register. */ 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)) 338 if ((channel > 0) && (channel < 4) && (pa >= (1 << 20))) 360 339 return EINVAL; 361 340 … … 373 352 ddf_msg(LVL_DEBUG, "Unspoiled address %#" PRIx32 " (size %" PRIu16 ")", 374 353 pa, size); 375 if ( is_dma16(channel)) {354 if (channel > 4) { 376 355 /* Size must be aligned to 16 bits */ 377 356 if ((size & 1) != 0) { … … 379 358 return EINVAL; 380 359 } 381 /* Size is in 2byte words */360 382 361 size >>= 1; 362 383 363 /* Address is fun: lower 16 bits need to be shifted by 1 */ 384 364 pa = ((pa & 0xffff) >> 1) | (pa & 0xff0000); … … 446 426 } 447 427 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 get489 * 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 }495 428 /** 496 429 * @}
Note:
See TracChangeset
for help on using the changeset viewer.