aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/dma/ioat_dma.c142
-rw-r--r--drivers/dma/ioatdma.h2
2 files changed, 78 insertions, 66 deletions
diff --git a/drivers/dma/ioat_dma.c b/drivers/dma/ioat_dma.c
index c1c2dcc6fc2e..c17ec3276062 100644
--- a/drivers/dma/ioat_dma.c
+++ b/drivers/dma/ioat_dma.c
@@ -173,10 +173,47 @@ static void ioat_set_dest(dma_addr_t addr,
173 tx_to_ioat_desc(tx)->dst = addr; 173 tx_to_ioat_desc(tx)->dst = addr;
174} 174}
175 175
176/**
177 * ioat_dma_memcpy_issue_pending - push potentially unrecognized appended
178 * descriptors to hw
179 * @chan: DMA channel handle
180 */
176static inline void __ioat1_dma_memcpy_issue_pending( 181static inline void __ioat1_dma_memcpy_issue_pending(
177 struct ioat_dma_chan *ioat_chan); 182 struct ioat_dma_chan *ioat_chan)
183{
184 ioat_chan->pending = 0;
185 writeb(IOAT_CHANCMD_APPEND, ioat_chan->reg_base + IOAT1_CHANCMD_OFFSET);
186}
187
188static void ioat1_dma_memcpy_issue_pending(struct dma_chan *chan)
189{
190 struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
191
192 if (ioat_chan->pending != 0) {
193 spin_lock_bh(&ioat_chan->desc_lock);
194 __ioat1_dma_memcpy_issue_pending(ioat_chan);
195 spin_unlock_bh(&ioat_chan->desc_lock);
196 }
197}
198
178static inline void __ioat2_dma_memcpy_issue_pending( 199static inline void __ioat2_dma_memcpy_issue_pending(
179 struct ioat_dma_chan *ioat_chan); 200 struct ioat_dma_chan *ioat_chan)
201{
202 ioat_chan->pending = 0;
203 writew(ioat_chan->dmacount,
204 ioat_chan->reg_base + IOAT_CHAN_DMACOUNT_OFFSET);
205}
206
207static void ioat2_dma_memcpy_issue_pending(struct dma_chan *chan)
208{
209 struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
210
211 if (ioat_chan->pending != 0) {
212 spin_lock_bh(&ioat_chan->desc_lock);
213 __ioat2_dma_memcpy_issue_pending(ioat_chan);
214 spin_unlock_bh(&ioat_chan->desc_lock);
215 }
216}
180 217
181static dma_cookie_t ioat1_tx_submit(struct dma_async_tx_descriptor *tx) 218static dma_cookie_t ioat1_tx_submit(struct dma_async_tx_descriptor *tx)
182{ 219{
@@ -203,7 +240,7 @@ static dma_cookie_t ioat1_tx_submit(struct dma_async_tx_descriptor *tx)
203 prev = to_ioat_desc(ioat_chan->used_desc.prev); 240 prev = to_ioat_desc(ioat_chan->used_desc.prev);
204 prefetch(prev->hw); 241 prefetch(prev->hw);
205 do { 242 do {
206 copy = min((u32) len, ioat_chan->xfercap); 243 copy = min_t(size_t, len, ioat_chan->xfercap);
207 244
208 new->async_tx.ack = 1; 245 new->async_tx.ack = 1;
209 246
@@ -291,10 +328,12 @@ static dma_cookie_t ioat2_tx_submit(struct dma_async_tx_descriptor *tx)
291 orig_ack = first->async_tx.ack; 328 orig_ack = first->async_tx.ack;
292 new = first; 329 new = first;
293 330
294 /* ioat_chan->desc_lock is still in force in version 2 path */ 331 /*
295 332 * ioat_chan->desc_lock is still in force in version 2 path
333 * it gets unlocked at end of this function
334 */
296 do { 335 do {
297 copy = min((u32) len, ioat_chan->xfercap); 336 copy = min_t(size_t, len, ioat_chan->xfercap);
298 337
299 new->async_tx.ack = 1; 338 new->async_tx.ack = 1;
300 339
@@ -432,7 +471,7 @@ static void ioat2_dma_massage_chan_desc(struct ioat_dma_chan *ioat_chan)
432static int ioat_dma_alloc_chan_resources(struct dma_chan *chan) 471static int ioat_dma_alloc_chan_resources(struct dma_chan *chan)
433{ 472{
434 struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan); 473 struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
435 struct ioat_desc_sw *desc = NULL; 474 struct ioat_desc_sw *desc;
436 u16 chanctrl; 475 u16 chanctrl;
437 u32 chanerr; 476 u32 chanerr;
438 int i; 477 int i;
@@ -575,7 +614,7 @@ static void ioat_dma_free_chan_resources(struct dma_chan *chan)
575static struct ioat_desc_sw * 614static struct ioat_desc_sw *
576ioat1_dma_get_next_descriptor(struct ioat_dma_chan *ioat_chan) 615ioat1_dma_get_next_descriptor(struct ioat_dma_chan *ioat_chan)
577{ 616{
578 struct ioat_desc_sw *new = NULL; 617 struct ioat_desc_sw *new;
579 618
580 if (!list_empty(&ioat_chan->free_desc)) { 619 if (!list_empty(&ioat_chan->free_desc)) {
581 new = to_ioat_desc(ioat_chan->free_desc.next); 620 new = to_ioat_desc(ioat_chan->free_desc.next);
@@ -583,9 +622,11 @@ ioat1_dma_get_next_descriptor(struct ioat_dma_chan *ioat_chan)
583 } else { 622 } else {
584 /* try to get another desc */ 623 /* try to get another desc */
585 new = ioat_dma_alloc_descriptor(ioat_chan, GFP_ATOMIC); 624 new = ioat_dma_alloc_descriptor(ioat_chan, GFP_ATOMIC);
586 /* will this ever happen? */ 625 if (!new) {
587 /* TODO add upper limit on these */ 626 dev_err(&ioat_chan->device->pdev->dev,
588 BUG_ON(!new); 627 "alloc failed\n");
628 return NULL;
629 }
589 } 630 }
590 631
591 prefetch(new->hw); 632 prefetch(new->hw);
@@ -595,7 +636,7 @@ ioat1_dma_get_next_descriptor(struct ioat_dma_chan *ioat_chan)
595static struct ioat_desc_sw * 636static struct ioat_desc_sw *
596ioat2_dma_get_next_descriptor(struct ioat_dma_chan *ioat_chan) 637ioat2_dma_get_next_descriptor(struct ioat_dma_chan *ioat_chan)
597{ 638{
598 struct ioat_desc_sw *new = NULL; 639 struct ioat_desc_sw *new;
599 640
600 /* 641 /*
601 * used.prev points to where to start processing 642 * used.prev points to where to start processing
@@ -609,8 +650,8 @@ ioat2_dma_get_next_descriptor(struct ioat_dma_chan *ioat_chan)
609 if (ioat_chan->used_desc.prev && 650 if (ioat_chan->used_desc.prev &&
610 ioat_chan->used_desc.next == ioat_chan->used_desc.prev->prev) { 651 ioat_chan->used_desc.next == ioat_chan->used_desc.prev->prev) {
611 652
612 struct ioat_desc_sw *desc = NULL; 653 struct ioat_desc_sw *desc;
613 struct ioat_desc_sw *noop_desc = NULL; 654 struct ioat_desc_sw *noop_desc;
614 int i; 655 int i;
615 656
616 /* set up the noop descriptor */ 657 /* set up the noop descriptor */
@@ -624,10 +665,14 @@ ioat2_dma_get_next_descriptor(struct ioat_dma_chan *ioat_chan)
624 ioat_chan->pending++; 665 ioat_chan->pending++;
625 ioat_chan->dmacount++; 666 ioat_chan->dmacount++;
626 667
627 /* get a few more descriptors */ 668 /* try to get a few more descriptors */
628 for (i = 16; i; i--) { 669 for (i = 16; i; i--) {
629 desc = ioat_dma_alloc_descriptor(ioat_chan, GFP_ATOMIC); 670 desc = ioat_dma_alloc_descriptor(ioat_chan, GFP_ATOMIC);
630 BUG_ON(!desc); 671 if (!desc) {
672 dev_err(&ioat_chan->device->pdev->dev,
673 "alloc failed\n");
674 break;
675 }
631 list_add_tail(&desc->node, ioat_chan->used_desc.next); 676 list_add_tail(&desc->node, ioat_chan->used_desc.next);
632 677
633 desc->hw->next 678 desc->hw->next
@@ -677,10 +722,13 @@ static struct dma_async_tx_descriptor *ioat1_dma_prep_memcpy(
677 722
678 spin_lock_bh(&ioat_chan->desc_lock); 723 spin_lock_bh(&ioat_chan->desc_lock);
679 new = ioat_dma_get_next_descriptor(ioat_chan); 724 new = ioat_dma_get_next_descriptor(ioat_chan);
680 new->len = len;
681 spin_unlock_bh(&ioat_chan->desc_lock); 725 spin_unlock_bh(&ioat_chan->desc_lock);
682 726
683 return new ? &new->async_tx : NULL; 727 if (new) {
728 new->len = len;
729 return &new->async_tx;
730 } else
731 return NULL;
684} 732}
685 733
686static struct dma_async_tx_descriptor *ioat2_dma_prep_memcpy( 734static struct dma_async_tx_descriptor *ioat2_dma_prep_memcpy(
@@ -693,53 +741,17 @@ static struct dma_async_tx_descriptor *ioat2_dma_prep_memcpy(
693 741
694 spin_lock_bh(&ioat_chan->desc_lock); 742 spin_lock_bh(&ioat_chan->desc_lock);
695 new = ioat2_dma_get_next_descriptor(ioat_chan); 743 new = ioat2_dma_get_next_descriptor(ioat_chan);
696 new->len = len;
697
698 /* leave ioat_chan->desc_lock set in version 2 path */
699 return new ? &new->async_tx : NULL;
700}
701
702
703/**
704 * ioat_dma_memcpy_issue_pending - push potentially unrecognized appended
705 * descriptors to hw
706 * @chan: DMA channel handle
707 */
708static inline void __ioat1_dma_memcpy_issue_pending(
709 struct ioat_dma_chan *ioat_chan)
710{
711 ioat_chan->pending = 0;
712 writeb(IOAT_CHANCMD_APPEND, ioat_chan->reg_base + IOAT1_CHANCMD_OFFSET);
713}
714
715static void ioat1_dma_memcpy_issue_pending(struct dma_chan *chan)
716{
717 struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
718
719 if (ioat_chan->pending != 0) {
720 spin_lock_bh(&ioat_chan->desc_lock);
721 __ioat1_dma_memcpy_issue_pending(ioat_chan);
722 spin_unlock_bh(&ioat_chan->desc_lock);
723 }
724}
725
726static inline void __ioat2_dma_memcpy_issue_pending(
727 struct ioat_dma_chan *ioat_chan)
728{
729 ioat_chan->pending = 0;
730 writew(ioat_chan->dmacount,
731 ioat_chan->reg_base + IOAT_CHAN_DMACOUNT_OFFSET);
732}
733 744
734static void ioat2_dma_memcpy_issue_pending(struct dma_chan *chan) 745 /*
735{ 746 * leave ioat_chan->desc_lock set in ioat 2 path
736 struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan); 747 * it will get unlocked at end of tx_submit
748 */
737 749
738 if (ioat_chan->pending != 0) { 750 if (new) {
739 spin_lock_bh(&ioat_chan->desc_lock); 751 new->len = len;
740 __ioat2_dma_memcpy_issue_pending(ioat_chan); 752 return &new->async_tx;
741 spin_unlock_bh(&ioat_chan->desc_lock); 753 } else
742 } 754 return NULL;
743} 755}
744 756
745static void ioat_dma_cleanup_tasklet(unsigned long data) 757static void ioat_dma_cleanup_tasklet(unsigned long data)
@@ -1019,7 +1031,7 @@ static void ioat_dma_start_null_desc(struct ioat_dma_chan *ioat_chan)
1019static void ioat_dma_test_callback(void *dma_async_param) 1031static void ioat_dma_test_callback(void *dma_async_param)
1020{ 1032{
1021 printk(KERN_ERR "ioatdma: ioat_dma_test_callback(%p)\n", 1033 printk(KERN_ERR "ioatdma: ioat_dma_test_callback(%p)\n",
1022 dma_async_param); 1034 dma_async_param);
1023} 1035}
1024 1036
1025/** 1037/**
@@ -1032,7 +1044,7 @@ static int ioat_dma_self_test(struct ioatdma_device *device)
1032 u8 *src; 1044 u8 *src;
1033 u8 *dest; 1045 u8 *dest;
1034 struct dma_chan *dma_chan; 1046 struct dma_chan *dma_chan;
1035 struct dma_async_tx_descriptor *tx = NULL; 1047 struct dma_async_tx_descriptor *tx;
1036 dma_addr_t addr; 1048 dma_addr_t addr;
1037 dma_cookie_t cookie; 1049 dma_cookie_t cookie;
1038 int err = 0; 1050 int err = 0;
diff --git a/drivers/dma/ioatdma.h b/drivers/dma/ioatdma.h
index b668234ef654..f2c7fedbf009 100644
--- a/drivers/dma/ioatdma.h
+++ b/drivers/dma/ioatdma.h
@@ -76,7 +76,7 @@ struct ioat_dma_chan {
76 dma_cookie_t completed_cookie; 76 dma_cookie_t completed_cookie;
77 unsigned long last_completion; 77 unsigned long last_completion;
78 78
79 u32 xfercap; /* XFERCAP register value expanded out */ 79 size_t xfercap; /* XFERCAP register value expanded out */
80 80
81 spinlock_t cleanup_lock; 81 spinlock_t cleanup_lock;
82 spinlock_t desc_lock; 82 spinlock_t desc_lock;