1 diff -ur linux-2.6.15-orig/drivers/ide/ide.c linux-2.6.15/drivers/ide/ide.c
2 --- linux-2.6.15-orig/drivers/ide/ide.c 2006-01-05 20:42:35.000000000 +0100
3 +++ linux-2.6.15/drivers/ide/ide.c 2006-01-05 20:20:35.000000000 +0100
4 @@ -1214,6 +1214,237 @@
6 EXPORT_SYMBOL(system_bus_clock);
9 +#include <linux/acpi.h>
10 +#define DBG(x...) printk(x)
11 +static int ide_acpi_find_device(struct device *dev, acpi_handle *handle)
16 + if (sscanf(dev->bus_id, "%u.%u", &tmp, &i) != 2)
20 + *handle = acpi_get_child(DEVICE_ACPI_HANDLE(dev->parent), addr);
26 +/* This assumes the ide controller is a PCI device */
27 +static int ide_acpi_find_channel(struct device *dev, acpi_handle *handle)
33 + num = sscanf(dev->bus_id, "ide%x", &channel);
35 + if (num != 1 || !dev->parent)
38 + *handle = acpi_get_child(DEVICE_ACPI_HANDLE(dev->parent), addr);
44 +static struct acpi_bus_type ide_acpi_bus = {
45 + .bus = &ide_bus_type,
46 + .find_device = ide_acpi_find_device,
47 + .find_bridge = ide_acpi_find_channel,
50 +static int __init ide_acpi_init(void)
52 + return register_acpi_bus_type(&ide_acpi_bus);
55 +#define MAX_DEVICES 10
56 +#define GTM_LEN (sizeof(u32) * 5)
57 +static struct acpi_ide_stat {
58 + acpi_handle handle; /* channel device"s handle */
59 + u32 gtm[GTM_LEN/sizeof(u32)]; /* info from _GTM */
60 + struct hd_driveid id_buff[2];
61 + int channel_handled;
62 +} device_state[MAX_DEVICES];
64 +static struct acpi_ide_stat *ide_get_acpi_state(acpi_handle handle)
67 + for (i = 0; i < MAX_DEVICES; i ++)
68 + if (device_state[i].handle == handle)
70 + if (i < MAX_DEVICES)
71 + return &device_state[i];
72 + for (i = 0; i < MAX_DEVICES; i ++)
73 + if (device_state[i].handle == NULL)
75 + if (i >= MAX_DEVICES)
78 + memset(&device_state[i], 0, sizeof(struct acpi_ide_stat));
79 + return &device_state[i];
82 +int acpi_ide_suspend(struct device *dev)
84 + acpi_handle handle, parent_handle;
85 + struct acpi_ide_stat *stat;
87 + struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
88 + union acpi_object *package;
89 + ide_drive_t *drive = dev->driver_data;
92 + handle = DEVICE_ACPI_HANDLE(dev);
94 + DBG("IDE device ACPI handler is NULL\n");
97 + if (ACPI_FAILURE(acpi_get_parent(handle, &parent_handle))) {
98 + printk(KERN_ERR "ACPI get parent handler error\n");
101 + stat = ide_get_acpi_state(parent_handle);
104 + if (stat->channel_handled) {
109 + status = acpi_evaluate_object(parent_handle, "_GTM", NULL, &buffer);
110 + if (ACPI_FAILURE(status)) {
111 + printk(KERN_ERR "Error evaluating _GTM\n");
114 + package = (union acpi_object *) buffer.pointer;
115 + if (package->buffer.length != GTM_LEN) {
116 + printk(KERN_ERR "Buffer length returned by _GTM is wrong\n");
117 + acpi_os_free(buffer.pointer);
120 + memcpy(stat->gtm, package->buffer.pointer, GTM_LEN);
121 + stat->handle = parent_handle;
122 + stat->channel_handled = 1;
123 + acpi_os_free(buffer.pointer);
125 + taskfile_lib_get_identify(drive, &stat->id_buff[drive_id]);
126 + DBG("GTM info %x,%x,%x,%x,%x\n", stat->gtm[0],
127 + stat->gtm[1], stat->gtm[2],
128 + stat->gtm[3], stat->gtm[4]);
132 +static int acpi_ide_stm(struct acpi_ide_stat *stat)
134 + struct acpi_object_list input;
135 + union acpi_object params[3];
136 + acpi_status status;
139 + input.pointer = params;
140 + params[0].type = ACPI_TYPE_BUFFER;
141 + params[0].buffer.length = sizeof(stat->gtm);
142 + params[0].buffer.pointer = (char*)stat->gtm;
144 + params[1].type = ACPI_TYPE_BUFFER;
145 + params[1].buffer.length = sizeof(stat->id_buff[0]);
146 + params[1].buffer.pointer = (char *)&stat->id_buff[0];
148 + params[2].type = ACPI_TYPE_BUFFER;
149 + params[2].buffer.length = sizeof(stat->id_buff[1]);
150 + params[2].buffer.pointer = (char *)&stat->id_buff[1];
152 + status = acpi_evaluate_object(stat->handle, "_STM", &input, NULL);
153 + if (ACPI_FAILURE(status)) {
154 + printk(KERN_ERR "Evaluating _STM error\n");
160 +static int acpi_ide_gtf(acpi_handle handle, ide_drive_t *drive)
162 + struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
165 + unsigned char *data;
166 + union acpi_object *package = NULL;
167 + acpi_status status;
169 + status = acpi_evaluate_object(handle, "_GTF", NULL, &output);
170 + if (ACPI_FAILURE(status)) {
171 + printk(KERN_ERR "evaluate _GTF error\n");
174 + package = (union acpi_object *) output.pointer;
175 + if (package->type != ACPI_TYPE_BUFFER
176 + || (package->buffer.length % 7) != 0) {
177 + acpi_os_free(output.pointer);
178 + printk(KERN_ERR "_GTF returned value is wrong\n");
181 + printk("start GTF\n");
183 + data = package->buffer.pointer;
184 + while (index < package->buffer.length) {
185 + memset(&args, 0, sizeof(ide_task_t));
186 + args.tfRegister[IDE_ERROR_OFFSET] = data[index];
187 + args.tfRegister[IDE_NSECTOR_OFFSET] = data[index + 1];
188 + args.tfRegister[IDE_SECTOR_OFFSET] = data[index + 2];
189 + args.tfRegister[IDE_LCYL_OFFSET] = data[index + 3];
190 + args.tfRegister[IDE_HCYL_OFFSET] = data[index + 4];
191 + args.tfRegister[IDE_SELECT_OFFSET] = data[index + 5];
192 + args.tfRegister[IDE_STATUS_OFFSET] = data[index + 6];
193 + args.command_type = IDE_DRIVE_TASK_NO_DATA;
194 + args.handler = &task_no_data_intr;
195 + printk("data %x,%x,%x,%x,%x,%x,%x\n",
196 + data[index], data[index+1], data[index+2],
197 + data[index+3],data[index+4],data[index+5],
199 + /* submit command request */
200 +// printk("return value %d\n", ide_raw_taskfile(drive, &args, NULL));
203 + acpi_os_free(output.pointer);
207 +int acpi_ide_resume(struct device *dev)
209 + acpi_handle handle, parent_handle;
210 + struct acpi_ide_stat *stat;
211 + ide_drive_t *drive = dev->driver_data;
213 + handle = DEVICE_ACPI_HANDLE(dev);
215 + DBG("IDE device ACPI handler is NULL\n");
218 + if (ACPI_FAILURE(acpi_get_parent(handle, &parent_handle))) {
219 + printk(KERN_ERR "ACPI get parent handler error\n");
222 + stat = ide_get_acpi_state(parent_handle);
223 + if (stat == NULL || stat->handle != parent_handle)
226 + if (stat->channel_handled == 0) {
227 + stat->handle = NULL;
231 + if (acpi_ide_stm(stat))
233 + stat->channel_handled = 0;
235 + return acpi_ide_gtf(handle, drive);
239 static int generic_ide_suspend(struct device *dev, pm_message_t state)
241 ide_drive_t *drive = dev->driver_data;
242 @@ -1230,6 +1461,7 @@
243 rqpm.pm_step = ide_pm_state_start_suspend;
244 rqpm.pm_state = state.event;
246 + acpi_ide_suspend(dev);
247 return ide_do_drive_cmd(drive, &rq, ide_wait);
250 @@ -1239,7 +1471,7 @@
252 struct request_pm_state rqpm;
255 + acpi_ide_resume(dev);
256 memset(&rq, 0, sizeof(rq));
257 memset(&rqpm, 0, sizeof(rqpm));
258 memset(&args, 0, sizeof(args));
259 @@ -1922,6 +2154,7 @@
261 system_bus_speed = ide_system_bus_speed();
264 bus_register(&ide_bus_type);