999-libata-hacks.patch 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. --- a/drivers/ata/libata-core.c
  2. +++ b/drivers/ata/libata-core.c
  3. @@ -1581,6 +1581,14 @@ unsigned ata_exec_internal_sg(struct ata
  4. return AC_ERR_SYSTEM;
  5. }
  6. + if (ap->ops->acquire_hw && !ap->ops->acquire_hw(ap, 0, 0)) {
  7. + spin_unlock_irqrestore(ap->lock, flags);
  8. + if (!ap->ops->acquire_hw(ap, 1, (2*HZ))) {
  9. + return AC_ERR_TIMEOUT;
  10. + }
  11. + spin_lock_irqsave(ap->lock, flags);
  12. + }
  13. +
  14. /* initialize internal qc */
  15. /* XXX: Tag 0 is used for drivers with legacy EH as some
  16. @@ -4796,6 +4804,9 @@ static struct ata_queued_cmd *ata_qc_new
  17. if (unlikely(ap->pflags & ATA_PFLAG_FROZEN))
  18. return NULL;
  19. + if (ap->ops->qc_new && ap->ops->qc_new(ap))
  20. + return NULL;
  21. +
  22. for (i = 0, tag = ap->last_tag + 1; i < max_queue; i++, tag++) {
  23. if (ap->flags & ATA_FLAG_LOWTAG)
  24. tag = i;
  25. @@ -4868,6 +4879,8 @@ void ata_qc_free(struct ata_queued_cmd *
  26. if (likely(ata_tag_valid(tag))) {
  27. qc->tag = ATA_TAG_POISON;
  28. clear_bit(tag, &ap->qc_allocated);
  29. + if (ap->ops->qc_free)
  30. + ap->ops->qc_free(qc);
  31. }
  32. }
  33. --- a/include/linux/libata.h
  34. +++ b/include/linux/libata.h
  35. @@ -903,6 +903,8 @@ struct ata_port_operations {
  36. void (*qc_prep)(struct ata_queued_cmd *qc);
  37. unsigned int (*qc_issue)(struct ata_queued_cmd *qc);
  38. bool (*qc_fill_rtf)(struct ata_queued_cmd *qc);
  39. + int (*qc_new)(struct ata_port *ap);
  40. + void (*qc_free)(struct ata_queued_cmd *qc);
  41. /*
  42. * Configuration and exception handling
  43. @@ -993,6 +995,9 @@ struct ata_port_operations {
  44. void (*phy_reset)(struct ata_port *ap);
  45. void (*eng_timeout)(struct ata_port *ap);
  46. + int (*acquire_hw)(struct ata_port *ap, int may_sleep,
  47. + int timeout_jiffies);
  48. +
  49. /*
  50. * ->inherits must be the last field and all the preceding
  51. * fields must be pointers.