diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_channel.c | 42 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drv.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_gem.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_notifier.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_object.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_state.c | 2 |
6 files changed, 32 insertions, 26 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index a7583a8ddb01..764dd672112a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c | |||
@@ -121,6 +121,7 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, | |||
121 | { | 121 | { |
122 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 122 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
123 | struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; | 123 | struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; |
124 | struct nouveau_fpriv *fpriv = nouveau_fpriv(file_priv); | ||
124 | struct nouveau_channel *chan; | 125 | struct nouveau_channel *chan; |
125 | unsigned long flags; | 126 | unsigned long flags; |
126 | int ret; | 127 | int ret; |
@@ -220,6 +221,11 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, | |||
220 | nouveau_debugfs_channel_init(chan); | 221 | nouveau_debugfs_channel_init(chan); |
221 | 222 | ||
222 | NV_DEBUG(dev, "channel %d initialised\n", chan->id); | 223 | NV_DEBUG(dev, "channel %d initialised\n", chan->id); |
224 | if (fpriv) { | ||
225 | spin_lock(&fpriv->lock); | ||
226 | list_add(&chan->list, &fpriv->channels); | ||
227 | spin_unlock(&fpriv->lock); | ||
228 | } | ||
223 | *chan_ret = chan; | 229 | *chan_ret = chan; |
224 | return 0; | 230 | return 0; |
225 | } | 231 | } |
@@ -236,29 +242,23 @@ nouveau_channel_get_unlocked(struct nouveau_channel *ref) | |||
236 | } | 242 | } |
237 | 243 | ||
238 | struct nouveau_channel * | 244 | struct nouveau_channel * |
239 | nouveau_channel_get(struct drm_device *dev, struct drm_file *file_priv, int id) | 245 | nouveau_channel_get(struct drm_file *file_priv, int id) |
240 | { | 246 | { |
241 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 247 | struct nouveau_fpriv *fpriv = nouveau_fpriv(file_priv); |
242 | struct nouveau_channel *chan; | 248 | struct nouveau_channel *chan; |
243 | unsigned long flags; | ||
244 | 249 | ||
245 | if (unlikely(id < 0 || id >= NOUVEAU_MAX_CHANNEL_NR)) | 250 | spin_lock(&fpriv->lock); |
246 | return ERR_PTR(-EINVAL); | 251 | list_for_each_entry(chan, &fpriv->channels, list) { |
247 | 252 | if (chan->id == id) { | |
248 | spin_lock_irqsave(&dev_priv->channels.lock, flags); | 253 | chan = nouveau_channel_get_unlocked(chan); |
249 | chan = nouveau_channel_get_unlocked(dev_priv->channels.ptr[id]); | 254 | spin_unlock(&fpriv->lock); |
250 | spin_unlock_irqrestore(&dev_priv->channels.lock, flags); | 255 | mutex_lock(&chan->mutex); |
251 | 256 | return chan; | |
252 | if (unlikely(!chan)) | 257 | } |
253 | return ERR_PTR(-EINVAL); | ||
254 | |||
255 | if (unlikely(file_priv && chan->file_priv != file_priv)) { | ||
256 | nouveau_channel_put_unlocked(&chan); | ||
257 | return ERR_PTR(-EINVAL); | ||
258 | } | 258 | } |
259 | spin_unlock(&fpriv->lock); | ||
259 | 260 | ||
260 | mutex_lock(&chan->mutex); | 261 | return ERR_PTR(-EINVAL); |
261 | return chan; | ||
262 | } | 262 | } |
263 | 263 | ||
264 | void | 264 | void |
@@ -383,10 +383,11 @@ nouveau_channel_cleanup(struct drm_device *dev, struct drm_file *file_priv) | |||
383 | 383 | ||
384 | NV_DEBUG(dev, "clearing FIFO enables from file_priv\n"); | 384 | NV_DEBUG(dev, "clearing FIFO enables from file_priv\n"); |
385 | for (i = 0; i < engine->fifo.channels; i++) { | 385 | for (i = 0; i < engine->fifo.channels; i++) { |
386 | chan = nouveau_channel_get(dev, file_priv, i); | 386 | chan = nouveau_channel_get(file_priv, i); |
387 | if (IS_ERR(chan)) | 387 | if (IS_ERR(chan)) |
388 | continue; | 388 | continue; |
389 | 389 | ||
390 | list_del(&chan->list); | ||
390 | atomic_dec(&chan->users); | 391 | atomic_dec(&chan->users); |
391 | nouveau_channel_put(&chan); | 392 | nouveau_channel_put(&chan); |
392 | } | 393 | } |
@@ -459,10 +460,11 @@ nouveau_ioctl_fifo_free(struct drm_device *dev, void *data, | |||
459 | struct drm_nouveau_channel_free *req = data; | 460 | struct drm_nouveau_channel_free *req = data; |
460 | struct nouveau_channel *chan; | 461 | struct nouveau_channel *chan; |
461 | 462 | ||
462 | chan = nouveau_channel_get(dev, file_priv, req->channel); | 463 | chan = nouveau_channel_get(file_priv, req->channel); |
463 | if (IS_ERR(chan)) | 464 | if (IS_ERR(chan)) |
464 | return PTR_ERR(chan); | 465 | return PTR_ERR(chan); |
465 | 466 | ||
467 | list_del(&chan->list); | ||
466 | atomic_dec(&chan->users); | 468 | atomic_dec(&chan->users); |
467 | nouveau_channel_put(&chan); | 469 | nouveau_channel_put(&chan); |
468 | return 0; | 470 | return 0; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index a378a9648198..633f1e6d421f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h | |||
@@ -47,6 +47,7 @@ | |||
47 | 47 | ||
48 | struct nouveau_fpriv { | 48 | struct nouveau_fpriv { |
49 | spinlock_t lock; | 49 | spinlock_t lock; |
50 | struct list_head channels; | ||
50 | }; | 51 | }; |
51 | 52 | ||
52 | static inline struct nouveau_fpriv * | 53 | static inline struct nouveau_fpriv * |
@@ -208,6 +209,7 @@ enum nouveau_channel_mutex_class { | |||
208 | 209 | ||
209 | struct nouveau_channel { | 210 | struct nouveau_channel { |
210 | struct drm_device *dev; | 211 | struct drm_device *dev; |
212 | struct list_head list; | ||
211 | int id; | 213 | int id; |
212 | 214 | ||
213 | /* references to the channel data structure */ | 215 | /* references to the channel data structure */ |
@@ -858,7 +860,7 @@ extern int nouveau_channel_alloc(struct drm_device *dev, | |||
858 | extern struct nouveau_channel * | 860 | extern struct nouveau_channel * |
859 | nouveau_channel_get_unlocked(struct nouveau_channel *); | 861 | nouveau_channel_get_unlocked(struct nouveau_channel *); |
860 | extern struct nouveau_channel * | 862 | extern struct nouveau_channel * |
861 | nouveau_channel_get(struct drm_device *, struct drm_file *, int id); | 863 | nouveau_channel_get(struct drm_file *, int id); |
862 | extern void nouveau_channel_put_unlocked(struct nouveau_channel **); | 864 | extern void nouveau_channel_put_unlocked(struct nouveau_channel **); |
863 | extern void nouveau_channel_put(struct nouveau_channel **); | 865 | extern void nouveau_channel_put(struct nouveau_channel **); |
864 | extern void nouveau_channel_ref(struct nouveau_channel *chan, | 866 | extern void nouveau_channel_ref(struct nouveau_channel *chan, |
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index b52e46018245..2bd8d6da9c3d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c | |||
@@ -139,7 +139,7 @@ nouveau_gem_ioctl_new(struct drm_device *dev, void *data, | |||
139 | } | 139 | } |
140 | 140 | ||
141 | if (req->channel_hint) { | 141 | if (req->channel_hint) { |
142 | chan = nouveau_channel_get(dev, file_priv, req->channel_hint); | 142 | chan = nouveau_channel_get(file_priv, req->channel_hint); |
143 | if (IS_ERR(chan)) | 143 | if (IS_ERR(chan)) |
144 | return PTR_ERR(chan); | 144 | return PTR_ERR(chan); |
145 | } | 145 | } |
@@ -548,7 +548,7 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, | |||
548 | struct nouveau_fence *fence = NULL; | 548 | struct nouveau_fence *fence = NULL; |
549 | int i, j, ret = 0, do_reloc = 0; | 549 | int i, j, ret = 0, do_reloc = 0; |
550 | 550 | ||
551 | chan = nouveau_channel_get(dev, file_priv, req->channel); | 551 | chan = nouveau_channel_get(file_priv, req->channel); |
552 | if (IS_ERR(chan)) | 552 | if (IS_ERR(chan)) |
553 | return PTR_ERR(chan); | 553 | return PTR_ERR(chan); |
554 | 554 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_notifier.c b/drivers/gpu/drm/nouveau/nouveau_notifier.c index 5b39718ae1f8..104b93b9f852 100644 --- a/drivers/gpu/drm/nouveau/nouveau_notifier.c +++ b/drivers/gpu/drm/nouveau/nouveau_notifier.c | |||
@@ -183,7 +183,7 @@ nouveau_ioctl_notifier_alloc(struct drm_device *dev, void *data, | |||
183 | if (unlikely(dev_priv->card_type >= NV_C0)) | 183 | if (unlikely(dev_priv->card_type >= NV_C0)) |
184 | return -EINVAL; | 184 | return -EINVAL; |
185 | 185 | ||
186 | chan = nouveau_channel_get(dev, file_priv, na->channel); | 186 | chan = nouveau_channel_get(file_priv, na->channel); |
187 | if (IS_ERR(chan)) | 187 | if (IS_ERR(chan)) |
188 | return PTR_ERR(chan); | 188 | return PTR_ERR(chan); |
189 | 189 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index 8f97016f5b26..8c9895827875 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c | |||
@@ -909,7 +909,7 @@ int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data, | |||
909 | if (init->handle == ~0) | 909 | if (init->handle == ~0) |
910 | return -EINVAL; | 910 | return -EINVAL; |
911 | 911 | ||
912 | chan = nouveau_channel_get(dev, file_priv, init->channel); | 912 | chan = nouveau_channel_get(file_priv, init->channel); |
913 | if (IS_ERR(chan)) | 913 | if (IS_ERR(chan)) |
914 | return PTR_ERR(chan); | 914 | return PTR_ERR(chan); |
915 | 915 | ||
@@ -936,7 +936,7 @@ int nouveau_ioctl_gpuobj_free(struct drm_device *dev, void *data, | |||
936 | struct nouveau_channel *chan; | 936 | struct nouveau_channel *chan; |
937 | int ret; | 937 | int ret; |
938 | 938 | ||
939 | chan = nouveau_channel_get(dev, file_priv, objfree->channel); | 939 | chan = nouveau_channel_get(file_priv, objfree->channel); |
940 | if (IS_ERR(chan)) | 940 | if (IS_ERR(chan)) |
941 | return PTR_ERR(chan); | 941 | return PTR_ERR(chan); |
942 | 942 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 9965063beb69..b38b28066836 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c | |||
@@ -774,6 +774,8 @@ nouveau_open(struct drm_device *dev, struct drm_file *file_priv) | |||
774 | return -ENOMEM; | 774 | return -ENOMEM; |
775 | 775 | ||
776 | spin_lock_init(&fpriv->lock); | 776 | spin_lock_init(&fpriv->lock); |
777 | INIT_LIST_HEAD(&fpriv->channels); | ||
778 | |||
777 | file_priv->driver_priv = fpriv; | 779 | file_priv->driver_priv = fpriv; |
778 | return 0; | 780 | return 0; |
779 | } | 781 | } |