/[linux-patches]/genpatches-2.6/tags/2.6.15-2/2300_ata-piix-suspend.patch
Gentoo

Contents of /genpatches-2.6/tags/2.6.15-2/2300_ata-piix-suspend.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 259 - (show annotations) (download)
Wed Jan 11 21:46:01 2006 UTC (8 years, 6 months ago) by dsd
File size: 9395 byte(s)
2.6.15-2 release
1 diff -rup linux-2.6.15-rc6-orig/drivers/scsi/ata_piix.c linux-2.6.15-rc6-patched/drivers/scsi/ata_piix.c
2 --- linux-2.6.15-rc6-orig/drivers/scsi/ata_piix.c 2005-12-21 03:04:46.000000000 +0200
3 +++ linux-2.6.15-rc6-patched/drivers/scsi/ata_piix.c 2005-12-21 03:14:22.000000000 +0200
4 @@ -125,6 +125,8 @@ static struct pci_driver piix_pci_driver
5 .id_table = piix_pci_tbl,
6 .probe = piix_init_one,
7 .remove = ata_pci_remove_one,
8 + .suspend = ata_pci_device_suspend,
9 + .resume = ata_pci_device_resume,
10 };
11
12 static struct scsi_host_template piix_sht = {
13 @@ -145,6 +147,8 @@ static struct scsi_host_template piix_sh
14 .slave_configure = ata_scsi_slave_config,
15 .bios_param = ata_std_bios_param,
16 .ordered_flush = 1,
17 + .suspend = ata_scsi_device_suspend,
18 + .resume = ata_scsi_device_resume,
19 };
20
21 static const struct ata_port_operations piix_pata_ops = {
22 diff -rup linux-2.6.15-rc6-orig/drivers/scsi/libata-core.c linux-2.6.15-rc6-patched/drivers/scsi/libata-core.c
23 --- linux-2.6.15-rc6-orig/drivers/scsi/libata-core.c 2005-12-21 03:04:47.000000000 +0200
24 +++ linux-2.6.15-rc6-patched/drivers/scsi/libata-core.c 2005-12-21 03:14:22.000000000 +0200
25 @@ -4099,6 +4099,104 @@ err_out:
26 }
27
28
29 +/*
30 + * Execute a 'simple' command, that only consists of the opcode 'cmd' itself,
31 + * without filling any other registers
32 + */
33 +static int ata_do_simple_cmd(struct ata_port *ap, struct ata_device *dev,
34 + u8 cmd)
35 +{
36 + DECLARE_COMPLETION(wait);
37 + struct ata_queued_cmd *qc;
38 + unsigned long flags;
39 + int rc;
40 +
41 + while ((qc = ata_qc_new_init(ap, dev)) == NULL)
42 + msleep(10);
43 +
44 + qc->tf.command = cmd;
45 + qc->tf.flags |= ATA_TFLAG_DEVICE;
46 + qc->tf.protocol = ATA_PROT_NODATA;
47 +
48 + qc->waiting = &wait;
49 + qc->complete_fn = ata_qc_complete_noop;
50 +
51 + spin_lock_irqsave(&ap->host_set->lock, flags);
52 + rc = ata_qc_issue(qc);
53 + spin_unlock_irqrestore(&ap->host_set->lock, flags);
54 +
55 + if (!rc)
56 + wait_for_completion(&wait);
57 +
58 + return rc;
59 +}
60 +
61 +static int ata_flush_cache(struct ata_port *ap, struct ata_device *dev)
62 +{
63 + u8 cmd;
64 +
65 + if (!ata_try_flush_cache(dev))
66 + return 0;
67 +
68 + if (ata_id_has_flush_ext(dev->id))
69 + cmd = ATA_CMD_FLUSH_EXT;
70 + else
71 + cmd = ATA_CMD_FLUSH;
72 +
73 + return ata_do_simple_cmd(ap, dev, cmd);
74 +}
75 +
76 +static int ata_standby_drive(struct ata_port *ap, struct ata_device *dev)
77 +{
78 + return ata_do_simple_cmd(ap, dev, ATA_CMD_STANDBYNOW1);
79 +}
80 +
81 +static int ata_start_drive(struct ata_port *ap, struct ata_device *dev)
82 +{
83 + return ata_do_simple_cmd(ap, dev, ATA_CMD_IDLEIMMEDIATE);
84 +}
85 +
86 +/**
87 + * ata_device_resume - wakeup a previously suspended devices
88 + *
89 + * Kick the drive back into action, by sending it an idle immediate
90 + * command and making sure its transfer mode matches between drive
91 + * and host.
92 + *
93 + */
94 +int ata_device_resume(struct ata_port *ap, struct ata_device *dev)
95 +{
96 + if (ap->flags & ATA_FLAG_SUSPENDED) {
97 + ap->flags &= ~ATA_FLAG_SUSPENDED;
98 + ata_set_mode(ap);
99 + }
100 + if (!ata_dev_present(dev))
101 + return 0;
102 + if (dev->class == ATA_DEV_ATA)
103 + ata_start_drive(ap, dev);
104 +
105 + return 0;
106 +}
107 +
108 +/**
109 + * ata_device_suspend - prepare a device for suspend
110 + *
111 + * Flush the cache on the drive, if appropriate, then issue a
112 + * standbynow command.
113 + *
114 + */
115 +int ata_device_suspend(struct ata_port *ap, struct ata_device *dev)
116 +{
117 + if (!ata_dev_present(dev))
118 + return 0;
119 + if (dev->class == ATA_DEV_ATA)
120 + ata_flush_cache(ap, dev);
121 +
122 + ata_standby_drive(ap, dev);
123 + ap->flags |= ATA_FLAG_SUSPENDED;
124 + return 0;
125 +}
126 +
127 /**
128 * ata_port_start - Set port up for dma.
129 * @ap: Port to initialize
130 @@ -4860,6 +4958,23 @@ int pci_test_config_bits(struct pci_dev
131
132 return (tmp == bits->val) ? 1 : 0;
133 }
134 +
135 +int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t state)
136 +{
137 + pci_save_state(pdev);
138 + pci_disable_device(pdev);
139 + pci_set_power_state(pdev, PCI_D3hot);
140 + return 0;
141 +}
142 +
143 +int ata_pci_device_resume(struct pci_dev *pdev)
144 +{
145 + pci_set_power_state(pdev, PCI_D0);
146 + pci_restore_state(pdev);
147 + pci_enable_device(pdev);
148 + pci_set_master(pdev);
149 + return 0;
150 +}
151 #endif /* CONFIG_PCI */
152
153
154 @@ -4963,4 +5078,11 @@ EXPORT_SYMBOL_GPL(ata_pci_host_stop);
155 EXPORT_SYMBOL_GPL(ata_pci_init_native_mode);
156 EXPORT_SYMBOL_GPL(ata_pci_init_one);
157 EXPORT_SYMBOL_GPL(ata_pci_remove_one);
158 +EXPORT_SYMBOL_GPL(ata_pci_device_suspend);
159 +EXPORT_SYMBOL_GPL(ata_pci_device_resume);
160 #endif /* CONFIG_PCI */
161 +
162 +EXPORT_SYMBOL_GPL(ata_device_suspend);
163 +EXPORT_SYMBOL_GPL(ata_device_resume);
164 +EXPORT_SYMBOL_GPL(ata_scsi_device_suspend);
165 +EXPORT_SYMBOL_GPL(ata_scsi_device_resume);
166 diff -rup linux-2.6.15-rc6-orig/drivers/scsi/libata-scsi.c linux-2.6.15-rc6-patched/drivers/scsi/libata-scsi.c
167 --- linux-2.6.15-rc6-orig/drivers/scsi/libata-scsi.c 2005-12-21 03:04:47.000000000 +0200
168 +++ linux-2.6.15-rc6-patched/drivers/scsi/libata-scsi.c 2005-12-21 03:14:22.000000000 +0200
169 @@ -396,6 +396,22 @@ void ata_dump_status(unsigned id, struct
170 }
171 }
172
173 +int ata_scsi_device_resume(struct scsi_device *sdev)
174 +{
175 + struct ata_port *ap = (struct ata_port *) &sdev->host->hostdata[0];
176 + struct ata_device *dev = &ap->device[sdev->id];
177 +
178 + return ata_device_resume(ap, dev);
179 +}
180 +
181 +int ata_scsi_device_suspend(struct scsi_device *sdev)
182 +{
183 + struct ata_port *ap = (struct ata_port *) &sdev->host->hostdata[0];
184 + struct ata_device *dev = &ap->device[sdev->id];
185 +
186 + return ata_device_suspend(ap, dev);
187 +}
188 +
189 /**
190 * ata_to_sense_error - convert ATA error to SCSI error
191 * @id: ATA device number
192 diff -rup linux-2.6.15-rc6-orig/drivers/scsi/scsi_sysfs.c linux-2.6.15-rc6-patched/drivers/scsi/scsi_sysfs.c
193 --- linux-2.6.15-rc6-orig/drivers/scsi/scsi_sysfs.c 2005-12-21 03:04:47.000000000 +0200
194 +++ linux-2.6.15-rc6-patched/drivers/scsi/scsi_sysfs.c 2005-12-21 03:14:22.000000000 +0200
195 @@ -263,9 +263,40 @@ static int scsi_bus_match(struct device
196 return (sdp->inq_periph_qual == SCSI_INQ_PQ_CON)? 1: 0;
197 }
198
199 +static int scsi_bus_suspend(struct device * dev, pm_message_t state)
200 +{
201 + struct scsi_device *sdev = to_scsi_device(dev);
202 + struct scsi_host_template *sht = sdev->host->hostt;
203 + int err;
204 +
205 + err = scsi_device_quiesce(sdev);
206 + if (err)
207 + return err;
208 +
209 + if (sht->suspend)
210 + err = sht->suspend(sdev);
211 +
212 + return err;
213 +}
214 +
215 +static int scsi_bus_resume(struct device * dev)
216 +{
217 + struct scsi_device *sdev = to_scsi_device(dev);
218 + struct scsi_host_template *sht = sdev->host->hostt;
219 + int err = 0;
220 +
221 + if (sht->resume)
222 + err = sht->resume(sdev);
223 +
224 + scsi_device_resume(sdev);
225 + return err;
226 +}
227 +
228 struct bus_type scsi_bus_type = {
229 - .name = "scsi",
230 - .match = scsi_bus_match,
231 + .name = "scsi",
232 + .match = scsi_bus_match,
233 + .suspend = scsi_bus_suspend,
234 + .resume = scsi_bus_resume,
235 };
236
237 int scsi_sysfs_register(void)
238 diff -rup linux-2.6.15-rc6-orig/include/linux/ata.h linux-2.6.15-rc6-patched/include/linux/ata.h
239 --- linux-2.6.15-rc6-orig/include/linux/ata.h 2005-12-21 03:04:48.000000000 +0200
240 +++ linux-2.6.15-rc6-patched/include/linux/ata.h 2005-12-21 03:14:22.000000000 +0200
241 @@ -141,6 +141,8 @@ enum {
242 ATA_CMD_PACKET = 0xA0,
243 ATA_CMD_VERIFY = 0x40,
244 ATA_CMD_VERIFY_EXT = 0x42,
245 + ATA_CMD_STANDBYNOW1 = 0xE0,
246 + ATA_CMD_IDLEIMMEDIATE = 0xE1,
247 ATA_CMD_INIT_DEV_PARAMS = 0x91,
248
249 /* SETFEATURES stuff */
250 diff -rup linux-2.6.15-rc6-orig/include/linux/libata.h linux-2.6.15-rc6-patched/include/linux/libata.h
251 --- linux-2.6.15-rc6-orig/include/linux/libata.h 2005-12-21 03:04:48.000000000 +0200
252 +++ linux-2.6.15-rc6-patched/include/linux/libata.h 2005-12-21 03:15:32.000000000 +0200
253 @@ -123,6 +123,7 @@ enum {
254 * proper HSM is in place. */
255 ATA_FLAG_DEBUGMSG = (1 << 10),
256 ATA_FLAG_NO_ATAPI = (1 << 11), /* No ATAPI support */
257 + ATA_FLAG_SUSPENDED = (1 << 12), /* port is suspended */
258
259 ATA_QCFLAG_ACTIVE = (1 << 1), /* cmd not yet ack'd to scsi lyer */
260 ATA_QCFLAG_SG = (1 << 3), /* have s/g table? */
261 @@ -436,6 +437,8 @@ extern void ata_std_ports(struct ata_iop
262 extern int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
263 unsigned int n_ports);
264 extern void ata_pci_remove_one (struct pci_dev *pdev);
265 +extern int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t state);
266 +extern int ata_pci_device_resume(struct pci_dev *pdev);
267 #endif /* CONFIG_PCI */
268 extern int ata_device_add(const struct ata_probe_ent *ent);
269 extern void ata_host_set_remove(struct ata_host_set *host_set);
270 @@ -445,6 +448,10 @@ extern int ata_scsi_queuecmd(struct scsi
271 extern int ata_scsi_error(struct Scsi_Host *host);
272 extern int ata_scsi_release(struct Scsi_Host *host);
273 extern unsigned int ata_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc);
274 +extern int ata_scsi_device_resume(struct scsi_device *);
275 +extern int ata_scsi_device_suspend(struct scsi_device *);
276 +extern int ata_device_resume(struct ata_port *, struct ata_device *);
277 +extern int ata_device_suspend(struct ata_port *, struct ata_device *);
278 extern int ata_ratelimit(void);
279
280 /*
281 diff -rup linux-2.6.15-rc6-orig/include/scsi/scsi_host.h linux-2.6.15-rc6-patched/include/scsi/scsi_host.h
282 --- linux-2.6.15-rc6-orig/include/scsi/scsi_host.h 2005-12-21 03:04:48.000000000 +0200
283 +++ linux-2.6.15-rc6-patched/include/scsi/scsi_host.h 2005-12-21 03:14:22.000000000 +0200
284 @@ -296,6 +296,12 @@ struct scsi_host_template {
285 int (*proc_info)(struct Scsi_Host *, char *, char **, off_t, int, int);
286
287 /*
288 + * suspend support
289 + */
290 + int (*suspend)(struct scsi_device *);
291 + int (*resume)(struct scsi_device *);
292 +
293 + /*
294 * Name of proc directory
295 */
296 char *proc_name;

  ViewVC Help
Powered by ViewVC 1.1.20