static status_t device_ioctl(void* dev, uint32 msg, void* buffer, size_t bufferLength) { DeviceInfo& di = *((DeviceInfo*)dev); // TRACE("device_ioctl(); ioctl: %lu, buffer: 0x%08lx, bufLen: %lu\n", msg, // (uint32)buffer, bufferLength); switch (msg) { case B_GET_ACCELERANT_SIGNATURE: strcpy((char*)buffer, ATI_ACCELERANT_NAME); return B_OK; case ATI_DEVICE_NAME: strncpy((char*)buffer, di.name, B_OS_NAME_LENGTH); ((char*)buffer)[B_OS_NAME_LENGTH -1] = '\0'; return B_OK; case ATI_GET_SHARED_DATA: if (bufferLength != sizeof(area_id)) return B_BAD_DATA; *((area_id*)buffer) = di.sharedArea; return B_OK; case ATI_GET_EDID: { if (bufferLength != sizeof(edid1_raw)) return B_BAD_DATA; edid1_raw rawEdid; status_t status = GetEdidFromBIOS(rawEdid); if (status == B_OK) user_memcpy((edid1_raw*)buffer, &rawEdid, sizeof(rawEdid)); return status; } case ATI_SET_VESA_DISPLAY_MODE: if (bufferLength != sizeof(uint16)) return B_BAD_DATA; return SetVesaDisplayMode(*((uint16*)buffer)); case ATI_RUN_INTERRUPTS: if (bufferLength != sizeof(bool)) return B_BAD_DATA; if (*((bool*)buffer)) EnableVBI(); else DisableVBI(); return B_OK; } return B_DEV_INVALID_IOCTL; }
static status_t device_ioctl(void* dev, uint32 msg, void* buf, size_t len) { DeviceInfo& di = *((DeviceInfo*)dev); (void)len; // avoid compiler warning for unused arg // TRACE("device_ioctl(); ioctl: %lu, buf: 0x%08lx, len: %lu\n", msg, (uint32)buf, len); switch (msg) { case B_GET_ACCELERANT_SIGNATURE: strcpy((char*)buf, "s3.accelerant"); return B_OK; case S3_DEVICE_NAME: strncpy((char*)buf, di.name, B_OS_NAME_LENGTH); ((char*)buf)[B_OS_NAME_LENGTH -1] = '\0'; return B_OK; case S3_GET_PRIVATE_DATA: { S3GetPrivateData* gpd = (S3GetPrivateData*)buf; if (gpd->magic == S3_PRIVATE_DATA_MAGIC) { gpd->sharedInfoArea = di.sharedArea; return B_OK; } break; } case S3_GET_EDID: { #ifdef __HAIKU__ S3GetEDID* ged = (S3GetEDID*)buf; if (ged->magic == S3_PRIVATE_DATA_MAGIC) { edid1_raw rawEdid; status_t status = GetEdidFromBIOS(rawEdid); if (status == B_OK) user_memcpy(&ged->rawEdid, &rawEdid, sizeof(rawEdid)); return status; } #else return B_UNSUPPORTED; #endif break; } case S3_GET_PIO: { S3GetSetPIO* gsp = (S3GetSetPIO*)buf; if (gsp->magic == S3_PRIVATE_DATA_MAGIC) { switch (gsp->size) { case 1: gsp->value = gPCI->read_io_8(gsp->offset); break; case 2: gsp->value = gPCI->read_io_16(gsp->offset); break; case 4: gsp->value = gPCI->read_io_32(gsp->offset); break; default: TRACE("device_ioctl() S3_GET_PIO invalid size: %ld\n", gsp->size); return B_ERROR; } return B_OK; } break; } case S3_SET_PIO: { S3GetSetPIO* gsp = (S3GetSetPIO*)buf; if (gsp->magic == S3_PRIVATE_DATA_MAGIC) { switch (gsp->size) { case 1: gPCI->write_io_8(gsp->offset, gsp->value); break; case 2: gPCI->write_io_16(gsp->offset, gsp->value); break; case 4: gPCI->write_io_32(gsp->offset, gsp->value); break; default: TRACE("device_ioctl() S3_SET_PIO invalid size: %ld\n", gsp->size); return B_ERROR; } return B_OK; } break; } case S3_RUN_INTERRUPTS: { S3SetBoolState* ri = (S3SetBoolState*)buf; if (ri->magic == S3_PRIVATE_DATA_MAGIC) { if (ri->bEnable) EnableVBI(); else DisableVBI(); } return B_OK; } } return B_DEV_INVALID_IOCTL; }