Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.32-rc8 606 lines 17 kB view raw
1/* 2 * drivers/input/tablet/wacom_sys.c 3 * 4 * USB Wacom Graphire and Wacom Intuos tablet support - system specific code 5 */ 6 7/* 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 */ 13 14#include "wacom.h" 15#include "wacom_wac.h" 16 17/* defines to get HID report descriptor */ 18#define HID_DEVICET_HID (USB_TYPE_CLASS | 0x01) 19#define HID_DEVICET_REPORT (USB_TYPE_CLASS | 0x02) 20#define HID_USAGE_UNDEFINED 0x00 21#define HID_USAGE_PAGE 0x05 22#define HID_USAGE_PAGE_DIGITIZER 0x0d 23#define HID_USAGE_PAGE_DESKTOP 0x01 24#define HID_USAGE 0x09 25#define HID_USAGE_X 0x30 26#define HID_USAGE_Y 0x31 27#define HID_USAGE_X_TILT 0x3d 28#define HID_USAGE_Y_TILT 0x3e 29#define HID_USAGE_FINGER 0x22 30#define HID_USAGE_STYLUS 0x20 31#define HID_COLLECTION 0xc0 32 33enum { 34 WCM_UNDEFINED = 0, 35 WCM_DESKTOP, 36 WCM_DIGITIZER, 37}; 38 39struct hid_descriptor { 40 struct usb_descriptor_header header; 41 __le16 bcdHID; 42 u8 bCountryCode; 43 u8 bNumDescriptors; 44 u8 bDescriptorType; 45 __le16 wDescriptorLength; 46} __attribute__ ((packed)); 47 48/* defines to get/set USB message */ 49#define USB_REQ_GET_REPORT 0x01 50#define USB_REQ_SET_REPORT 0x09 51#define WAC_HID_FEATURE_REPORT 0x03 52 53static int usb_get_report(struct usb_interface *intf, unsigned char type, 54 unsigned char id, void *buf, int size) 55{ 56 return usb_control_msg(interface_to_usbdev(intf), 57 usb_rcvctrlpipe(interface_to_usbdev(intf), 0), 58 USB_REQ_GET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, 59 (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber, 60 buf, size, 100); 61} 62 63static int usb_set_report(struct usb_interface *intf, unsigned char type, 64 unsigned char id, void *buf, int size) 65{ 66 return usb_control_msg(interface_to_usbdev(intf), 67 usb_sndctrlpipe(interface_to_usbdev(intf), 0), 68 USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, 69 (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber, 70 buf, size, 1000); 71} 72 73static struct input_dev * get_input_dev(struct wacom_combo *wcombo) 74{ 75 return wcombo->wacom->dev; 76} 77 78static void wacom_sys_irq(struct urb *urb) 79{ 80 struct wacom *wacom = urb->context; 81 struct wacom_combo wcombo; 82 int retval; 83 84 switch (urb->status) { 85 case 0: 86 /* success */ 87 break; 88 case -ECONNRESET: 89 case -ENOENT: 90 case -ESHUTDOWN: 91 /* this urb is terminated, clean up */ 92 dbg("%s - urb shutting down with status: %d", __func__, urb->status); 93 return; 94 default: 95 dbg("%s - nonzero urb status received: %d", __func__, urb->status); 96 goto exit; 97 } 98 99 wcombo.wacom = wacom; 100 wcombo.urb = urb; 101 102 if (wacom_wac_irq(wacom->wacom_wac, (void *)&wcombo)) 103 input_sync(get_input_dev(&wcombo)); 104 105 exit: 106 usb_mark_last_busy(wacom->usbdev); 107 retval = usb_submit_urb (urb, GFP_ATOMIC); 108 if (retval) 109 err ("%s - usb_submit_urb failed with result %d", 110 __func__, retval); 111} 112 113void wacom_report_key(void *wcombo, unsigned int key_type, int key_data) 114{ 115 input_report_key(get_input_dev((struct wacom_combo *)wcombo), key_type, key_data); 116} 117 118void wacom_report_abs(void *wcombo, unsigned int abs_type, int abs_data) 119{ 120 input_report_abs(get_input_dev((struct wacom_combo *)wcombo), abs_type, abs_data); 121} 122 123void wacom_report_rel(void *wcombo, unsigned int rel_type, int rel_data) 124{ 125 input_report_rel(get_input_dev((struct wacom_combo *)wcombo), rel_type, rel_data); 126} 127 128void wacom_input_event(void *wcombo, unsigned int type, unsigned int code, int value) 129{ 130 input_event(get_input_dev((struct wacom_combo *)wcombo), type, code, value); 131} 132 133__u16 wacom_be16_to_cpu(unsigned char *data) 134{ 135 __u16 value; 136 value = be16_to_cpu(*(__be16 *) data); 137 return value; 138} 139 140__u16 wacom_le16_to_cpu(unsigned char *data) 141{ 142 __u16 value; 143 value = le16_to_cpu(*(__le16 *) data); 144 return value; 145} 146 147void wacom_input_sync(void *wcombo) 148{ 149 input_sync(get_input_dev((struct wacom_combo *)wcombo)); 150} 151 152static int wacom_open(struct input_dev *dev) 153{ 154 struct wacom *wacom = input_get_drvdata(dev); 155 156 mutex_lock(&wacom->lock); 157 158 wacom->irq->dev = wacom->usbdev; 159 160 if (usb_autopm_get_interface(wacom->intf) < 0) { 161 mutex_unlock(&wacom->lock); 162 return -EIO; 163 } 164 165 if (usb_submit_urb(wacom->irq, GFP_KERNEL)) { 166 usb_autopm_put_interface(wacom->intf); 167 mutex_unlock(&wacom->lock); 168 return -EIO; 169 } 170 171 wacom->open = 1; 172 wacom->intf->needs_remote_wakeup = 1; 173 174 mutex_unlock(&wacom->lock); 175 return 0; 176} 177 178static void wacom_close(struct input_dev *dev) 179{ 180 struct wacom *wacom = input_get_drvdata(dev); 181 182 mutex_lock(&wacom->lock); 183 usb_kill_urb(wacom->irq); 184 wacom->open = 0; 185 wacom->intf->needs_remote_wakeup = 0; 186 mutex_unlock(&wacom->lock); 187} 188 189void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac) 190{ 191 input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_1) | 192 BIT_MASK(BTN_5); 193 input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); 194} 195 196void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac) 197{ 198 input_dev->evbit[0] |= BIT_MASK(EV_MSC); 199 input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL); 200 input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_FINGER); 201 input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_0) | 202 BIT_MASK(BTN_4); 203} 204 205void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac) 206{ 207 input_dev->evbit[0] |= BIT_MASK(EV_REL); 208 input_dev->relbit[0] |= BIT_MASK(REL_WHEEL); 209 input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_LEFT) | 210 BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE); 211 input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) | 212 BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_STYLUS2); 213 input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0); 214} 215 216void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac) 217{ 218 input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_FINGER); 219 input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_0) | 220 BIT_MASK(BTN_1) | BIT_MASK(BTN_2) | BIT_MASK(BTN_3); 221 input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0); 222 input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); 223} 224 225void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac) 226{ 227 input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_4) | 228 BIT_MASK(BTN_5) | BIT_MASK(BTN_6) | BIT_MASK(BTN_7); 229 input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0); 230} 231 232void input_dev_i4s(struct input_dev *input_dev, struct wacom_wac *wacom_wac) 233{ 234 input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_FINGER); 235 input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_0) | BIT_MASK(BTN_1) | BIT_MASK(BTN_2) | BIT_MASK(BTN_3); 236 input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_4) | BIT_MASK(BTN_5) | BIT_MASK(BTN_6); 237 input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); 238} 239 240void input_dev_i4(struct input_dev *input_dev, struct wacom_wac *wacom_wac) 241{ 242 input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_7) | BIT_MASK(BTN_8); 243} 244 245void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac) 246{ 247 input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_8) | BIT_MASK(BTN_9); 248} 249 250void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac) 251{ 252 input_dev->evbit[0] |= BIT_MASK(EV_MSC) | BIT_MASK(EV_REL); 253 input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL); 254 input_dev->relbit[0] |= BIT_MASK(REL_WHEEL); 255 input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_LEFT) | 256 BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE) | 257 BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA); 258 input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) | 259 BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_TOOL_BRUSH) | 260 BIT_MASK(BTN_TOOL_PENCIL) | BIT_MASK(BTN_TOOL_AIRBRUSH) | 261 BIT_MASK(BTN_TOOL_LENS) | BIT_MASK(BTN_STYLUS2); 262 input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0); 263 input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0); 264 input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0); 265 input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0); 266 input_set_abs_params(input_dev, ABS_RZ, -900, 899, 0, 0); 267 input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0); 268} 269 270void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac) 271{ 272 input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_STYLUS2); 273} 274 275void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac) 276{ 277 input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER); 278} 279 280static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc, 281 struct wacom_wac *wacom_wac) 282{ 283 struct usb_device *dev = interface_to_usbdev(intf); 284 struct wacom_features *features = wacom_wac->features; 285 char limit = 0, result = 0; 286 int i = 0, usage = WCM_UNDEFINED, finger = 0, pen = 0; 287 unsigned char *report; 288 289 report = kzalloc(hid_desc->wDescriptorLength, GFP_KERNEL); 290 if (!report) 291 return -ENOMEM; 292 293 /* retrive report descriptors */ 294 do { 295 result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 296 USB_REQ_GET_DESCRIPTOR, 297 USB_RECIP_INTERFACE | USB_DIR_IN, 298 HID_DEVICET_REPORT << 8, 299 intf->altsetting[0].desc.bInterfaceNumber, /* interface */ 300 report, 301 hid_desc->wDescriptorLength, 302 5000); /* 5 secs */ 303 } while (result < 0 && limit++ < 5); 304 305 /* No need to parse the Descriptor. It isn't an error though */ 306 if (result < 0) 307 goto out; 308 309 for (i = 0; i < hid_desc->wDescriptorLength; i++) { 310 311 switch (report[i]) { 312 case HID_USAGE_PAGE: 313 switch (report[i + 1]) { 314 case HID_USAGE_PAGE_DIGITIZER: 315 usage = WCM_DIGITIZER; 316 i++; 317 break; 318 319 case HID_USAGE_PAGE_DESKTOP: 320 usage = WCM_DESKTOP; 321 i++; 322 break; 323 } 324 break; 325 326 case HID_USAGE: 327 switch (report[i + 1]) { 328 case HID_USAGE_X: 329 if (usage == WCM_DESKTOP) { 330 if (finger) { 331 features->touch_x_max = 332 features->touch_y_max = 333 wacom_le16_to_cpu(&report[i + 3]); 334 features->x_max = 335 wacom_le16_to_cpu(&report[i + 6]); 336 i += 7; 337 } else if (pen) { 338 features->x_max = 339 wacom_le16_to_cpu(&report[i + 3]); 340 i += 4; 341 } 342 } else if (usage == WCM_DIGITIZER) { 343 /* max pressure isn't reported 344 features->pressure_max = (unsigned short) 345 (report[i+4] << 8 | report[i + 3]); 346 */ 347 features->pressure_max = 255; 348 i += 4; 349 } 350 break; 351 352 case HID_USAGE_Y: 353 if (usage == WCM_DESKTOP) 354 features->y_max = 355 wacom_le16_to_cpu(&report[i + 3]); 356 i += 4; 357 break; 358 359 case HID_USAGE_FINGER: 360 finger = 1; 361 i++; 362 break; 363 364 case HID_USAGE_STYLUS: 365 pen = 1; 366 i++; 367 break; 368 369 case HID_USAGE_UNDEFINED: 370 if (usage == WCM_DESKTOP && finger) /* capacity */ 371 features->pressure_max = 372 wacom_le16_to_cpu(&report[i + 3]); 373 i += 4; 374 break; 375 } 376 break; 377 378 case HID_COLLECTION: 379 /* reset UsagePage ans Finger */ 380 finger = usage = 0; 381 break; 382 } 383 } 384 385 out: 386 result = 0; 387 kfree(report); 388 return result; 389} 390 391static int wacom_query_tablet_data(struct usb_interface *intf) 392{ 393 unsigned char *rep_data; 394 int limit = 0; 395 int error; 396 397 rep_data = kmalloc(2, GFP_KERNEL); 398 if (!rep_data) 399 return -ENOMEM; 400 401 do { 402 rep_data[0] = 2; 403 rep_data[1] = 2; 404 error = usb_set_report(intf, WAC_HID_FEATURE_REPORT, 405 2, rep_data, 2); 406 if (error >= 0) 407 error = usb_get_report(intf, 408 WAC_HID_FEATURE_REPORT, 2, 409 rep_data, 2); 410 } while ((error < 0 || rep_data[1] != 2) && limit++ < 5); 411 412 kfree(rep_data); 413 414 return error < 0 ? error : 0; 415} 416 417static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) 418{ 419 struct usb_device *dev = interface_to_usbdev(intf); 420 struct usb_host_interface *interface = intf->cur_altsetting; 421 struct usb_endpoint_descriptor *endpoint; 422 struct wacom *wacom; 423 struct wacom_wac *wacom_wac; 424 struct wacom_features *features; 425 struct input_dev *input_dev; 426 int error = -ENOMEM; 427 struct hid_descriptor *hid_desc; 428 429 wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); 430 wacom_wac = kzalloc(sizeof(struct wacom_wac), GFP_KERNEL); 431 input_dev = input_allocate_device(); 432 if (!wacom || !input_dev || !wacom_wac) 433 goto fail1; 434 435 wacom_wac->data = usb_buffer_alloc(dev, 10, GFP_KERNEL, &wacom->data_dma); 436 if (!wacom_wac->data) 437 goto fail1; 438 439 wacom->irq = usb_alloc_urb(0, GFP_KERNEL); 440 if (!wacom->irq) 441 goto fail2; 442 443 wacom->usbdev = dev; 444 wacom->dev = input_dev; 445 wacom->intf = intf; 446 mutex_init(&wacom->lock); 447 usb_make_path(dev, wacom->phys, sizeof(wacom->phys)); 448 strlcat(wacom->phys, "/input0", sizeof(wacom->phys)); 449 450 wacom_wac->features = features = get_wacom_feature(id); 451 BUG_ON(features->pktlen > 10); 452 453 input_dev->name = wacom_wac->features->name; 454 wacom->wacom_wac = wacom_wac; 455 usb_to_input_id(dev, &input_dev->id); 456 457 input_dev->dev.parent = &intf->dev; 458 459 input_set_drvdata(input_dev, wacom); 460 461 input_dev->open = wacom_open; 462 input_dev->close = wacom_close; 463 464 endpoint = &intf->cur_altsetting->endpoint[0].desc; 465 466 /* Initialize touch_x_max and touch_y_max in case it is not defined */ 467 if (wacom_wac->features->type == TABLETPC) { 468 features->touch_x_max = 1023; 469 features->touch_y_max = 1023; 470 } else { 471 features->touch_x_max = 0; 472 features->touch_y_max = 0; 473 } 474 475 /* TabletPC need to retrieve the physical and logical maximum from report descriptor */ 476 if (wacom_wac->features->type == TABLETPC) { 477 if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) { 478 if (usb_get_extra_descriptor(&interface->endpoint[0], 479 HID_DEVICET_REPORT, &hid_desc)) { 480 printk("wacom: can not retrive extra class descriptor\n"); 481 goto fail2; 482 } 483 } 484 error = wacom_parse_hid(intf, hid_desc, wacom_wac); 485 if (error) 486 goto fail2; 487 } 488 489 input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); 490 input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_PEN) | 491 BIT_MASK(BTN_TOUCH) | BIT_MASK(BTN_STYLUS); 492 input_set_abs_params(input_dev, ABS_X, 0, features->x_max, 4, 0); 493 input_set_abs_params(input_dev, ABS_Y, 0, features->y_max, 4, 0); 494 input_set_abs_params(input_dev, ABS_PRESSURE, 0, features->pressure_max, 0, 0); 495 if (features->type == TABLETPC) { 496 input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_DOUBLETAP); 497 input_set_abs_params(input_dev, ABS_RX, 0, features->touch_x_max, 4, 0); 498 input_set_abs_params(input_dev, ABS_RY, 0, features->touch_y_max, 4, 0); 499 } 500 input_dev->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC); 501 502 wacom_init_input_dev(input_dev, wacom_wac); 503 504 usb_fill_int_urb(wacom->irq, dev, 505 usb_rcvintpipe(dev, endpoint->bEndpointAddress), 506 wacom_wac->data, wacom_wac->features->pktlen, 507 wacom_sys_irq, wacom, endpoint->bInterval); 508 wacom->irq->transfer_dma = wacom->data_dma; 509 wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; 510 511 error = input_register_device(wacom->dev); 512 if (error) 513 goto fail3; 514 515 /* 516 * Ask the tablet to report tablet data if it is not a Tablet PC. 517 * Note that if query fails it is not a hard failure. 518 */ 519 if (wacom_wac->features->type != TABLETPC) 520 wacom_query_tablet_data(intf); 521 522 usb_set_intfdata(intf, wacom); 523 return 0; 524 525 fail3: usb_free_urb(wacom->irq); 526 fail2: usb_buffer_free(dev, 10, wacom_wac->data, wacom->data_dma); 527 fail1: input_free_device(input_dev); 528 kfree(wacom); 529 kfree(wacom_wac); 530 return error; 531} 532 533static void wacom_disconnect(struct usb_interface *intf) 534{ 535 struct wacom *wacom = usb_get_intfdata(intf); 536 537 usb_set_intfdata(intf, NULL); 538 539 usb_kill_urb(wacom->irq); 540 input_unregister_device(wacom->dev); 541 usb_free_urb(wacom->irq); 542 usb_buffer_free(interface_to_usbdev(intf), 10, 543 wacom->wacom_wac->data, wacom->data_dma); 544 kfree(wacom->wacom_wac); 545 kfree(wacom); 546} 547 548static int wacom_suspend(struct usb_interface *intf, pm_message_t message) 549{ 550 struct wacom *wacom = usb_get_intfdata(intf); 551 552 mutex_lock(&wacom->lock); 553 usb_kill_urb(wacom->irq); 554 mutex_unlock(&wacom->lock); 555 556 return 0; 557} 558 559static int wacom_resume(struct usb_interface *intf) 560{ 561 struct wacom *wacom = usb_get_intfdata(intf); 562 int rv; 563 564 mutex_lock(&wacom->lock); 565 if (wacom->open) 566 rv = usb_submit_urb(wacom->irq, GFP_NOIO); 567 else 568 rv = 0; 569 mutex_unlock(&wacom->lock); 570 571 return rv; 572} 573 574static int wacom_reset_resume(struct usb_interface *intf) 575{ 576 return wacom_resume(intf); 577} 578 579static struct usb_driver wacom_driver = { 580 .name = "wacom", 581 .probe = wacom_probe, 582 .disconnect = wacom_disconnect, 583 .suspend = wacom_suspend, 584 .resume = wacom_resume, 585 .reset_resume = wacom_reset_resume, 586 .supports_autosuspend = 1, 587}; 588 589static int __init wacom_init(void) 590{ 591 int result; 592 wacom_driver.id_table = get_device_table(); 593 result = usb_register(&wacom_driver); 594 if (result == 0) 595 printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" 596 DRIVER_DESC "\n"); 597 return result; 598} 599 600static void __exit wacom_exit(void) 601{ 602 usb_deregister(&wacom_driver); 603} 604 605module_init(wacom_init); 606module_exit(wacom_exit);