Changes in uspace/drv/bus/isa/i8237.c [e5bc912:3e6a98c5] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/isa/i8237.c
re5bc912 r3e6a98c5 38 38 #include <stdbool.h> 39 39 #include <errno.h> 40 #include <ddi.h>41 #include <ddf/log.h>42 40 #include <fibril_synch.h> 43 41 #include <ddi.h> … … 200 198 .channels = { 201 199 /* The first chip 8-bit */ 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,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, 233 231 }, 234 232 235 233 /* The second chip 16-bit */ 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,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, 267 265 }, 268 266 }, … … 274 272 }; 275 273 276 /* *Initialize I/O access to DMA controller I/O ports.274 /* Initialize I/O access to DMA controller I/O ports. 277 275 * 278 276 * @param controller DMA Controller structure to initialize. 279 277 * 280 278 * @return Error code. 279 * 281 280 */ 282 281 static inline int dma_controller_init(dma_controller_t *controller) … … 305 304 306 305 return EOK; 307 }308 309 /** Helper function. Channels 4,5,6, and 7 are 8 bit DMA.310 * @pram channel DMA channel.311 * @reutrn True, if channel is 4,5,6, or 7, false otherwise.312 */313 static inline bool is_dma16(unsigned channel)314 {315 return (channel >= 4) && (channel < 8);316 }317 318 /** Helper function. Channels 0,1,2, and 3 are 8 bit DMA.319 * @pram channel DMA channel.320 * @reutrn True, if channel is 0,1,2, or 3, false otherwise.321 */322 static inline bool is_dma8(unsigned channel)323 {324 return (channel < 4);325 306 } 326 307 … … 339 320 * 340 321 * @return Error code. 341 */ 342 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, 343 325 uint8_t mode) 344 326 { 345 if (!is_dma8(channel) && !is_dma16(channel))346 return ENOENT;347 348 327 if ((channel == 0) || (channel == 4)) 349 328 return ENOTSUP; 329 330 if (channel > 7) 331 return ENOENT; 350 332 351 333 /* DMA is limited to 24bit addresses. */ … … 354 336 355 337 /* 8 bit channels use only 4 bits from the page register. */ 356 if (is_dma8(channel) && (pa >= (1 << 20))) 357 return EINVAL; 358 359 /* Buffers cannot cross 64K page boundaries */ 360 if ((pa & 0xffff0000) != ((pa + size - 1) & 0xffff0000)) 338 if ((channel > 0) && (channel < 4) && (pa >= (1 << 20))) 361 339 return EINVAL; 362 340 … … 374 352 ddf_msg(LVL_DEBUG, "Unspoiled address %#" PRIx32 " (size %" PRIu16 ")", 375 353 pa, size); 376 if ( is_dma16(channel)) {354 if (channel > 4) { 377 355 /* Size must be aligned to 16 bits */ 378 356 if ((size & 1) != 0) { … … 380 358 return EINVAL; 381 359 } 382 /* Size is in 2byte words */360 383 361 size >>= 1; 362 384 363 /* Address is fun: lower 16 bits need to be shifted by 1 */ 385 364 pa = ((pa & 0xffff) >> 1) | (pa & 0xff0000); … … 447 426 } 448 427 449 /** Query remaining buffer size.450 *451 * @param channel DMA Channel 1, 2, 3 for 8 bit transfers,452 * 5, 6, 7 for 16 bit.453 * @param size Place to store number of bytes pending in the assigned buffer.454 *455 * @return Error code.456 */457 int dma_channel_remain(unsigned channel, size_t *size)458 {459 assert(size);460 if (!is_dma8(channel) && !is_dma16(channel))461 return ENOENT;462 463 if ((channel == 0) || (channel == 4))464 return ENOTSUP;465 466 fibril_mutex_lock(&guard);467 if (!controller_8237.initialized) {468 fibril_mutex_unlock(&guard);469 return EIO;470 }471 472 const dma_channel_t dma_channel = controller_8237.channels[channel];473 /* Get size - reset flip-flop */474 pio_write_8(dma_channel.flip_flop_address, 0);475 476 /* Low byte */477 const uint8_t value_low = pio_read_8(dma_channel.size_reg_address);478 ddf_msg(LVL_DEBUG2, "Read size low byte: %p:%x.",479 dma_channel.size_reg_address, value_low);480 481 /* High byte */482 const uint8_t value_high = pio_read_8(dma_channel.size_reg_address);483 ddf_msg(LVL_DEBUG2, "Read size high byte: %p:%x.",484 dma_channel.size_reg_address, value_high);485 fibril_mutex_unlock(&guard);486 487 uint16_t remain = (value_high << 8 | value_low) ;488 /* 16 bit DMA size is in words,489 * the upper bits are bogus for 16bit transfers so we need to get490 * rid of them. Using limited type works well.*/491 if (is_dma16(channel))492 remain <<= 1;493 *size = is_dma16(channel) ? remain + 2: remain + 1;494 return EOK;495 }496 428 /** 497 429 * @}
Note:
See TracChangeset
for help on using the changeset viewer.