Changes in uspace/drv/bus/isa/i8237.c [561c301:3e6a98c5] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/isa/i8237.c
r561c301 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. … … 306 304 307 305 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);326 306 } 327 307 … … 340 320 * 341 321 * @return Error code. 342 */ 343 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, 344 325 uint8_t mode) 345 326 { 346 if (!is_dma8(channel) && !is_dma16(channel))347 return ENOENT;348 349 327 if ((channel == 0) || (channel == 4)) 350 328 return ENOTSUP; 329 330 if (channel > 7) 331 return ENOENT; 351 332 352 333 /* DMA is limited to 24bit addresses. */ … … 355 336 356 337 /* 8 bit channels use only 4 bits from the page register. */ 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)) 338 if ((channel > 0) && (channel < 4) && (pa >= (1 << 20))) 362 339 return EINVAL; 363 340 … … 375 352 ddf_msg(LVL_DEBUG, "Unspoiled address %#" PRIx32 " (size %" PRIu16 ")", 376 353 pa, size); 377 if ( is_dma16(channel)) {354 if (channel > 4) { 378 355 /* Size must be aligned to 16 bits */ 379 356 if ((size & 1) != 0) { … … 381 358 return EINVAL; 382 359 } 383 /* Size is in 2byte words */360 384 361 size >>= 1; 362 385 363 /* Address is fun: lower 16 bits need to be shifted by 1 */ 386 364 pa = ((pa & 0xffff) >> 1) | (pa & 0xff0000); … … 448 426 } 449 427 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 get491 * 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 }497 428 /** 498 429 * @}
Note:
See TracChangeset
for help on using the changeset viewer.