Changes in uspace/drv/bus/isa/i8237.c [3869c596:3e6a98c5] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/isa/i8237.c
r3869c596 r3e6a98c5 36 36 37 37 #include <assert.h> 38 #include < bool.h>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 #include <libarch/ddi.h>44 43 #include "i8237.h" 45 44 … … 199 198 .channels = { 200 199 /* The first chip 8-bit */ 201 { /* Channel 0 - Unusable*/202 .offset_reg_address =(uint8_t *) 0x00,203 .size_reg_address =(uint8_t *) 0x01,204 .page_reg_address =(uint8_t *) 0x87,205 .single_mask_address =(uint8_t *) 0x0a,206 .mode_address =(uint8_t *) 0x0b,207 .flip_flop_address =(uint8_t *) 0x0c,208 }, 209 { /* Channel 1 */210 .offset_reg_address =(uint8_t *) 0x02,211 .size_reg_address =(uint8_t *) 0x03,212 .page_reg_address =(uint8_t *) 0x83,213 .single_mask_address =(uint8_t *) 0x0a,214 .mode_address =(uint8_t *) 0x0b,215 .flip_flop_address =(uint8_t *) 0x0c,216 }, 217 { /* Channel 2 */218 .offset_reg_address =(uint8_t *) 0x04,219 .size_reg_address =(uint8_t *) 0x05,220 .page_reg_address =(uint8_t *) 0x81,221 .single_mask_address =(uint8_t *) 0x0a,222 .mode_address =(uint8_t *) 0x0b,223 .flip_flop_address =(uint8_t *) 0x0c,224 }, 225 { /* Channel 3 */226 .offset_reg_address =(uint8_t *) 0x06,227 .size_reg_address =(uint8_t *) 0x07,228 .page_reg_address =(uint8_t *) 0x82,229 .single_mask_address =(uint8_t *) 0x0a,230 .mode_address =(uint8_t *) 0x0b,231 .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, 232 231 }, 233 232 234 233 /* The second chip 16-bit */ 235 { /* Channel 4 - Unusable */236 .offset_reg_address =(uint8_t *) 0xc0,237 .size_reg_address =(uint8_t *) 0xc2,238 .page_reg_address =(uint8_t *) 0x8f,239 .single_mask_address =(uint8_t *) 0xd4,240 .mode_address =(uint8_t *) 0xd6,241 .flip_flop_address =(uint8_t *) 0xd8,242 }, 243 { /* Channel 5 */244 .offset_reg_address =(uint8_t *) 0xc4,245 .size_reg_address =(uint8_t *) 0xc6,246 .page_reg_address =(uint8_t *) 0x8b,247 .single_mask_address =(uint8_t *) 0xd4,248 .mode_address =(uint8_t *) 0xd6,249 .flip_flop_address =(uint8_t *) 0xd8,250 }, 251 { /* Channel 6 */252 .offset_reg_address =(uint8_t *) 0xc8,253 .size_reg_address =(uint8_t *) 0xca,254 .page_reg_address =(uint8_t *) 0x89,255 .single_mask_address =(uint8_t *) 0xd4,256 .mode_address =(uint8_t *) 0xd6,257 .flip_flop_address =(uint8_t *) 0xd8,258 }, 259 { /* Channel 7 */260 .offset_reg_address =(uint8_t *) 0xcc,261 .size_reg_address =(uint8_t *) 0xce,262 .page_reg_address =(uint8_t *) 0x8a,263 .single_mask_address =(uint8_t *) 0xd4,264 .mode_address =(uint8_t *) 0xd6,265 .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, 266 265 }, 267 266 }, … … 273 272 }; 274 273 275 /* *Initialize I/O access to DMA controller I/O ports.274 /* Initialize I/O access to DMA controller I/O ports. 276 275 * 277 276 * @param controller DMA Controller structure to initialize. 278 277 * 279 278 * @return Error code. 279 * 280 280 */ 281 281 static inline int dma_controller_init(dma_controller_t *controller) … … 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, uint16_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) & 0xffff0000)) 338 if ((channel > 0) && (channel < 4) && (pa >= (1 << 20))) 360 339 return EINVAL; 361 340 … … 370 349 } 371 350 372 ddf_msg(LVL_DEBUG, "Unspoiled address: %p and size: %zu.", pa, size);373 374 351 /* 16 bit transfers are a bit special */ 375 if (is_dma16(channel)) { 352 ddf_msg(LVL_DEBUG, "Unspoiled address %#" PRIx32 " (size %" PRIu16 ")", 353 pa, size); 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); … … 387 367 const dma_channel_t dma_channel = controller_8237.channels[channel]; 388 368 389 ddf_msg(LVL_DEBUG, "Setting channel %u , to address %p(%zu), mode %hhx.",390 channel, pa, size, mode);369 ddf_msg(LVL_DEBUG, "Setting channel %u to address %#" PRIx32 " " 370 "(size %" PRIu16 "), mode %hhx.", channel, pa, size, mode); 391 371 392 372 /* Mask DMA request */ … … 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:%zx.",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:%zx.",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.