aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libata-eh.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/libata-eh.c')
-rw-r--r--drivers/scsi/libata-eh.c103
1 files changed, 103 insertions, 0 deletions
diff --git a/drivers/scsi/libata-eh.c b/drivers/scsi/libata-eh.c
index 037a561809f5..cb4e2b8d32d9 100644
--- a/drivers/scsi/libata-eh.c
+++ b/drivers/scsi/libata-eh.c
@@ -291,6 +291,109 @@ int ata_port_abort(struct ata_port *ap)
291 return nr_aborted; 291 return nr_aborted;
292} 292}
293 293
294/**
295 * __ata_port_freeze - freeze port
296 * @ap: ATA port to freeze
297 *
298 * This function is called when HSM violation or some other
299 * condition disrupts normal operation of the port. Frozen port
300 * is not allowed to perform any operation until the port is
301 * thawed, which usually follows a successful reset.
302 *
303 * ap->ops->freeze() callback can be used for freezing the port
304 * hardware-wise (e.g. mask interrupt and stop DMA engine). If a
305 * port cannot be frozen hardware-wise, the interrupt handler
306 * must ack and clear interrupts unconditionally while the port
307 * is frozen.
308 *
309 * LOCKING:
310 * spin_lock_irqsave(host_set lock)
311 */
312static void __ata_port_freeze(struct ata_port *ap)
313{
314 WARN_ON(!ap->ops->error_handler);
315
316 if (ap->ops->freeze)
317 ap->ops->freeze(ap);
318
319 ap->flags |= ATA_FLAG_FROZEN;
320
321 DPRINTK("ata%u port frozen\n", ap->id);
322}
323
324/**
325 * ata_port_freeze - abort & freeze port
326 * @ap: ATA port to freeze
327 *
328 * Abort and freeze @ap.
329 *
330 * LOCKING:
331 * spin_lock_irqsave(host_set lock)
332 *
333 * RETURNS:
334 * Number of aborted commands.
335 */
336int ata_port_freeze(struct ata_port *ap)
337{
338 int nr_aborted;
339
340 WARN_ON(!ap->ops->error_handler);
341
342 nr_aborted = ata_port_abort(ap);
343 __ata_port_freeze(ap);
344
345 return nr_aborted;
346}
347
348/**
349 * ata_eh_freeze_port - EH helper to freeze port
350 * @ap: ATA port to freeze
351 *
352 * Freeze @ap.
353 *
354 * LOCKING:
355 * None.
356 */
357void ata_eh_freeze_port(struct ata_port *ap)
358{
359 unsigned long flags;
360
361 if (!ap->ops->error_handler)
362 return;
363
364 spin_lock_irqsave(&ap->host_set->lock, flags);
365 __ata_port_freeze(ap);
366 spin_unlock_irqrestore(&ap->host_set->lock, flags);
367}
368
369/**
370 * ata_port_thaw_port - EH helper to thaw port
371 * @ap: ATA port to thaw
372 *
373 * Thaw frozen port @ap.
374 *
375 * LOCKING:
376 * None.
377 */
378void ata_eh_thaw_port(struct ata_port *ap)
379{
380 unsigned long flags;
381
382 if (!ap->ops->error_handler)
383 return;
384
385 spin_lock_irqsave(&ap->host_set->lock, flags);
386
387 ap->flags &= ~ATA_FLAG_FROZEN;
388
389 if (ap->ops->thaw)
390 ap->ops->thaw(ap);
391
392 spin_unlock_irqrestore(&ap->host_set->lock, flags);
393
394 DPRINTK("ata%u port thawed\n", ap->id);
395}
396
294static void ata_eh_scsidone(struct scsi_cmnd *scmd) 397static void ata_eh_scsidone(struct scsi_cmnd *scmd)
295{ 398{
296 /* nada */ 399 /* nada */