Commit 7403ed3e authored by Paul Mackerras's avatar Paul Mackerras

Merge samba.org:/home/paulus/kernel/linux-2.5

into samba.org:/home/paulus/kernel/for-linus-ppc
parents 738198a4 f9fc1633
...@@ -247,6 +247,15 @@ ChangeLog ...@@ -247,6 +247,15 @@ ChangeLog
Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog. Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog.
2.0.13:
- Internal changes towards using iget5_locked() in preparation for
fake inodes and small cleanups to ntfs_volume structure.
2.0.12:
- Internal cleanups in address space operations made possible by the
changes introduced in the previous release.
2.0.11:
- Internal updates and cleanups introducing the first step towards
fake inode based attribute i/o.
2.0.10: 2.0.10:
- Microsoft says that the maximum number of inodes is 2^32 - 1. Update - Microsoft says that the maximum number of inodes is 2^32 - 1. Update
the driver accordingly to only use 32-bits to store inode numbers on the driver accordingly to only use 32-bits to store inode numbers on
......
...@@ -84,6 +84,10 @@ typedef unsigned int drm_magic_t; ...@@ -84,6 +84,10 @@ typedef unsigned int drm_magic_t;
/* Warning: If you change this structure, make sure you change /* Warning: If you change this structure, make sure you change
* XF86DRIClipRectRec in the server as well */ * XF86DRIClipRectRec in the server as well */
/* KW: Actually it's illegal to change either for
* backwards-compatibility reasons.
*/
typedef struct drm_clip_rect { typedef struct drm_clip_rect {
unsigned short x1; unsigned short x1;
unsigned short y1; unsigned short y1;
...@@ -99,15 +103,6 @@ typedef struct drm_tex_region { ...@@ -99,15 +103,6 @@ typedef struct drm_tex_region {
unsigned int age; unsigned int age;
} drm_tex_region_t; } drm_tex_region_t;
/* Seperate include files for the i810/mga/r128 specific structures */
#include "mga_drm.h"
#include "i810_drm.h"
#include "r128_drm.h"
#include "radeon_drm.h"
#include "sis_drm.h"
#include "i830_drm.h"
#include "gamma_drm.h"
typedef struct drm_version { typedef struct drm_version {
int version_major; /* Major version */ int version_major; /* Major version */
int version_minor; /* Minor version */ int version_minor; /* Minor version */
...@@ -428,95 +423,8 @@ typedef struct drm_scatter_gather { ...@@ -428,95 +423,8 @@ typedef struct drm_scatter_gather {
#define DRM_IOCTL_SG_ALLOC DRM_IOW( 0x38, drm_scatter_gather_t) #define DRM_IOCTL_SG_ALLOC DRM_IOW( 0x38, drm_scatter_gather_t)
#define DRM_IOCTL_SG_FREE DRM_IOW( 0x39, drm_scatter_gather_t) #define DRM_IOCTL_SG_FREE DRM_IOW( 0x39, drm_scatter_gather_t)
/* MGA specific ioctls */ /* Device specfic ioctls should only be in their respective headers
#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t) * The device specific ioctl range is 0x40 to 0x79. */
#define DRM_IOCTL_MGA_FLUSH DRM_IOW( 0x41, drm_lock_t) #define DRM_COMMAND_BASE 0x40
#define DRM_IOCTL_MGA_RESET DRM_IO( 0x42)
#define DRM_IOCTL_MGA_SWAP DRM_IO( 0x43)
#define DRM_IOCTL_MGA_CLEAR DRM_IOW( 0x44, drm_mga_clear_t)
#define DRM_IOCTL_MGA_VERTEX DRM_IOW( 0x45, drm_mga_vertex_t)
#define DRM_IOCTL_MGA_INDICES DRM_IOW( 0x46, drm_mga_indices_t)
#define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x47, drm_mga_iload_t)
#define DRM_IOCTL_MGA_BLIT DRM_IOW( 0x48, drm_mga_blit_t)
/* i810 specific ioctls */
#define DRM_IOCTL_I810_INIT DRM_IOW( 0x40, drm_i810_init_t)
#define DRM_IOCTL_I810_VERTEX DRM_IOW( 0x41, drm_i810_vertex_t)
#define DRM_IOCTL_I810_CLEAR DRM_IOW( 0x42, drm_i810_clear_t)
#define DRM_IOCTL_I810_FLUSH DRM_IO( 0x43)
#define DRM_IOCTL_I810_GETAGE DRM_IO( 0x44)
#define DRM_IOCTL_I810_GETBUF DRM_IOWR(0x45, drm_i810_dma_t)
#define DRM_IOCTL_I810_SWAP DRM_IO( 0x46)
#define DRM_IOCTL_I810_COPY DRM_IOW( 0x47, drm_i810_copy_t)
#define DRM_IOCTL_I810_DOCOPY DRM_IO( 0x48)
#define DRM_IOCTL_I810_OV0INFO DRM_IOR( 0x49, drm_i810_overlay_t)
#define DRM_IOCTL_I810_FSTATUS DRM_IO ( 0x4a)
#define DRM_IOCTL_I810_OV0FLIP DRM_IO ( 0x4b)
#define DRM_IOCTL_I810_MC DRM_IOW( 0x4c, drm_i810_mc_t)
#define DRM_IOCTL_I810_RSTATUS DRM_IO ( 0x4d )
/* Rage 128 specific ioctls */
#define DRM_IOCTL_R128_INIT DRM_IOW( 0x40, drm_r128_init_t)
#define DRM_IOCTL_R128_CCE_START DRM_IO( 0x41)
#define DRM_IOCTL_R128_CCE_STOP DRM_IOW( 0x42, drm_r128_cce_stop_t)
#define DRM_IOCTL_R128_CCE_RESET DRM_IO( 0x43)
#define DRM_IOCTL_R128_CCE_IDLE DRM_IO( 0x44)
#define DRM_IOCTL_R128_RESET DRM_IO( 0x46)
#define DRM_IOCTL_R128_SWAP DRM_IO( 0x47)
#define DRM_IOCTL_R128_CLEAR DRM_IOW( 0x48, drm_r128_clear_t)
#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x49, drm_r128_vertex_t)
#define DRM_IOCTL_R128_INDICES DRM_IOW( 0x4a, drm_r128_indices_t)
#define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4b, drm_r128_blit_t)
#define DRM_IOCTL_R128_DEPTH DRM_IOW( 0x4c, drm_r128_depth_t)
#define DRM_IOCTL_R128_STIPPLE DRM_IOW( 0x4d, drm_r128_stipple_t)
#define DRM_IOCTL_R128_INDIRECT DRM_IOWR(0x4f, drm_r128_indirect_t)
#define DRM_IOCTL_R128_FULLSCREEN DRM_IOW( 0x50, drm_r128_fullscreen_t)
#define DRM_IOCTL_R128_CLEAR2 DRM_IOW( 0x51, drm_r128_clear2_t)
/* Radeon specific ioctls */
#define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( 0x40, drm_radeon_init_t)
#define DRM_IOCTL_RADEON_CP_START DRM_IO( 0x41)
#define DRM_IOCTL_RADEON_CP_STOP DRM_IOW( 0x42, drm_radeon_cp_stop_t)
#define DRM_IOCTL_RADEON_CP_RESET DRM_IO( 0x43)
#define DRM_IOCTL_RADEON_CP_IDLE DRM_IO( 0x44)
#define DRM_IOCTL_RADEON_RESET DRM_IO( 0x45)
#define DRM_IOCTL_RADEON_FULLSCREEN DRM_IOW( 0x46, drm_radeon_fullscreen_t)
#define DRM_IOCTL_RADEON_SWAP DRM_IO( 0x47)
#define DRM_IOCTL_RADEON_CLEAR DRM_IOW( 0x48, drm_radeon_clear_t)
#define DRM_IOCTL_RADEON_VERTEX DRM_IOW( 0x49, drm_radeon_vertex_t)
#define DRM_IOCTL_RADEON_INDICES DRM_IOW( 0x4a, drm_radeon_indices_t)
#define DRM_IOCTL_RADEON_STIPPLE DRM_IOW( 0x4c, drm_radeon_stipple_t)
#define DRM_IOCTL_RADEON_INDIRECT DRM_IOWR(0x4d, drm_radeon_indirect_t)
#define DRM_IOCTL_RADEON_TEXTURE DRM_IOWR(0x4e, drm_radeon_texture_t)
#define DRM_IOCTL_RADEON_VERTEX2 DRM_IOW( 0x4f, drm_radeon_vertex_t)
#define DRM_IOCTL_RADEON_CMDBUF DRM_IOW( 0x50, drm_radeon_cmd_buffer_t)
#define DRM_IOCTL_RADEON_GETPARAM DRM_IOWR(0x51, drm_radeon_getparam_t)
#define DRM_IOCTL_RADEON_FLIP DRM_IO( 0x52)
/* Gamma specific ioctls */
#define DRM_IOCTL_GAMMA_INIT DRM_IOW( 0x40, drm_gamma_init_t)
#define DRM_IOCTL_GAMMA_COPY DRM_IOW( 0x41, drm_gamma_copy_t)
/* SiS specific ioctls */
#define SIS_IOCTL_FB_ALLOC DRM_IOWR(0x44, drm_sis_mem_t)
#define SIS_IOCTL_FB_FREE DRM_IOW( 0x45, drm_sis_mem_t)
#define SIS_IOCTL_AGP_INIT DRM_IOWR(0x53, drm_sis_agp_t)
#define SIS_IOCTL_AGP_ALLOC DRM_IOWR(0x54, drm_sis_mem_t)
#define SIS_IOCTL_AGP_FREE DRM_IOW( 0x55, drm_sis_mem_t)
#define SIS_IOCTL_FLIP DRM_IOW( 0x48, drm_sis_flip_t)
#define SIS_IOCTL_FLIP_INIT DRM_IO( 0x49)
#define SIS_IOCTL_FLIP_FINAL DRM_IO( 0x50)
/* I830 specific ioctls */
#define DRM_IOCTL_I830_INIT DRM_IOW( 0x40, drm_i830_init_t)
#define DRM_IOCTL_I830_VERTEX DRM_IOW( 0x41, drm_i830_vertex_t)
#define DRM_IOCTL_I830_CLEAR DRM_IOW( 0x42, drm_i830_clear_t)
#define DRM_IOCTL_I830_FLUSH DRM_IO ( 0x43)
#define DRM_IOCTL_I830_GETAGE DRM_IO ( 0x44)
#define DRM_IOCTL_I830_GETBUF DRM_IOWR(0x45, drm_i830_dma_t)
#define DRM_IOCTL_I830_SWAP DRM_IO ( 0x46)
#define DRM_IOCTL_I830_COPY DRM_IOW( 0x47, drm_i830_copy_t)
#define DRM_IOCTL_I830_DOCOPY DRM_IO ( 0x48)
#endif #endif
...@@ -555,7 +555,7 @@ static int DRM(alloc_queue)(drm_device_t *dev) ...@@ -555,7 +555,7 @@ static int DRM(alloc_queue)(drm_device_t *dev)
/* Allocate a new queue */ /* Allocate a new queue */
down(&dev->struct_sem); down(&dev->struct_sem);
queue = gamma_alloc(sizeof(*queue), DRM_MEM_QUEUES); queue = DRM(alloc)(sizeof(*queue), DRM_MEM_QUEUES);
memset(queue, 0, sizeof(*queue)); memset(queue, 0, sizeof(*queue));
atomic_set(&queue->use_count, 1); atomic_set(&queue->use_count, 1);
......
...@@ -32,6 +32,8 @@ ...@@ -32,6 +32,8 @@
#define __NO_VERSION__ #define __NO_VERSION__
#include "gamma.h" #include "gamma.h"
#include "drmP.h" #include "drmP.h"
#include "drm.h"
#include "gamma_drm.h"
#include "gamma_drv.h" #include "gamma_drv.h"
#include <linux/interrupt.h> /* For task queue support */ #include <linux/interrupt.h> /* For task queue support */
......
...@@ -48,6 +48,16 @@ typedef struct _drm_gamma_sarea { ...@@ -48,6 +48,16 @@ typedef struct _drm_gamma_sarea {
int vertex_prim; int vertex_prim;
} drm_gamma_sarea_t; } drm_gamma_sarea_t;
/* WARNING: If you change any of these defines, make sure to change the
* defines in the Xserver file (xf86drmGamma.h)
*/
/* Gamma specific ioctls
* The device specific ioctl range is 0x40 to 0x79.
*/
#define DRM_IOCTL_GAMMA_INIT DRM_IOW( 0x40, drm_gamma_init_t)
#define DRM_IOCTL_GAMMA_COPY DRM_IOW( 0x41, drm_gamma_copy_t)
typedef struct drm_gamma_copy { typedef struct drm_gamma_copy {
unsigned int DMAOutputAddress; unsigned int DMAOutputAddress;
unsigned int DMAOutputCount; unsigned int DMAOutputCount;
......
...@@ -32,6 +32,8 @@ ...@@ -32,6 +32,8 @@
#include <linux/config.h> #include <linux/config.h>
#include "gamma.h" #include "gamma.h"
#include "drmP.h" #include "drmP.h"
#include "drm.h"
#include "gamma_drm.h"
#include "gamma_drv.h" #include "gamma_drv.h"
#define DRIVER_AUTHOR "VA Linux Systems Inc." #define DRIVER_AUTHOR "VA Linux Systems Inc."
......
...@@ -33,6 +33,8 @@ ...@@ -33,6 +33,8 @@
#define __NO_VERSION__ #define __NO_VERSION__
#include "i810.h" #include "i810.h"
#include "drmP.h" #include "drmP.h"
#include "drm.h"
#include "i810_drm.h"
#include "i810_drv.h" #include "i810_drv.h"
#include <linux/interrupt.h> /* For task queue support */ #include <linux/interrupt.h> /* For task queue support */
#include <linux/delay.h> #include <linux/delay.h>
......
...@@ -168,14 +168,34 @@ typedef struct _drm_i810_sarea { ...@@ -168,14 +168,34 @@ typedef struct _drm_i810_sarea {
} drm_i810_sarea_t; } drm_i810_sarea_t;
/* WARNING: If you change any of these defines, make sure to change the
* defines in the Xserver file (xf86drmMga.h)
*/
/* i810 specific ioctls
* The device specific ioctl range is 0x40 to 0x79.
*/
#define DRM_IOCTL_I810_INIT DRM_IOW( 0x40, drm_i810_init_t)
#define DRM_IOCTL_I810_VERTEX DRM_IOW( 0x41, drm_i810_vertex_t)
#define DRM_IOCTL_I810_CLEAR DRM_IOW( 0x42, drm_i810_clear_t)
#define DRM_IOCTL_I810_FLUSH DRM_IO( 0x43)
#define DRM_IOCTL_I810_GETAGE DRM_IO( 0x44)
#define DRM_IOCTL_I810_GETBUF DRM_IOWR(0x45, drm_i810_dma_t)
#define DRM_IOCTL_I810_SWAP DRM_IO( 0x46)
#define DRM_IOCTL_I810_COPY DRM_IOW( 0x47, drm_i810_copy_t)
#define DRM_IOCTL_I810_DOCOPY DRM_IO( 0x48)
#define DRM_IOCTL_I810_OV0INFO DRM_IOR( 0x49, drm_i810_overlay_t)
#define DRM_IOCTL_I810_FSTATUS DRM_IO ( 0x4a)
#define DRM_IOCTL_I810_OV0FLIP DRM_IO ( 0x4b)
#define DRM_IOCTL_I810_MC DRM_IOW( 0x4c, drm_i810_mc_t)
#define DRM_IOCTL_I810_RSTATUS DRM_IO ( 0x4d )
typedef struct _drm_i810_clear { typedef struct _drm_i810_clear {
int clear_color; int clear_color;
int clear_depth; int clear_depth;
int flags; int flags;
} drm_i810_clear_t; } drm_i810_clear_t;
/* These may be placeholders if we have more cliprects than /* These may be placeholders if we have more cliprects than
* I810_NR_SAREA_CLIPRECTS. In that case, the client sets discard to * I810_NR_SAREA_CLIPRECTS. In that case, the client sets discard to
* false, indicating that the buffer will be dispatched again with a * false, indicating that the buffer will be dispatched again with a
......
...@@ -33,6 +33,8 @@ ...@@ -33,6 +33,8 @@
#include <linux/config.h> #include <linux/config.h>
#include "i810.h" #include "i810.h"
#include "drmP.h" #include "drmP.h"
#include "drm.h"
#include "i810_drm.h"
#include "i810_drv.h" #include "i810_drv.h"
#define DRIVER_AUTHOR "VA Linux Systems Inc." #define DRIVER_AUTHOR "VA Linux Systems Inc."
......
...@@ -34,10 +34,11 @@ ...@@ -34,10 +34,11 @@
#define __NO_VERSION__ #define __NO_VERSION__
#include "i830.h" #include "i830.h"
#include "drmP.h" #include "drmP.h"
#include "drm.h"
#include "i830_drm.h"
#include "i830_drv.h" #include "i830_drv.h"
#include <linux/interrupt.h> /* For task queue support */ #include <linux/interrupt.h> /* For task queue support */
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/pagemap.h>
/* in case we don't have a 2.3.99-pre6 kernel or later: */ /* in case we don't have a 2.3.99-pre6 kernel or later: */
#ifndef VM_DONTCOPY #ifndef VM_DONTCOPY
...@@ -58,7 +59,6 @@ ...@@ -58,7 +59,6 @@
do { \ do { \
int _head; \ int _head; \
int _tail; \ int _tail; \
int _i; \
do { \ do { \
_head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR; \ _head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR; \
_tail = I830_READ(LP_RING + RING_TAIL) & TAIL_ADDR; \ _tail = I830_READ(LP_RING + RING_TAIL) & TAIL_ADDR; \
...@@ -370,8 +370,6 @@ static int i830_wait_ring(drm_device_t *dev, int n) ...@@ -370,8 +370,6 @@ static int i830_wait_ring(drm_device_t *dev, int n)
end = jiffies + (HZ*3); end = jiffies + (HZ*3);
while (ring->space < n) { while (ring->space < n) {
int i;
ring->head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR; ring->head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
ring->space = ring->head - (ring->tail+8); ring->space = ring->head - (ring->tail+8);
if (ring->space < 0) ring->space += ring->Size; if (ring->space < 0) ring->space += ring->Size;
...@@ -387,7 +385,6 @@ static int i830_wait_ring(drm_device_t *dev, int n) ...@@ -387,7 +385,6 @@ static int i830_wait_ring(drm_device_t *dev, int n)
DRM_ERROR("lockup\n"); DRM_ERROR("lockup\n");
goto out_wait_ring; goto out_wait_ring;
} }
udelay(1); udelay(1);
} }
......
...@@ -201,6 +201,19 @@ typedef struct _drm_i830_sarea { ...@@ -201,6 +201,19 @@ typedef struct _drm_i830_sarea {
int vertex_prim; int vertex_prim;
} drm_i830_sarea_t; } drm_i830_sarea_t;
/* I830 specific ioctls
* The device specific ioctl range is 0x40 to 0x79.
*/
#define DRM_IOCTL_I830_INIT DRM_IOW( 0x40, drm_i830_init_t)
#define DRM_IOCTL_I830_VERTEX DRM_IOW( 0x41, drm_i830_vertex_t)
#define DRM_IOCTL_I830_CLEAR DRM_IOW( 0x42, drm_i830_clear_t)
#define DRM_IOCTL_I830_FLUSH DRM_IO ( 0x43)
#define DRM_IOCTL_I830_GETAGE DRM_IO ( 0x44)
#define DRM_IOCTL_I830_GETBUF DRM_IOWR(0x45, drm_i830_dma_t)
#define DRM_IOCTL_I830_SWAP DRM_IO ( 0x46)
#define DRM_IOCTL_I830_COPY DRM_IOW( 0x47, drm_i830_copy_t)
#define DRM_IOCTL_I830_DOCOPY DRM_IO ( 0x48)
typedef struct _drm_i830_clear { typedef struct _drm_i830_clear {
int clear_color; int clear_color;
int clear_depth; int clear_depth;
......
...@@ -34,6 +34,8 @@ ...@@ -34,6 +34,8 @@
#include <linux/config.h> #include <linux/config.h>
#include "i830.h" #include "i830.h"
#include "drmP.h" #include "drmP.h"
#include "drm.h"
#include "i830_drm.h"
#include "i830_drv.h" #include "i830_drv.h"
#define DRIVER_AUTHOR "VA Linux Systems Inc." #define DRIVER_AUTHOR "VA Linux Systems Inc."
......
...@@ -36,6 +36,8 @@ ...@@ -36,6 +36,8 @@
#define __NO_VERSION__ #define __NO_VERSION__
#include "mga.h" #include "mga.h"
#include "drmP.h" #include "drmP.h"
#include "drm.h"
#include "mga_drm.h"
#include "mga_drv.h" #include "mga_drv.h"
#include <linux/interrupt.h> /* For task queue support */ #include <linux/interrupt.h> /* For task queue support */
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
/* WARNING: If you change any of these defines, make sure to change the /* WARNING: If you change any of these defines, make sure to change the
* defines in the Xserver file (mga_sarea.h) * defines in the Xserver file (mga_sarea.h)
*/ */
#ifndef __MGA_SAREA_DEFINES__ #ifndef __MGA_SAREA_DEFINES__
#define __MGA_SAREA_DEFINES__ #define __MGA_SAREA_DEFINES__
...@@ -225,6 +226,20 @@ typedef struct _drm_mga_sarea { ...@@ -225,6 +226,20 @@ typedef struct _drm_mga_sarea {
/* WARNING: If you change any of these defines, make sure to change the /* WARNING: If you change any of these defines, make sure to change the
* defines in the Xserver file (xf86drmMga.h) * defines in the Xserver file (xf86drmMga.h)
*/ */
/* MGA specific ioctls
* The device specific ioctl range is 0x40 to 0x79.
*/
#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t)
#define DRM_IOCTL_MGA_FLUSH DRM_IOW( 0x41, drm_lock_t)
#define DRM_IOCTL_MGA_RESET DRM_IO( 0x42)
#define DRM_IOCTL_MGA_SWAP DRM_IO( 0x43)
#define DRM_IOCTL_MGA_CLEAR DRM_IOW( 0x44, drm_mga_clear_t)
#define DRM_IOCTL_MGA_VERTEX DRM_IOW( 0x45, drm_mga_vertex_t)
#define DRM_IOCTL_MGA_INDICES DRM_IOW( 0x46, drm_mga_indices_t)
#define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x47, drm_mga_iload_t)
#define DRM_IOCTL_MGA_BLIT DRM_IOW( 0x48, drm_mga_blit_t)
typedef struct _drm_mga_warp_index { typedef struct _drm_mga_warp_index {
int installed; int installed;
unsigned long phys_addr; unsigned long phys_addr;
......
...@@ -32,6 +32,8 @@ ...@@ -32,6 +32,8 @@
#include <linux/config.h> #include <linux/config.h>
#include "mga.h" #include "mga.h"
#include "drmP.h" #include "drmP.h"
#include "drm.h"
#include "mga_drm.h"
#include "mga_drv.h" #include "mga_drv.h"
#define DRIVER_AUTHOR "Gareth Hughes, VA Linux Systems Inc." #define DRIVER_AUTHOR "Gareth Hughes, VA Linux Systems Inc."
......
...@@ -35,6 +35,8 @@ ...@@ -35,6 +35,8 @@
#define __NO_VERSION__ #define __NO_VERSION__
#include "mga.h" #include "mga.h"
#include "drmP.h" #include "drmP.h"
#include "drm.h"
#include "mga_drm.h"
#include "mga_drv.h" #include "mga_drv.h"
#include "drm.h" #include "drm.h"
......
...@@ -30,6 +30,8 @@ ...@@ -30,6 +30,8 @@
#define __NO_VERSION__ #define __NO_VERSION__
#include "mga.h" #include "mga.h"
#include "drmP.h" #include "drmP.h"
#include "drm.h"
#include "mga_drm.h"
#include "mga_drv.h" #include "mga_drv.h"
#include "mga_ucode.h" #include "mga_ucode.h"
......
...@@ -31,6 +31,8 @@ ...@@ -31,6 +31,8 @@
#define __NO_VERSION__ #define __NO_VERSION__
#include "r128.h" #include "r128.h"
#include "drmP.h" #include "drmP.h"
#include "drm.h"
#include "r128_drm.h"
#include "r128_drv.h" #include "r128_drv.h"
#include <linux/interrupt.h> /* For task queue support */ #include <linux/interrupt.h> /* For task queue support */
......
...@@ -170,6 +170,27 @@ typedef struct drm_r128_sarea { ...@@ -170,6 +170,27 @@ typedef struct drm_r128_sarea {
/* WARNING: If you change any of these defines, make sure to change the /* WARNING: If you change any of these defines, make sure to change the
* defines in the Xserver file (xf86drmR128.h) * defines in the Xserver file (xf86drmR128.h)
*/ */
/* Rage 128 specific ioctls
* The device specific ioctl range is 0x40 to 0x79.
*/
#define DRM_IOCTL_R128_INIT DRM_IOW( 0x40, drm_r128_init_t)
#define DRM_IOCTL_R128_CCE_START DRM_IO( 0x41)
#define DRM_IOCTL_R128_CCE_STOP DRM_IOW( 0x42, drm_r128_cce_stop_t)
#define DRM_IOCTL_R128_CCE_RESET DRM_IO( 0x43)
#define DRM_IOCTL_R128_CCE_IDLE DRM_IO( 0x44)
#define DRM_IOCTL_R128_RESET DRM_IO( 0x46)
#define DRM_IOCTL_R128_SWAP DRM_IO( 0x47)
#define DRM_IOCTL_R128_CLEAR DRM_IOW( 0x48, drm_r128_clear_t)
#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x49, drm_r128_vertex_t)
#define DRM_IOCTL_R128_INDICES DRM_IOW( 0x4a, drm_r128_indices_t)
#define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4b, drm_r128_blit_t)
#define DRM_IOCTL_R128_DEPTH DRM_IOW( 0x4c, drm_r128_depth_t)
#define DRM_IOCTL_R128_STIPPLE DRM_IOW( 0x4d, drm_r128_stipple_t)
#define DRM_IOCTL_R128_INDIRECT DRM_IOWR(0x4f, drm_r128_indirect_t)
#define DRM_IOCTL_R128_FULLSCREEN DRM_IOW( 0x50, drm_r128_fullscreen_t)
#define DRM_IOCTL_R128_CLEAR2 DRM_IOW( 0x51, drm_r128_clear2_t)
typedef struct drm_r128_init { typedef struct drm_r128_init {
enum { enum {
R128_INIT_CCE = 0x01, R128_INIT_CCE = 0x01,
......
...@@ -32,6 +32,8 @@ ...@@ -32,6 +32,8 @@
#include <linux/config.h> #include <linux/config.h>
#include "r128.h" #include "r128.h"
#include "drmP.h" #include "drmP.h"
#include "drm.h"
#include "r128_drm.h"
#include "r128_drv.h" #include "r128_drv.h"
#include "ati_pcigart.h" #include "ati_pcigart.h"
......
...@@ -34,8 +34,8 @@ ...@@ -34,8 +34,8 @@
#ifndef __R128_DRV_H__ #ifndef __R128_DRV_H__
#define __R128_DRV_H__ #define __R128_DRV_H__
#define GET_RING_HEAD( ring ) le32_to_cpu( *(ring)->head ) #define GET_RING_HEAD(ring) readl( (volatile u32 *) (ring)->head )
#define SET_RING_HEAD( ring, val ) *(ring)->head = cpu_to_le32( val ) #define SET_RING_HEAD(ring,val) writel( (val), (volatile u32 *) (ring)->head )
typedef struct drm_r128_freelist { typedef struct drm_r128_freelist {
unsigned int age; unsigned int age;
...@@ -384,44 +384,11 @@ extern int r128_cce_indirect( struct inode *inode, struct file *filp, ...@@ -384,44 +384,11 @@ extern int r128_cce_indirect( struct inode *inode, struct file *filp,
#define R128_BASE(reg) ((unsigned long)(dev_priv->mmio->handle)) #define R128_BASE(reg) ((unsigned long)(dev_priv->mmio->handle))
#define R128_ADDR(reg) (R128_BASE( reg ) + reg) #define R128_ADDR(reg) (R128_BASE( reg ) + reg)
#define R128_DEREF(reg) *(volatile u32 *)R128_ADDR( reg ) #define R128_READ(reg) readl( (volatile u32 *) R128_ADDR(reg) )
#ifdef __alpha__ #define R128_WRITE(reg,val) writel( (val), (volatile u32 *) R128_ADDR(reg) )
#define R128_READ(reg) (_R128_READ((u32 *)R128_ADDR(reg)))
static inline u32 _R128_READ(u32 *addr)
{
mb();
return *(volatile u32 *)addr;
}
#define R128_WRITE(reg,val) \
do { \
wmb(); \
R128_DEREF(reg) = val; \
} while (0)
#else
#define R128_READ(reg) le32_to_cpu( R128_DEREF( reg ) )
#define R128_WRITE(reg,val) \
do { \
R128_DEREF( reg ) = cpu_to_le32( val ); \
} while (0)
#endif
#define R128_DEREF8(reg) *(volatile u8 *)R128_ADDR( reg ) #define R128_READ8(reg) readb( (volatile u8 *) R128_ADDR(reg) )
#ifdef __alpha__ #define R128_WRITE8(reg,val) writeb( (val), (volatile u8 *) R128_ADDR(reg) )
#define R128_READ8(reg) _R128_READ8((u8 *)R128_ADDR(reg))
static inline u8 _R128_READ8(u8 *addr)
{
mb();
return *(volatile u8 *)addr;
}
#define R128_WRITE8(reg,val) \
do { \
wmb(); \
R128_DEREF8(reg) = val; \
} while (0)
#else
#define R128_READ8(reg) R128_DEREF8( reg )
#define R128_WRITE8(reg,val) do { R128_DEREF8( reg ) = val; } while (0)
#endif
#define R128_WRITE_PLL(addr,val) \ #define R128_WRITE_PLL(addr,val) \
do { \ do { \
...@@ -493,7 +460,11 @@ do { \ ...@@ -493,7 +460,11 @@ do { \
* Ring control * Ring control
*/ */
#if defined(__powerpc__)
#define r128_flush_write_combine() (void) GET_RING_HEAD( &dev_priv->ring )
#else
#define r128_flush_write_combine() mb() #define r128_flush_write_combine() mb()
#endif
#define R128_VERBOSE 0 #define R128_VERBOSE 0
......
...@@ -30,6 +30,8 @@ ...@@ -30,6 +30,8 @@
#define __NO_VERSION__ #define __NO_VERSION__
#include "r128.h" #include "r128.h"
#include "drmP.h" #include "drmP.h"
#include "drm.h"
#include "r128_drm.h"
#include "r128_drv.h" #include "r128_drv.h"
#include "drm.h" #include "drm.h"
#include <linux/delay.h> #include <linux/delay.h>
......
...@@ -31,6 +31,8 @@ ...@@ -31,6 +31,8 @@
#define __NO_VERSION__ #define __NO_VERSION__
#include "radeon.h" #include "radeon.h"
#include "drmP.h" #include "drmP.h"
#include "drm.h"
#include "radeon_drm.h"
#include "radeon_drv.h" #include "radeon_drv.h"
#include <linux/interrupt.h> /* For task queue support */ #include <linux/interrupt.h> /* For task queue support */
...@@ -38,7 +40,7 @@ ...@@ -38,7 +40,7 @@
#define RADEON_FIFO_DEBUG 0 #define RADEON_FIFO_DEBUG 0
#if defined(__alpha__) #if defined(__alpha__) || defined(__powerpc__)
# define PCIGART_ENABLED # define PCIGART_ENABLED
#else #else
# undef PCIGART_ENABLED # undef PCIGART_ENABLED
...@@ -631,7 +633,11 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev, ...@@ -631,7 +633,11 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev,
} }
/* Set ring buffer size */ /* Set ring buffer size */
#ifdef __BIG_ENDIAN
RADEON_WRITE( RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw | RADEON_BUF_SWAP_32BIT );
#else
RADEON_WRITE( RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw ); RADEON_WRITE( RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw );
#endif
radeon_do_wait_for_idle( dev_priv ); radeon_do_wait_for_idle( dev_priv );
......
...@@ -301,6 +301,29 @@ typedef struct { ...@@ -301,6 +301,29 @@ typedef struct {
* *
* KW: actually it's illegal to change any of this (backwards compatibility). * KW: actually it's illegal to change any of this (backwards compatibility).
*/ */
/* Radeon specific ioctls
* The device specific ioctl range is 0x40 to 0x79.
*/
#define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( 0x40, drm_radeon_init_t)
#define DRM_IOCTL_RADEON_CP_START DRM_IO( 0x41)
#define DRM_IOCTL_RADEON_CP_STOP DRM_IOW( 0x42, drm_radeon_cp_stop_t)
#define DRM_IOCTL_RADEON_CP_RESET DRM_IO( 0x43)
#define DRM_IOCTL_RADEON_CP_IDLE DRM_IO( 0x44)
#define DRM_IOCTL_RADEON_RESET DRM_IO( 0x45)
#define DRM_IOCTL_RADEON_FULLSCREEN DRM_IOW( 0x46, drm_radeon_fullscreen_t)
#define DRM_IOCTL_RADEON_SWAP DRM_IO( 0x47)
#define DRM_IOCTL_RADEON_CLEAR DRM_IOW( 0x48, drm_radeon_clear_t)
#define DRM_IOCTL_RADEON_VERTEX DRM_IOW( 0x49, drm_radeon_vertex_t)
#define DRM_IOCTL_RADEON_INDICES DRM_IOW( 0x4a, drm_radeon_indices_t)
#define DRM_IOCTL_RADEON_STIPPLE DRM_IOW( 0x4c, drm_radeon_stipple_t)
#define DRM_IOCTL_RADEON_INDIRECT DRM_IOWR(0x4d, drm_radeon_indirect_t)
#define DRM_IOCTL_RADEON_TEXTURE DRM_IOWR(0x4e, drm_radeon_texture_t)
#define DRM_IOCTL_RADEON_VERTEX2 DRM_IOW( 0x4f, drm_radeon_vertex_t)
#define DRM_IOCTL_RADEON_CMDBUF DRM_IOW( 0x50, drm_radeon_cmd_buffer_t)
#define DRM_IOCTL_RADEON_GETPARAM DRM_IOWR(0x51, drm_radeon_getparam_t)
#define DRM_IOCTL_RADEON_FLIP DRM_IO( 0x52)
typedef struct drm_radeon_init { typedef struct drm_radeon_init {
enum { enum {
RADEON_INIT_CP = 0x01, RADEON_INIT_CP = 0x01,
......
...@@ -30,6 +30,8 @@ ...@@ -30,6 +30,8 @@
#include <linux/config.h> #include <linux/config.h>
#include "radeon.h" #include "radeon.h"
#include "drmP.h" #include "drmP.h"
#include "drm.h"
#include "radeon_drm.h"
#include "radeon_drv.h" #include "radeon_drv.h"
#include "ati_pcigart.h" #include "ati_pcigart.h"
...@@ -37,11 +39,11 @@ ...@@ -37,11 +39,11 @@
#define DRIVER_NAME "radeon" #define DRIVER_NAME "radeon"
#define DRIVER_DESC "ATI Radeon" #define DRIVER_DESC "ATI Radeon"
#define DRIVER_DATE "20020521" #define DRIVER_DATE "20020611"
#define DRIVER_MAJOR 1 #define DRIVER_MAJOR 1
#define DRIVER_MINOR 3 #define DRIVER_MINOR 3
#define DRIVER_PATCHLEVEL 0 #define DRIVER_PATCHLEVEL 1
/* Interface history: /* Interface history:
* *
......
...@@ -31,6 +31,9 @@ ...@@ -31,6 +31,9 @@
#ifndef __RADEON_DRV_H__ #ifndef __RADEON_DRV_H__
#define __RADEON_DRV_H__ #define __RADEON_DRV_H__
#define GET_RING_HEAD(ring) readl( (volatile u32 *) (ring)->head )
#define SET_RING_HEAD(ring,val) writel( (val), (volatile u32 *) (ring)->head )
typedef struct drm_radeon_freelist { typedef struct drm_radeon_freelist {
unsigned int age; unsigned int age;
drm_buf_t *buf; drm_buf_t *buf;
...@@ -141,7 +144,7 @@ extern int radeon_wait_ring( drm_radeon_private_t *dev_priv, int n ); ...@@ -141,7 +144,7 @@ extern int radeon_wait_ring( drm_radeon_private_t *dev_priv, int n );
static inline void static inline void
radeon_update_ring_snapshot( drm_radeon_ring_buffer_t *ring ) radeon_update_ring_snapshot( drm_radeon_ring_buffer_t *ring )
{ {
ring->space = (*(volatile int *)ring->head - ring->tail) * sizeof(u32); ring->space = (GET_RING_HEAD(ring) - ring->tail) * sizeof(u32);
if ( ring->space <= 0 ) if ( ring->space <= 0 )
ring->space += ring->size; ring->space += ring->size;
} }
...@@ -249,6 +252,12 @@ extern int radeon_cp_flip( struct inode *inode, struct file *filp, ...@@ -249,6 +252,12 @@ extern int radeon_cp_flip( struct inode *inode, struct file *filp,
# define RADEON_ISYNC_WAIT_IDLEGUI (1 << 4) # define RADEON_ISYNC_WAIT_IDLEGUI (1 << 4)
# define RADEON_ISYNC_CPSCRATCH_IDLEGUI (1 << 5) # define RADEON_ISYNC_CPSCRATCH_IDLEGUI (1 << 5)
#define RADEON_RBBM_GUICNTL 0x172c
# define RADEON_HOST_DATA_SWAP_NONE (0 << 0)
# define RADEON_HOST_DATA_SWAP_16BIT (1 << 0)
# define RADEON_HOST_DATA_SWAP_32BIT (2 << 0)
# define RADEON_HOST_DATA_SWAP_HDW (3 << 0)
#define RADEON_MC_AGP_LOCATION 0x014c #define RADEON_MC_AGP_LOCATION 0x014c
#define RADEON_MC_FB_LOCATION 0x0148 #define RADEON_MC_FB_LOCATION 0x0148
#define RADEON_MCLK_CNTL 0x0012 #define RADEON_MCLK_CNTL 0x0012
...@@ -424,6 +433,7 @@ extern int radeon_cp_flip( struct inode *inode, struct file *filp, ...@@ -424,6 +433,7 @@ extern int radeon_cp_flip( struct inode *inode, struct file *filp,
#define RADEON_CP_RB_BASE 0x0700 #define RADEON_CP_RB_BASE 0x0700
#define RADEON_CP_RB_CNTL 0x0704 #define RADEON_CP_RB_CNTL 0x0704
# define RADEON_BUF_SWAP_32BIT (2 << 16)
#define RADEON_CP_RB_RPTR_ADDR 0x070c #define RADEON_CP_RB_RPTR_ADDR 0x070c
#define RADEON_CP_RB_RPTR 0x0710 #define RADEON_CP_RB_RPTR 0x0710
#define RADEON_CP_RB_WPTR 0x0714 #define RADEON_CP_RB_WPTR 0x0714
...@@ -533,41 +543,11 @@ extern int radeon_cp_flip( struct inode *inode, struct file *filp, ...@@ -533,41 +543,11 @@ extern int radeon_cp_flip( struct inode *inode, struct file *filp,
#define RADEON_BASE(reg) ((unsigned long)(dev_priv->mmio->handle)) #define RADEON_BASE(reg) ((unsigned long)(dev_priv->mmio->handle))
#define RADEON_ADDR(reg) (RADEON_BASE( reg ) + reg) #define RADEON_ADDR(reg) (RADEON_BASE( reg ) + reg)
#define RADEON_DEREF(reg) *(volatile u32 *)RADEON_ADDR( reg ) #define RADEON_READ(reg) readl( (volatile u32 *) RADEON_ADDR(reg) )
#ifdef __alpha__ #define RADEON_WRITE(reg,val) writel( (val), (volatile u32 *) RADEON_ADDR(reg) )
#define RADEON_READ(reg) (_RADEON_READ((u32 *)RADEON_ADDR( reg )))
static inline u32 _RADEON_READ(u32 *addr)
{
mb();
return *(volatile u32 *)addr;
}
#define RADEON_WRITE(reg,val) \
do { \
wmb(); \
RADEON_DEREF(reg) = val; \
} while (0)
#else
#define RADEON_READ(reg) RADEON_DEREF( reg )
#define RADEON_WRITE(reg, val) do { RADEON_DEREF( reg ) = val; } while (0)
#endif
#define RADEON_DEREF8(reg) *(volatile u8 *)RADEON_ADDR( reg ) #define RADEON_READ8(reg) readb( (volatile u8 *) RADEON_ADDR(reg) )
#ifdef __alpha__ #define RADEON_WRITE8(reg,val) writeb( (val), (volatile u8 *) RADEON_ADDR(reg) )
#define RADEON_READ8(reg) _RADEON_READ8((u8 *)RADEON_ADDR( reg ))
static inline u8 _RADEON_READ8(u8 *addr)
{
mb();
return *(volatile u8 *)addr;
}
#define RADEON_WRITE8(reg,val) \
do { \
wmb(); \
RADEON_DEREF8( reg ) = val; \
} while (0)
#else
#define RADEON_READ8(reg) RADEON_DEREF8( reg )
#define RADEON_WRITE8(reg, val) do { RADEON_DEREF8( reg ) = val; } while (0)
#endif
#define RADEON_WRITE_PLL( addr, val ) \ #define RADEON_WRITE_PLL( addr, val ) \
do { \ do { \
...@@ -664,6 +644,15 @@ do { \ ...@@ -664,6 +644,15 @@ do { \
goto __ring_space_done; \ goto __ring_space_done; \
udelay( 1 ); \ udelay( 1 ); \
} \ } \
DRM_ERROR( "ring space check from memory failed, reading register...\n" ); \
/* If ring space check fails from RAM, try reading the \
register directly */ \
ring->space = 4 * ( RADEON_READ( RADEON_CP_RB_RPTR ) - ring->tail ); \
if ( ring->space <= 0 ) \
ring->space += ring->size; \
if ( ring->space >= ring->high_mark ) \
goto __ring_space_done; \
\
DRM_ERROR( "ring space check failed!\n" ); \ DRM_ERROR( "ring space check failed!\n" ); \
return -EBUSY; \ return -EBUSY; \
} \ } \
...@@ -701,7 +690,11 @@ do { \ ...@@ -701,7 +690,11 @@ do { \
* Ring control * Ring control
*/ */
#if defined(__powerpc__)
#define radeon_flush_write_combine() (void) GET_RING_HEAD( &dev_priv->ring )
#else
#define radeon_flush_write_combine() mb() #define radeon_flush_write_combine() mb()
#endif
#define RADEON_VERBOSE 0 #define RADEON_VERBOSE 0
...@@ -738,6 +731,7 @@ do { \ ...@@ -738,6 +731,7 @@ do { \
} while (0) } while (0)
#define COMMIT_RING() do { \ #define COMMIT_RING() do { \
radeon_flush_write_combine(); \
RADEON_WRITE( RADEON_CP_RB_WPTR, dev_priv->ring.tail ); \ RADEON_WRITE( RADEON_CP_RB_WPTR, dev_priv->ring.tail ); \
} while (0) } while (0)
......
...@@ -30,8 +30,9 @@ ...@@ -30,8 +30,9 @@
#define __NO_VERSION__ #define __NO_VERSION__
#include "radeon.h" #include "radeon.h"
#include "drmP.h" #include "drmP.h"
#include "radeon_drv.h"
#include "drm.h" #include "drm.h"
#include "radeon_drm.h"
#include "radeon_drv.h"
#include <linux/delay.h> #include <linux/delay.h>
...@@ -669,7 +670,6 @@ static void radeon_cp_dispatch_vertex( drm_device_t *dev, ...@@ -669,7 +670,6 @@ static void radeon_cp_dispatch_vertex( drm_device_t *dev,
int i = 0; int i = 0;
RING_LOCALS; RING_LOCALS;
DRM_DEBUG("%s: hwprim 0x%x vfmt 0x%x %d..%d %d verts\n", DRM_DEBUG("%s: hwprim 0x%x vfmt 0x%x %d..%d %d verts\n",
__FUNCTION__, __FUNCTION__,
prim->prim, prim->prim,
...@@ -684,7 +684,6 @@ static void radeon_cp_dispatch_vertex( drm_device_t *dev, ...@@ -684,7 +684,6 @@ static void radeon_cp_dispatch_vertex( drm_device_t *dev,
return; return;
} }
do { do {
/* Emit the next cliprect */ /* Emit the next cliprect */
if ( i < nbox ) { if ( i < nbox ) {
...@@ -906,6 +905,16 @@ static int radeon_cp_dispatch_texture( drm_device_t *dev, ...@@ -906,6 +905,16 @@ static int radeon_cp_dispatch_texture( drm_device_t *dev,
ADVANCE_RING(); ADVANCE_RING();
#ifdef __BIG_ENDIAN
/* The Mesa texture functions provide the data in little endian as the
* chip wants it, but we need to compensate for the fact that the CP
* ring gets byte-swapped
*/
BEGIN_RING( 2 );
OUT_RING_REG( RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_32BIT );
ADVANCE_RING();
#endif
/* Make a copy of the parameters in case we have to update them /* Make a copy of the parameters in case we have to update them
* for a multi-pass texture blit. * for a multi-pass texture blit.
*/ */
...@@ -1081,6 +1090,7 @@ static int radeon_do_init_pageflip( drm_device_t *dev ) ...@@ -1081,6 +1090,7 @@ static int radeon_do_init_pageflip( drm_device_t *dev )
dev_priv->page_flipping = 1; dev_priv->page_flipping = 1;
dev_priv->current_page = 0; dev_priv->current_page = 0;
dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page;
return 0; return 0;
} }
...@@ -1095,6 +1105,7 @@ int radeon_do_cleanup_pageflip( drm_device_t *dev ) ...@@ -1095,6 +1105,7 @@ int radeon_do_cleanup_pageflip( drm_device_t *dev )
dev_priv->page_flipping = 0; dev_priv->page_flipping = 0;
dev_priv->current_page = 0; dev_priv->current_page = 0;
dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page;
return 0; return 0;
} }
...@@ -1585,15 +1596,15 @@ static int radeon_emit_packets( ...@@ -1585,15 +1596,15 @@ static int radeon_emit_packets(
drm_radeon_cmd_header_t header, drm_radeon_cmd_header_t header,
drm_radeon_cmd_buffer_t *cmdbuf ) drm_radeon_cmd_buffer_t *cmdbuf )
{ {
int sz = packet[(int)header.packet.packet_id].len; int id = (int)header.packet.packet_id;
int reg = packet[(int)header.packet.packet_id].start; int sz = packet[id].len;
int reg = packet[id].start;
int *data = (int *)cmdbuf->buf; int *data = (int *)cmdbuf->buf;
RING_LOCALS; RING_LOCALS;
if (sz * sizeof(int) > cmdbuf->bufsz) if (sz * sizeof(int) > cmdbuf->bufsz)
return -EINVAL; return -EINVAL;
BEGIN_RING(sz+1); BEGIN_RING(sz+1);
OUT_RING( CP_PACKET0( reg, (sz-1) ) ); OUT_RING( CP_PACKET0( reg, (sz-1) ) );
OUT_RING_USER_TABLE( data, sz ); OUT_RING_USER_TABLE( data, sz );
......
...@@ -2,6 +2,16 @@ ...@@ -2,6 +2,16 @@
#ifndef _sis_drm_public_h_ #ifndef _sis_drm_public_h_
#define _sis_drm_public_h_ #define _sis_drm_public_h_
/* SiS specific ioctls */
#define SIS_IOCTL_FB_ALLOC DRM_IOWR(0x44, drm_sis_mem_t)
#define SIS_IOCTL_FB_FREE DRM_IOW( 0x45, drm_sis_mem_t)
#define SIS_IOCTL_AGP_INIT DRM_IOWR(0x53, drm_sis_agp_t)
#define SIS_IOCTL_AGP_ALLOC DRM_IOWR(0x54, drm_sis_mem_t)
#define SIS_IOCTL_AGP_FREE DRM_IOW( 0x55, drm_sis_mem_t)
#define SIS_IOCTL_FLIP DRM_IOW( 0x48, drm_sis_flip_t)
#define SIS_IOCTL_FLIP_INIT DRM_IO( 0x49)
#define SIS_IOCTL_FLIP_FINAL DRM_IO( 0x50)
typedef struct { typedef struct {
int context; int context;
unsigned int offset; unsigned int offset;
......
...@@ -66,12 +66,24 @@ ...@@ -66,12 +66,24 @@
* 12/19/98 bv - v1.02a Use spinlocks for 2.1.95 and up * 12/19/98 bv - v1.02a Use spinlocks for 2.1.95 and up
* 01/31/99 bv - v1.02b Use mdelay instead of waitForPause * 01/31/99 bv - v1.02b Use mdelay instead of waitForPause
* 08/08/99 bv - v1.02c Use waitForPause again. * 08/08/99 bv - v1.02c Use waitForPause again.
* 06/25/02 Doug Ledford <dledford@redhat.com> - v1.02d
* - Remove limit on number of controllers
* - Port to DMA mapping API
* - Clean up interrupt handler registration
* - Fix memory leaks
* - Fix allocation of scsi host structs and private data
**************************************************************************/ **************************************************************************/
#include <linux/version.h> #include <linux/version.h>
#include <linux/jiffies.h> #include <linux/module.h>
#include <asm/irq.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <asm/io.h> #include <asm/io.h>
#include "i60uscsi.h" #include <linux/blkdev.h>
#include "scsi.h"
#include "hosts.h"
#include "inia100.h"
#define JIFFIES_TO_MS(t) ((t) * 1000 / HZ) #define JIFFIES_TO_MS(t) ((t) * 1000 / HZ)
#define MS_TO_JIFFIES(j) ((j * HZ) / 1000) #define MS_TO_JIFFIES(j) ((j * HZ) / 1000)
...@@ -98,10 +110,7 @@ ORC_SCB *orc_alloc_scb(ORC_HCS * hcsp); ...@@ -98,10 +110,7 @@ ORC_SCB *orc_alloc_scb(ORC_HCS * hcsp);
extern void inia100SCBPost(BYTE * pHcb, BYTE * pScb); extern void inia100SCBPost(BYTE * pHcb, BYTE * pScb);
/* ---- INTERNAL VARIABLES ---- */ /* ---- INTERNAL VARIABLES ---- */
ORC_HCS orc_hcs[MAX_SUPPORTED_ADAPTERS]; struct inia100_Adpt_Struc *inia100_adpt;
static INIA100_ADPT_STRUCT inia100_adpt[MAX_SUPPORTED_ADAPTERS];
/* set by inia100_setup according to the command line */
int orc_num_scb;
NVRAM nvram, *nvramp = &nvram; NVRAM nvram, *nvramp = &nvram;
static UCHAR dftNvRam[64] = static UCHAR dftNvRam[64] =
...@@ -300,7 +309,7 @@ UCHAR get_NVRAM(ORC_HCS * hcsp, unsigned char address, unsigned char *pDataIn) ...@@ -300,7 +309,7 @@ UCHAR get_NVRAM(ORC_HCS * hcsp, unsigned char address, unsigned char *pDataIn)
/***************************************************************************/ /***************************************************************************/
void orc_exec_scb(ORC_HCS * hcsp, ORC_SCB * scbp) void orc_exec_scb(ORC_HCS * hcsp, ORC_SCB * scbp)
{ {
scbp->SCB_Status = SCB_POST; scbp->SCB_Status = ORCSCB_POST;
ORC_WR(hcsp->HCS_Base + ORC_PQUEUE, scbp->SCB_ScbIdx); ORC_WR(hcsp->HCS_Base + ORC_PQUEUE, scbp->SCB_ScbIdx);
return; return;
} }
...@@ -439,17 +448,11 @@ void setup_SCBs(ORC_HCS * hcsp) ...@@ -439,17 +448,11 @@ void setup_SCBs(ORC_HCS * hcsp)
{ {
ORC_SCB *pVirScb; ORC_SCB *pVirScb;
int i; int i;
UCHAR j;
ESCB *pVirEscb; ESCB *pVirEscb;
PVOID pPhysEscb; dma_addr_t pPhysEscb;
PVOID tPhysEscb;
j = 0;
pVirScb = NULL;
tPhysEscb = (PVOID) NULL;
pPhysEscb = (PVOID) NULL;
/* Setup SCB HCS_Base and SCB Size registers */ /* Setup SCB HCS_Base and SCB Size registers */
ORC_WR(hcsp->HCS_Base + ORC_SCBSIZE, orc_num_scb); /* Total number of SCBs */ ORC_WR(hcsp->HCS_Base + ORC_SCBSIZE, ORC_MAXQUEUE); /* Total number of SCBs */
/* SCB HCS_Base address 0 */ /* SCB HCS_Base address 0 */
ORC_WRLONG(hcsp->HCS_Base + ORC_SCBBASE0, hcsp->HCS_physScbArray); ORC_WRLONG(hcsp->HCS_Base + ORC_SCBBASE0, hcsp->HCS_physScbArray);
/* SCB HCS_Base address 1 */ /* SCB HCS_Base address 1 */
...@@ -459,8 +462,8 @@ void setup_SCBs(ORC_HCS * hcsp) ...@@ -459,8 +462,8 @@ void setup_SCBs(ORC_HCS * hcsp)
pVirScb = (ORC_SCB *) hcsp->HCS_virScbArray; pVirScb = (ORC_SCB *) hcsp->HCS_virScbArray;
pVirEscb = (ESCB *) hcsp->HCS_virEscbArray; pVirEscb = (ESCB *) hcsp->HCS_virEscbArray;
for (i = 0; i < orc_num_scb; i++) { for (i = 0; i < ORC_MAXQUEUE; i++) {
pPhysEscb = (PVOID) (hcsp->HCS_physEscbArray + (sizeof(ESCB) * i)); pPhysEscb = (hcsp->HCS_physEscbArray + (sizeof(ESCB) * i));
pVirScb->SCB_SGPAddr = (U32) pPhysEscb; pVirScb->SCB_SGPAddr = (U32) pPhysEscb;
pVirScb->SCB_SensePAddr = (U32) pPhysEscb; pVirScb->SCB_SensePAddr = (U32) pPhysEscb;
pVirScb->SCB_EScb = pVirEscb; pVirScb->SCB_EScb = pVirEscb;
...@@ -534,7 +537,7 @@ int init_orchid(ORC_HCS * hcsp) ...@@ -534,7 +537,7 @@ int init_orchid(ORC_HCS * hcsp)
readBytep = (UCHAR *) & (nvramp->Target00Config); readBytep = (UCHAR *) & (nvramp->Target00Config);
for (i = 0; i < 16; readBytep++, i++) { for (i = 0; i < 16; readBytep++, i++) {
hcsp->TargetFlag[i] = *readBytep; hcsp->TargetFlag[i] = *readBytep;
hcsp->MaximumTags[i] = orc_num_scb; hcsp->MaximumTags[i] = ORC_MAXTAGS;
} /* for */ } /* for */
if (nvramp->SCSI0Config & NCC_BUSRESET) { /* Reset SCSI bus */ if (nvramp->SCSI0Config & NCC_BUSRESET) { /* Reset SCSI bus */
...@@ -578,7 +581,7 @@ int orc_reset_scsi_bus(ORC_HCS * pHCB) ...@@ -578,7 +581,7 @@ int orc_reset_scsi_bus(ORC_HCS * pHCB)
Output : None. Output : None.
Return : pSRB - Pointer to SCSI request block. Return : pSRB - Pointer to SCSI request block.
*****************************************************************************/ *****************************************************************************/
int orc_device_reset(ORC_HCS * pHCB, ULONG SCpnt, unsigned int target, unsigned int ResetFlags) int orc_device_reset(ORC_HCS * pHCB, Scsi_Cmnd *SCpnt, unsigned int target, unsigned int ResetFlags)
{ /* I need Host Control Block Information */ { /* I need Host Control Block Information */
ORC_SCB *pScb; ORC_SCB *pScb;
ESCB *pVirEscb; ESCB *pVirEscb;
...@@ -595,14 +598,14 @@ int orc_device_reset(ORC_HCS * pHCB, ULONG SCpnt, unsigned int target, unsigned ...@@ -595,14 +598,14 @@ int orc_device_reset(ORC_HCS * pHCB, ULONG SCpnt, unsigned int target, unsigned
initAFlag(pHCB); initAFlag(pHCB);
/* device reset */ /* device reset */
for (i = 0; i < orc_num_scb; i++) { for (i = 0; i < ORC_MAXQUEUE; i++) {
pVirEscb = pVirScb->SCB_EScb; pVirEscb = pVirScb->SCB_EScb;
if ((pVirScb->SCB_Status) && (pVirEscb->SCB_Srb == (unsigned char *) SCpnt)) if ((pVirScb->SCB_Status) && (pVirEscb->SCB_Srb == SCpnt))
break; break;
pVirScb++; pVirScb++;
} }
if (i == orc_num_scb) { if (i == ORC_MAXQUEUE) {
printk("Unable to Reset - No SCB Found\n"); printk("Unable to Reset - No SCB Found\n");
spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags); spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags);
return (SCSI_RESET_NOT_RUNNING); return (SCSI_RESET_NOT_RUNNING);
...@@ -624,7 +627,7 @@ int orc_device_reset(ORC_HCS * pHCB, ULONG SCpnt, unsigned int target, unsigned ...@@ -624,7 +627,7 @@ int orc_device_reset(ORC_HCS * pHCB, ULONG SCpnt, unsigned int target, unsigned
pVirEscb->SCB_Srb = 0; pVirEscb->SCB_Srb = 0;
if (ResetFlags & SCSI_RESET_SYNCHRONOUS) { if (ResetFlags & SCSI_RESET_SYNCHRONOUS) {
pVirEscb->SCB_Srb = (unsigned char *) SCpnt; pVirEscb->SCB_Srb = SCpnt;
} }
orc_exec_scb(pHCB, pScb); /* Start execute SCB */ orc_exec_scb(pHCB, pScb); /* Start execute SCB */
spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags); spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags);
...@@ -640,7 +643,6 @@ ORC_SCB *__orc_alloc_scb(ORC_HCS * hcsp) ...@@ -640,7 +643,6 @@ ORC_SCB *__orc_alloc_scb(ORC_HCS * hcsp)
ULONG idx; ULONG idx;
UCHAR index; UCHAR index;
UCHAR i; UCHAR i;
ULONG flags;
Ch = hcsp->HCS_Index; Ch = hcsp->HCS_Index;
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
...@@ -687,6 +689,22 @@ void orc_release_scb(ORC_HCS * hcsp, ORC_SCB * scbp) ...@@ -687,6 +689,22 @@ void orc_release_scb(ORC_HCS * hcsp, ORC_SCB * scbp)
} }
/***************************************************************************/
void orc_release_dma(ORC_HCS * hcsp, Scsi_Cmnd * SCpnt)
{
struct scatterlist *pSrbSG;
if (SCpnt->use_sg) {
pSrbSG = (struct scatterlist *)SCpnt->request_buffer;
pci_unmap_sg(hcsp->pdev, pSrbSG, SCpnt->use_sg,
scsi_to_pci_dma_dir(SCpnt->sc_data_direction));
} else if (SCpnt->request_bufflen != 0) {
pci_unmap_single(hcsp->pdev, (U32)SCpnt->host_scribble,
SCpnt->request_bufflen,
scsi_to_pci_dma_dir(SCpnt->sc_data_direction));
}
}
/***************************************************************************** /*****************************************************************************
Function name : Addinia100_into_Adapter_table Function name : Addinia100_into_Adapter_table
Description : This function will scan PCI bus to get all Orchid card Description : This function will scan PCI bus to get all Orchid card
...@@ -695,33 +713,29 @@ void orc_release_scb(ORC_HCS * hcsp, ORC_SCB * scbp) ...@@ -695,33 +713,29 @@ void orc_release_scb(ORC_HCS * hcsp, ORC_SCB * scbp)
Return : SUCCESSFUL - Successful scan Return : SUCCESSFUL - Successful scan
ohterwise - No drives founded ohterwise - No drives founded
*****************************************************************************/ *****************************************************************************/
int Addinia100_into_Adapter_table(WORD wBIOS, WORD wBASE, BYTE bInterrupt, int Addinia100_into_Adapter_table(WORD wBIOS, WORD wBASE, struct pci_dev *pdev,
BYTE bBus, BYTE bDevice) int iAdapters)
{ {
unsigned int i, j; unsigned int i, j;
for (i = 0; i < MAX_SUPPORTED_ADAPTERS; i++) { for (i = 0; i < iAdapters; i++) {
if (inia100_adpt[i].ADPT_BIOS < wBIOS) if (inia100_adpt[i].ADPT_BIOS < wBIOS)
continue; continue;
if (inia100_adpt[i].ADPT_BIOS == wBIOS) { if (inia100_adpt[i].ADPT_BIOS == wBIOS) {
if (inia100_adpt[i].ADPT_BASE == wBASE) { if (inia100_adpt[i].ADPT_BASE == wBASE) {
if (inia100_adpt[i].ADPT_Bus != 0xFF) if (inia100_adpt[i].ADPT_pdev->bus->number != 0xFF)
return (FAILURE); return (FAILURE);
} else if (inia100_adpt[i].ADPT_BASE < wBASE) } else if (inia100_adpt[i].ADPT_BASE < wBASE)
continue; continue;
} }
for (j = MAX_SUPPORTED_ADAPTERS - 1; j > i; j--) { for (j = iAdapters - 1; j > i; j--) {
inia100_adpt[j].ADPT_BASE = inia100_adpt[j - 1].ADPT_BASE; inia100_adpt[j].ADPT_BASE = inia100_adpt[j - 1].ADPT_BASE;
inia100_adpt[j].ADPT_INTR = inia100_adpt[j - 1].ADPT_INTR;
inia100_adpt[j].ADPT_BIOS = inia100_adpt[j - 1].ADPT_BIOS; inia100_adpt[j].ADPT_BIOS = inia100_adpt[j - 1].ADPT_BIOS;
inia100_adpt[j].ADPT_Bus = inia100_adpt[j - 1].ADPT_Bus; inia100_adpt[j].ADPT_pdev = inia100_adpt[j - 1].ADPT_pdev;
inia100_adpt[j].ADPT_Device = inia100_adpt[j - 1].ADPT_Device;
} }
inia100_adpt[i].ADPT_BASE = wBASE; inia100_adpt[i].ADPT_BASE = wBASE;
inia100_adpt[i].ADPT_INTR = bInterrupt;
inia100_adpt[i].ADPT_BIOS = wBIOS; inia100_adpt[i].ADPT_BIOS = wBIOS;
inia100_adpt[i].ADPT_Bus = bBus; inia100_adpt[i].ADPT_pdev = pdev;
inia100_adpt[i].ADPT_Device = bDevice;
return (SUCCESSFUL); return (SUCCESSFUL);
} }
return (FAILURE); return (FAILURE);
...@@ -733,20 +747,23 @@ int Addinia100_into_Adapter_table(WORD wBIOS, WORD wBASE, BYTE bInterrupt, ...@@ -733,20 +747,23 @@ int Addinia100_into_Adapter_table(WORD wBIOS, WORD wBASE, BYTE bInterrupt,
Description : This function will scan PCI bus to get all Orchid card Description : This function will scan PCI bus to get all Orchid card
Input : None. Input : None.
Output : None. Output : None.
Return : SUCCESSFUL - Successful scan Return : 0 on success, 1 on failure
ohterwise - No drives founded
*****************************************************************************/ *****************************************************************************/
void init_inia100Adapter_table(void) int init_inia100Adapter_table(int iAdapters)
{ {
int i; int i;
for (i = 0; i < MAX_SUPPORTED_ADAPTERS; i++) { /* Initialize adapter structure */ inia100_adpt = kmalloc(sizeof(INIA100_ADPT_STRUCT) * iAdapters,
GFP_KERNEL);
if(inia100_adpt == NULL)
return 1;
for (i = 0; i < iAdapters; i++) {/* Initialize adapter structure */
inia100_adpt[i].ADPT_BIOS = 0xffff; inia100_adpt[i].ADPT_BIOS = 0xffff;
inia100_adpt[i].ADPT_BASE = 0xffff; inia100_adpt[i].ADPT_BASE = 0xffff;
inia100_adpt[i].ADPT_INTR = 0xff; inia100_adpt[i].ADPT_pdev = NULL;
inia100_adpt[i].ADPT_Bus = 0xff;
inia100_adpt[i].ADPT_Device = 0xff;
} }
return 0;
} }
/***************************************************************************** /*****************************************************************************
...@@ -760,7 +777,7 @@ void get_orcPCIConfig(ORC_HCS * pCurHcb, int ch_idx) ...@@ -760,7 +777,7 @@ void get_orcPCIConfig(ORC_HCS * pCurHcb, int ch_idx)
{ {
pCurHcb->HCS_Base = inia100_adpt[ch_idx].ADPT_BASE; /* Supply base address */ pCurHcb->HCS_Base = inia100_adpt[ch_idx].ADPT_BASE; /* Supply base address */
pCurHcb->HCS_BIOS = inia100_adpt[ch_idx].ADPT_BIOS; /* Supply BIOS address */ pCurHcb->HCS_BIOS = inia100_adpt[ch_idx].ADPT_BIOS; /* Supply BIOS address */
pCurHcb->HCS_Intr = inia100_adpt[ch_idx].ADPT_INTR; /* Supply interrupt line */ pCurHcb->HCS_Intr = inia100_adpt[ch_idx].ADPT_pdev->irq; /* Supply interrupt line */
return; return;
} }
...@@ -805,7 +822,7 @@ int abort_SCB(ORC_HCS * hcsp, ORC_SCB * pScb) ...@@ -805,7 +822,7 @@ int abort_SCB(ORC_HCS * hcsp, ORC_SCB * pScb)
Output : None. Output : None.
Return : pSRB - Pointer to SCSI request block. Return : pSRB - Pointer to SCSI request block.
*****************************************************************************/ *****************************************************************************/
int orc_abort_srb(ORC_HCS * hcsp, ULONG SCpnt) int orc_abort_srb(ORC_HCS * hcsp, Scsi_Cmnd *SCpnt)
{ {
ESCB *pVirEscb; ESCB *pVirEscb;
ORC_SCB *pVirScb; ORC_SCB *pVirScb;
...@@ -816,9 +833,9 @@ int orc_abort_srb(ORC_HCS * hcsp, ULONG SCpnt) ...@@ -816,9 +833,9 @@ int orc_abort_srb(ORC_HCS * hcsp, ULONG SCpnt)
pVirScb = (ORC_SCB *) hcsp->HCS_virScbArray; pVirScb = (ORC_SCB *) hcsp->HCS_virScbArray;
for (i = 0; i < orc_num_scb; i++, pVirScb++) { for (i = 0; i < ORC_MAXQUEUE; i++, pVirScb++) {
pVirEscb = pVirScb->SCB_EScb; pVirEscb = pVirScb->SCB_EScb;
if ((pVirScb->SCB_Status) && (pVirEscb->SCB_Srb == (unsigned char *) SCpnt)) { if ((pVirScb->SCB_Status) && (pVirEscb->SCB_Srb == SCpnt)) {
if (pVirScb->SCB_TagMsg == 0) { if (pVirScb->SCB_TagMsg == 0) {
spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags); spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags);
return (SCSI_ABORT_BUSY); return (SCSI_ABORT_BUSY);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -141,6 +141,19 @@ static struct fb_var_screeninfo vesafb_defined = { ...@@ -141,6 +141,19 @@ static struct fb_var_screeninfo vesafb_defined = {
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
static inline void my_install_cmap(WPMINFO2)
{
/* Do not touch this code if you do not understand what it does! */
/* Never try to use do_install_cmap() instead. It is crap. */
struct fb_cmap* cmap = &ACCESS_FBINFO(currcon_display)->cmap;
if (cmap->len)
fb_set_cmap(cmap, 1, &ACCESS_FBINFO(fbcon));
else
fb_set_cmap(fb_default_cmap(ACCESS_FBINFO(curr.cmap_len)),
1, &ACCESS_FBINFO(fbcon));
}
static void matrox_pan_var(WPMINFO struct fb_var_screeninfo *var) { static void matrox_pan_var(WPMINFO struct fb_var_screeninfo *var) {
unsigned int pos; unsigned int pos;
...@@ -869,7 +882,7 @@ static int matroxfb_set_var(struct fb_var_screeninfo *var, int con, ...@@ -869,7 +882,7 @@ static int matroxfb_set_var(struct fb_var_screeninfo *var, int con,
up_read(&ACCESS_FBINFO(altout.lock)); up_read(&ACCESS_FBINFO(altout.lock));
} }
matrox_cfbX_init(PMINFO display); matrox_cfbX_init(PMINFO display);
do_install_cmap(ACCESS_FBINFO(fbcon.currcon),&ACCESS_FBINFO(fbcon)); my_install_cmap(PMINFO2);
#if defined(CONFIG_FB_COMPAT_XPMAC) #if defined(CONFIG_FB_COMPAT_XPMAC)
if (console_fb_info == &ACCESS_FBINFO(fbcon)) { if (console_fb_info == &ACCESS_FBINFO(fbcon)) {
int vmode, cmode; int vmode, cmode;
......
...@@ -29,7 +29,7 @@ MODULE_PARM_DESC(mem, "Memory size reserved for dualhead (default=8MB)"); ...@@ -29,7 +29,7 @@ MODULE_PARM_DESC(mem, "Memory size reserved for dualhead (default=8MB)");
static int matroxfb_dh_getcolreg(unsigned regno, unsigned *red, unsigned *green, static int matroxfb_dh_getcolreg(unsigned regno, unsigned *red, unsigned *green,
unsigned *blue, unsigned *transp, struct fb_info* info) { unsigned *blue, unsigned *transp, struct fb_info* info) {
#define m2info ((struct matroxfb_dh_fb_info*)info) #define m2info ((struct matroxfb_dh_fb_info*)info)
if (regno > 16) if (regno >= 16)
return 1; return 1;
*red = m2info->palette[regno].red; *red = m2info->palette[regno].red;
*blue = m2info->palette[regno].blue; *blue = m2info->palette[regno].blue;
...@@ -44,7 +44,7 @@ static int matroxfb_dh_setcolreg(unsigned regno, unsigned red, unsigned green, ...@@ -44,7 +44,7 @@ static int matroxfb_dh_setcolreg(unsigned regno, unsigned red, unsigned green,
#define m2info ((struct matroxfb_dh_fb_info*)info) #define m2info ((struct matroxfb_dh_fb_info*)info)
struct display* p; struct display* p;
if (regno > 16) if (regno >= 16)
return 1; return 1;
m2info->palette[regno].red = red; m2info->palette[regno].red = red;
m2info->palette[regno].blue = blue; m2info->palette[regno].blue = blue;
...@@ -84,6 +84,19 @@ static int matroxfb_dh_setcolreg(unsigned regno, unsigned red, unsigned green, ...@@ -84,6 +84,19 @@ static int matroxfb_dh_setcolreg(unsigned regno, unsigned red, unsigned green,
#undef m2info #undef m2info
} }
static inline void my_install_cmap(struct matroxfb_dh_fb_info* m2info)
{
/* Do not touch this code if you do not understand what it does! */
/* Never try to use do_install_cmap() instead. It is crap. */
struct fb_cmap* cmap = &m2info->currcon_display->cmap;
if (cmap->len)
fb_set_cmap(cmap, 1, &m2info->fbcon);
else
fb_set_cmap(fb_default_cmap(16), 1, &m2info->fbcon);
}
static void matroxfb_dh_restore(struct matroxfb_dh_fb_info* m2info, static void matroxfb_dh_restore(struct matroxfb_dh_fb_info* m2info,
struct my_timming* mt, struct my_timming* mt,
struct display* p, struct display* p,
...@@ -439,7 +452,7 @@ static int matroxfb_dh_set_var(struct fb_var_screeninfo* var, int con, ...@@ -439,7 +452,7 @@ static int matroxfb_dh_set_var(struct fb_var_screeninfo* var, int con,
up_read(&ACCESS_FBINFO(altout.lock)); up_read(&ACCESS_FBINFO(altout.lock));
} }
matroxfb_dh_cfbX_init(m2info, p); matroxfb_dh_cfbX_init(m2info, p);
do_install_cmap(ACCESS_FBINFO(fbcon.currcon), &ACCESS_FBINFO(fbcon)); my_install_cmap(m2info);
} }
return 0; return 0;
#undef m2info #undef m2info
......
...@@ -1124,14 +1124,10 @@ static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file) ...@@ -1124,14 +1124,10 @@ static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file)
psinfo.pr_ppid = prstatus.pr_ppid = current->parent->pid; psinfo.pr_ppid = prstatus.pr_ppid = current->parent->pid;
psinfo.pr_pgrp = prstatus.pr_pgrp = current->pgrp; psinfo.pr_pgrp = prstatus.pr_pgrp = current->pgrp;
psinfo.pr_sid = prstatus.pr_sid = current->session; psinfo.pr_sid = prstatus.pr_sid = current->session;
prstatus.pr_utime.tv_sec = CT_TO_SECS(current->times.tms_utime); jiffies_to_timeval(current->utime, &prstatus.pr_utime);
prstatus.pr_utime.tv_usec = CT_TO_USECS(current->times.tms_utime); jiffies_to_timeval(current->stime, &prstatus.pr_stime);
prstatus.pr_stime.tv_sec = CT_TO_SECS(current->times.tms_stime); jiffies_to_timeval(current->cutime, &prstatus.pr_cutime);
prstatus.pr_stime.tv_usec = CT_TO_USECS(current->times.tms_stime); jiffies_to_timeval(current->cstime, &prstatus.pr_cstime);
prstatus.pr_cutime.tv_sec = CT_TO_SECS(current->times.tms_cutime);
prstatus.pr_cutime.tv_usec = CT_TO_USECS(current->times.tms_cutime);
prstatus.pr_cstime.tv_sec = CT_TO_SECS(current->times.tms_cstime);
prstatus.pr_cstime.tv_usec = CT_TO_USECS(current->times.tms_cstime);
#ifdef DEBUG #ifdef DEBUG
dump_regs("Passed in regs", (elf_greg_t *)regs); dump_regs("Passed in regs", (elf_greg_t *)regs);
......
...@@ -6,7 +6,7 @@ ToDo: ...@@ -6,7 +6,7 @@ ToDo:
user open()s a file with i_size > s_maxbytes? Should read_inode() user open()s a file with i_size > s_maxbytes? Should read_inode()
truncate the visible i_size? Will the user just get -E2BIG (or truncate the visible i_size? Will the user just get -E2BIG (or
whatever) on open()? Or will (s)he be able to open() but lseek() and whatever) on open()? Or will (s)he be able to open() but lseek() and
read() will fail when s_maxbytes is reached? -> Investigate this! read() will fail when s_maxbytes is reached? -> Investigate this.
- Implement/allow non-resident index bitmaps in dir.c::ntfs_readdir() - Implement/allow non-resident index bitmaps in dir.c::ntfs_readdir()
and then also consider initialized_size w.r.t. the bitmaps, etc. and then also consider initialized_size w.r.t. the bitmaps, etc.
- vcn_to_lcn() should somehow return the correct pointer within the - vcn_to_lcn() should somehow return the correct pointer within the
...@@ -17,11 +17,67 @@ ToDo: ...@@ -17,11 +17,67 @@ ToDo:
- Consider if ntfs_file_read_compressed_block() shouldn't be coping - Consider if ntfs_file_read_compressed_block() shouldn't be coping
with initialized_size < data_size. I don't think it can happen but with initialized_size < data_size. I don't think it can happen but
it requires more careful consideration. it requires more careful consideration.
- CLEANUP: Modularise and reuse code in aops.c. At the moment we have - CLEANUP: At the moment we have two copies of almost identical
several copies of almost identicall functions and the functions are functions in aops.c, can merge them once fake inode address space
quite big. Modularising them a bit, e.g. a-la get_block(), will make based attribute i/o is further developed.
them cleaner and make code reuse easier. - CLEANUP: Modularising code in aops.c a bit, e.g. a-la get_block(),
- Want to use dummy inodes for address space i/o. will be cleaner and make code reuse easier.
- Modify ntfs_read_locked_inode() to return an error code and update
callers, i.e. ntfs_iget(), to pass that error code up instead of just
using -EIO.
- Enable NFS exporting of NTFS.
- Use fake inodes for address space i/o.
2.0.13 - Use iget5_locked() in preparation for fake inodes and small cleanups.
- Remove nr_mft_bits and the now superfluous union with nr_mft_records
from ntfs_volume structure.
- Remove nr_lcn_bits and the now superfluous union with nr_clusters
from ntfs_volume structure.
- Use iget5_locked() and friends instead of conventional iget(). Wrap
the call in fs/ntfs/inode.c::ntfs_iget() and update callers of iget()
to use ntfs_iget(). Leave only one iget() call at mount time so we
don't need an ntfs_iget_mount().
- Change fs/ntfs/inode.c::ntfs_new_extent_inode() to take mft_no as an
additional argument.
2.0.12 - Initial cleanup of address space operations following 2.0.11 changes.
- Merge fs/ntfs/aops.c::end_buffer_read_mst_async() and
fs/ntfs/aops.c::end_buffer_read_file_async() into one function
fs/ntfs/aops.c::end_buffer_read_attr_async() using NInoMstProtected()
to determine whether to apply mst fixups or not.
- Above change allows merging fs/ntfs/aops.c::ntfs_file_read_block()
and fs/ntfs/aops.c::ntfs_mst_readpage() into one function
fs/ntfs/aops.c::ntfs_attr_read_block(). Also, create a tiny wrapper
fs/ntfs/aops.c::ntfs_mst_readpage() to transform the parameters from
the VFS readpage function prototype to the ntfs_attr_read_block()
function prototype.
2.0.11 - Initial preparations for fake inode based attribute i/o.
- Move definition of ntfs_inode_state_bits to fs/ntfs/inode.h and
do some macro magic (adapted from include/linux/buffer_head.h) to
expand all the helper functions NInoFoo(), NInoSetFoo(), and
NInoClearFoo().
- Add new flag to ntfs_inode_state_bits: NI_Sparse.
- Add new fields to ntfs_inode structure to allow use of fake inodes
for attribute i/o: type, name, name_len. Also add new state bits:
NI_Attr, which, if set, indicates the inode is a fake inode, and
NI_MstProtected, which, if set, indicates the attribute uses multi
sector transfer protection, i.e. fixups need to be applied after
reads and before/after writes.
- Rename fs/ntfs/inode.c::ntfs_{new,clear,destroy}_inode() to
ntfs_{new,clear,destroy}_extent_inode() and update callers.
- Use ntfs_clear_extent_inode() in fs/ntfs/inode.c::__ntfs_clear_inode()
instead of ntfs_destroy_extent_inode().
- Cleanup memory deallocations in {__,}ntfs_clear_{,big_}inode().
- Make all operations on ntfs inode state bits use the NIno* functions.
- Set up the new ntfs inode fields and state bits in
fs/ntfs/inode.c::ntfs_read_inode() and add appropriate cleanup of
allocated memory to __ntfs_clear_inode().
- Cleanup ntfs_inode structure a bit for better ordering of elements
w.r.t. their size to allow better packing of the structure in memory.
2.0.10 - There can only be 2^32 - 1 inodes on an NTFS volume. 2.0.10 - There can only be 2^32 - 1 inodes on an NTFS volume.
...@@ -38,7 +94,10 @@ ToDo: ...@@ -38,7 +94,10 @@ ToDo:
- Change decompression engine to use a single buffer protected by a - Change decompression engine to use a single buffer protected by a
spin lock instead of per-CPU buffers. (Rusty Russell) spin lock instead of per-CPU buffers. (Rusty Russell)
- Switch to using the new KM_BIO_SRC_IRQ for atomic kmaps. (Andrew - Do not update cb_pos when handling a partial final page during
decompression of a sparse compression block, as the value is later
reset without being read/used. (Rusty Russell)
- Switch to using the new KM_BIO_SRC_IRQ for atomic kmap()s. (Andrew
Morton) Morton)
- Change buffer size in ntfs_readdir()/ntfs_filldir() to use - Change buffer size in ntfs_readdir()/ntfs_filldir() to use
NLS_MAX_CHARSET_SIZE which makes the buffers almost 1kiB each but NLS_MAX_CHARSET_SIZE which makes the buffers almost 1kiB each but
......
...@@ -5,7 +5,7 @@ obj-$(CONFIG_NTFS_FS) += ntfs.o ...@@ -5,7 +5,7 @@ obj-$(CONFIG_NTFS_FS) += ntfs.o
ntfs-objs := aops.o attrib.o compress.o debug.o dir.o file.o inode.o mft.o \ ntfs-objs := aops.o attrib.o compress.o debug.o dir.o file.o inode.o mft.o \
mst.o namei.o super.o sysctl.o time.o unistr.o upcase.o mst.o namei.o super.o sysctl.o time.o unistr.o upcase.o
EXTRA_CFLAGS = -DNTFS_VERSION=\"2.0.10\" EXTRA_CFLAGS = -DNTFS_VERSION=\"2.0.13\"
ifeq ($(CONFIG_NTFS_DEBUG),y) ifeq ($(CONFIG_NTFS_DEBUG),y)
EXTRA_CFLAGS += -DDEBUG EXTRA_CFLAGS += -DDEBUG
......
This diff is collapsed.
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
/** /**
* The little endian Unicode string $I30 as a global constant. * The little endian Unicode string $I30 as a global constant.
*/ */
const uchar_t I30[5] = { const_cpu_to_le16('$'), const_cpu_to_le16('I'), uchar_t I30[5] = { const_cpu_to_le16('$'), const_cpu_to_le16('I'),
const_cpu_to_le16('3'), const_cpu_to_le16('0'), const_cpu_to_le16('3'), const_cpu_to_le16('0'),
const_cpu_to_le16(0) }; const_cpu_to_le16(0) };
......
...@@ -38,7 +38,7 @@ typedef struct { ...@@ -38,7 +38,7 @@ typedef struct {
} __attribute__ ((__packed__)) ntfs_name; } __attribute__ ((__packed__)) ntfs_name;
/* The little endian Unicode string $I30 as a global constant. */ /* The little endian Unicode string $I30 as a global constant. */
extern const uchar_t I30[5]; extern uchar_t I30[5];
extern MFT_REF ntfs_lookup_inode_by_name(ntfs_inode *dir_ni, extern MFT_REF ntfs_lookup_inode_by_name(ntfs_inode *dir_ni,
const uchar_t *uname, const int uname_len, ntfs_name **res); const uchar_t *uname, const int uname_len, ntfs_name **res);
......
This diff is collapsed.
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* the Linux-NTFS project. * the Linux-NTFS project.
* *
* Copyright (c) 2001,2002 Anton Altaparmakov. * Copyright (c) 2001,2002 Anton Altaparmakov.
* Copyright (C) 2002 Richard Russon. * Copyright (c) 2002 Richard Russon.
* *
* This program/include file is free software; you can redistribute it and/or * This program/include file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published * modify it under the terms of the GNU General Public License as published
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include "layout.h"
#include "volume.h" #include "volume.h"
typedef struct _ntfs_inode ntfs_inode; typedef struct _ntfs_inode ntfs_inode;
...@@ -38,21 +39,39 @@ struct _ntfs_inode { ...@@ -38,21 +39,39 @@ struct _ntfs_inode {
s64 initialized_size; /* Copy from $DATA/$INDEX_ALLOCATION. */ s64 initialized_size; /* Copy from $DATA/$INDEX_ALLOCATION. */
s64 allocated_size; /* Copy from $DATA/$INDEX_ALLOCATION. */ s64 allocated_size; /* Copy from $DATA/$INDEX_ALLOCATION. */
unsigned long state; /* NTFS specific flags describing this inode. unsigned long state; /* NTFS specific flags describing this inode.
See fs/ntfs/ntfs.h:ntfs_inode_state_bits. */ See ntfs_inode_state_bits below. */
unsigned long mft_no; /* Number of the mft record / inode. */ unsigned long mft_no; /* Number of the mft record / inode. */
u16 seq_no; /* Sequence number of the mft record. */ u16 seq_no; /* Sequence number of the mft record. */
atomic_t count; /* Inode reference count for book keeping. */ atomic_t count; /* Inode reference count for book keeping. */
ntfs_volume *vol; /* Pointer to the ntfs volume of this inode. */ ntfs_volume *vol; /* Pointer to the ntfs volume of this inode. */
/*
* If NInoAttr() is true, the below fields describe the attribute which
* this fake inode belongs to. The actual inode of this attribute is
* pointed to by base_ntfs_ino and nr_extents is always set to -1 (see
* below). For real inodes, we also set the type (AT_DATA for files and
* AT_INDEX_ALLOCATION for directories), with the name = NULL and
* name_len = 0 for files and name = I30 (global constant) and
* name_len = 4 for directories.
*/
ATTR_TYPES type; /* Attribute type of this fake inode. */
uchar_t *name; /* Attribute name of this fake inode. */
u32 name_len; /* Attribute name length of this fake inode. */
run_list run_list; /* If state has the NI_NonResident bit set, run_list run_list; /* If state has the NI_NonResident bit set,
the run list of the unnamed data attribute the run list of the unnamed data attribute
(if a file) or of the index allocation (if a file) or of the index allocation
attribute (directory). If run_list.rl is attribute (directory) or of the attribute
NULL, the run list has not been read in or described by the fake inode (if NInoAttr()).
has been unmapped. If NI_NonResident is If run_list.rl is NULL, the run list has not
clear, the unnamed data attribute is been read in yet or has been unmapped. If
resident (file) or there is no $I30 index NI_NonResident is clear, the attribute is
allocation attribute (directory). In that resident (file and fake inode) or there is
case run_list.rl is always NULL.*/ no $I30 index allocation attribute
(small directory). In the latter case
run_list.rl is always NULL.*/
/*
* The following fields are only valid for real inodes and extent
* inodes.
*/
struct rw_semaphore mrec_lock; /* Lock for serializing access to the struct rw_semaphore mrec_lock; /* Lock for serializing access to the
mft record belonging to this inode. */ mft record belonging to this inode. */
atomic_t mft_count; /* Mapping reference count for book keeping. */ atomic_t mft_count; /* Mapping reference count for book keeping. */
...@@ -74,17 +93,18 @@ struct _ntfs_inode { ...@@ -74,17 +93,18 @@ struct _ntfs_inode {
union { union {
struct { /* It is a directory or $MFT. */ struct { /* It is a directory or $MFT. */
u32 index_block_size; /* Size of an index block. */ u32 index_block_size; /* Size of an index block. */
u8 index_block_size_bits; /* Log2 of the above. */
u32 index_vcn_size; /* Size of a vcn in this u32 index_vcn_size; /* Size of a vcn in this
directory index. */ directory index. */
u8 index_vcn_size_bits; /* Log2 of the above. */
s64 bmp_size; /* Size of the $I30 bitmap. */ s64 bmp_size; /* Size of the $I30 bitmap. */
s64 bmp_initialized_size; /* Copy from $I30 bitmap. */ s64 bmp_initialized_size; /* Copy from $I30 bitmap. */
s64 bmp_allocated_size; /* Copy from $I30 bitmap. */ s64 bmp_allocated_size; /* Copy from $I30 bitmap. */
run_list bmp_rl; /* Run list for the $I30 bitmap run_list bmp_rl; /* Run list for the $I30 bitmap
if it is non-resident. */ if it is non-resident. */
u8 index_block_size_bits; /* Log2 of the above. */
u8 index_vcn_size_bits; /* Log2 of the above. */
} SN(idm); } SN(idm);
struct { /* It is a compressed file. */ struct { /* It is a compressed file or fake inode. */
s64 compressed_size; /* Copy from $DATA. */
u32 compression_block_size; /* Size of a compression u32 compression_block_size; /* Size of a compression
block (cb). */ block (cb). */
u8 compression_block_size_bits; /* Log2 of the size of u8 compression_block_size_bits; /* Log2 of the size of
...@@ -92,13 +112,13 @@ struct _ntfs_inode { ...@@ -92,13 +112,13 @@ struct _ntfs_inode {
u8 compression_block_clusters; /* Number of clusters u8 compression_block_clusters; /* Number of clusters
per compression per compression
block. */ block. */
s64 compressed_size; /* Copy from $DATA. */
} SN(icf); } SN(icf);
} SN(idc); } SN(idc);
struct semaphore extent_lock; /* Lock for accessing/modifying the struct semaphore extent_lock; /* Lock for accessing/modifying the
below . */ below . */
s32 nr_extents; /* For a base mft record, the number of attached extent s32 nr_extents; /* For a base mft record, the number of attached extent
inodes (0 if none), for extent records this is -1. */ inodes (0 if none), for extent records and for fake
inodes describing an attribute this is -1. */
union { /* This union is only used if nr_extents != 0. */ union { /* This union is only used if nr_extents != 0. */
ntfs_inode **extent_ntfs_inos; /* For nr_extents > 0, array of ntfs_inode **extent_ntfs_inos; /* For nr_extents > 0, array of
the ntfs inodes of the extent the ntfs inodes of the extent
...@@ -107,7 +127,9 @@ struct _ntfs_inode { ...@@ -107,7 +127,9 @@ struct _ntfs_inode {
been loaded. */ been loaded. */
ntfs_inode *base_ntfs_ino; /* For nr_extents == -1, the ntfs_inode *base_ntfs_ino; /* For nr_extents == -1, the
ntfs inode of the base mft ntfs inode of the base mft
record. */ record. For fake inodes, the
real (base) inode to which
the attribute belongs. */
} SN(ine); } SN(ine);
}; };
...@@ -115,6 +137,79 @@ struct _ntfs_inode { ...@@ -115,6 +137,79 @@ struct _ntfs_inode {
#define _ICF(X) SC(idc.icf,X) #define _ICF(X) SC(idc.icf,X)
#define _INE(X) SC(ine,X) #define _INE(X) SC(ine,X)
/*
* Defined bits for the state field in the ntfs_inode structure.
* (f) = files only, (d) = directories only, (a) = attributes/fake inodes only
*/
typedef enum {
NI_Dirty, /* 1: Mft record needs to be written to disk. */
NI_AttrList, /* 1: Mft record contains an attribute list. */
NI_AttrListNonResident, /* 1: Attribute list is non-resident. Implies
NI_AttrList is set. */
NI_Attr, /* 1: Fake inode for attribute i/o.
0: Real inode or extent inode. */
NI_MstProtected, /* 1: Attribute is protected by MST fixups.
0: Attribute is not protected by fixups. */
NI_NonResident, /* 1: Unnamed data attr is non-resident (f).
1: Attribute is non-resident (a). */
NI_IndexAllocPresent = NI_NonResident, /* 1: $I30 index alloc attr is
present (d). */
NI_Compressed, /* 1: Unnamed data attr is compressed (f).
1: Create compressed files by default (d).
1: Attribute is compressed (a). */
NI_Encrypted, /* 1: Unnamed data attr is encrypted (f).
1: Create encrypted files by default (d).
1: Attribute is encrypted (a). */
NI_Sparse, /* 1: Unnamed data attr is sparse (f).
1: Create sparse files by default (d).
1: Attribute is sparse (a). */
NI_BmpNonResident, /* 1: $I30 bitmap attr is non resident (d). */
} ntfs_inode_state_bits;
/*
* NOTE: We should be adding dirty mft records to a list somewhere and they
* should be independent of the (ntfs/vfs) inode structure so that an inode can
* be removed but the record can be left dirty for syncing later.
*/
/*
* Macro tricks to expand the NInoFoo(), NInoSetFoo(), and NInoClearFoo()
* functions.
*/
#define NINO_FNS(flag) \
static inline int NIno##flag(ntfs_inode *ni) \
{ \
return test_bit(NI_##flag, &(ni)->state); \
} \
static inline void NInoSet##flag(ntfs_inode *ni) \
{ \
set_bit(NI_##flag, &(ni)->state); \
} \
static inline void NInoClear##flag(ntfs_inode *ni) \
{ \
clear_bit(NI_##flag, &(ni)->state); \
}
/* Emit the ntfs inode bitops functions. */
NINO_FNS(Dirty)
NINO_FNS(AttrList)
NINO_FNS(AttrListNonResident)
NINO_FNS(Attr)
NINO_FNS(MstProtected)
NINO_FNS(NonResident)
NINO_FNS(IndexAllocPresent)
NINO_FNS(Compressed)
NINO_FNS(Encrypted)
NINO_FNS(Sparse)
NINO_FNS(BmpNonResident)
/*
* The full structure containing a ntfs_inode and a vfs struct inode. Used for
* all real and fake inodes but not for extent inodes which lack the vfs struct
* inode.
*/
typedef struct { typedef struct {
ntfs_inode ntfs_inode; ntfs_inode ntfs_inode;
struct inode vfs_inode; /* The vfs inode structure. */ struct inode vfs_inode; /* The vfs inode structure. */
...@@ -136,14 +231,16 @@ static inline struct inode *VFS_I(ntfs_inode *ni) ...@@ -136,14 +231,16 @@ static inline struct inode *VFS_I(ntfs_inode *ni)
return &((big_ntfs_inode*)ni)->vfs_inode; return &((big_ntfs_inode*)ni)->vfs_inode;
} }
extern struct inode *ntfs_iget(struct super_block *sb, unsigned long mft_no);
extern struct inode *ntfs_alloc_big_inode(struct super_block *sb); extern struct inode *ntfs_alloc_big_inode(struct super_block *sb);
extern void ntfs_destroy_big_inode(struct inode *inode); extern void ntfs_destroy_big_inode(struct inode *inode);
extern void ntfs_clear_big_inode(struct inode *vi); extern void ntfs_clear_big_inode(struct inode *vi);
extern ntfs_inode *ntfs_new_inode(struct super_block *sb); extern ntfs_inode *ntfs_new_extent_inode(struct super_block *sb,
extern void ntfs_clear_inode(ntfs_inode *ni); unsigned long mft_no);
extern void ntfs_clear_extent_inode(ntfs_inode *ni);
extern void ntfs_read_inode(struct inode *vi);
extern void ntfs_read_inode_mount(struct inode *vi); extern void ntfs_read_inode_mount(struct inode *vi);
extern void ntfs_dirty_inode(struct inode *vi); extern void ntfs_dirty_inode(struct inode *vi);
......
...@@ -102,7 +102,7 @@ extern int ntfs_mst_readpage(struct file *, struct page *); ...@@ -102,7 +102,7 @@ extern int ntfs_mst_readpage(struct file *, struct page *);
* ntfs_mft_aops - address space operations for access to $MFT * ntfs_mft_aops - address space operations for access to $MFT
* *
* Address space operations for access to $MFT. This allows us to simply use * Address space operations for access to $MFT. This allows us to simply use
* read_cache_page() in map_mft_record(). * ntfs_map_page() in map_mft_record_page().
*/ */
struct address_space_operations ntfs_mft_aops = { struct address_space_operations ntfs_mft_aops = {
writepage: NULL, /* Write dirty page to disk. */ writepage: NULL, /* Write dirty page to disk. */
...@@ -334,9 +334,9 @@ void unmap_mft_record(const int rw, ntfs_inode *ni) ...@@ -334,9 +334,9 @@ void unmap_mft_record(const int rw, ntfs_inode *ni)
/* /*
* If pure ntfs_inode, i.e. no vfs inode attached, we leave it to * If pure ntfs_inode, i.e. no vfs inode attached, we leave it to
* ntfs_clear_inode() in the extent inode case, and to the caller in * ntfs_clear_extent_inode() in the extent inode case, and to the
* the non-extent, yet pure ntfs inode case, to do the actual tear * caller in the non-extent, yet pure ntfs inode case, to do the actual
* down of all structures and freeing of all allocated memory. * tear down of all structures and freeing of all allocated memory.
*/ */
return; return;
} }
...@@ -417,14 +417,13 @@ MFT_RECORD *map_extent_mft_record(ntfs_inode *base_ni, MFT_REF mref, ...@@ -417,14 +417,13 @@ MFT_RECORD *map_extent_mft_record(ntfs_inode *base_ni, MFT_REF mref,
return m; return m;
} }
/* Record wasn't there. Get a new ntfs inode and initialize it. */ /* Record wasn't there. Get a new ntfs inode and initialize it. */
ni = ntfs_new_inode(base_ni->vol->sb); ni = ntfs_new_extent_inode(base_ni->vol->sb, mft_no);
if (!ni) { if (!ni) {
up(&base_ni->extent_lock); up(&base_ni->extent_lock);
atomic_dec(&base_ni->count); atomic_dec(&base_ni->count);
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
} }
ni->vol = base_ni->vol; ni->vol = base_ni->vol;
ni->mft_no = mft_no;
ni->seq_no = seq_no; ni->seq_no = seq_no;
ni->nr_extents = -1; ni->nr_extents = -1;
ni->_INE(base_ntfs_ino) = base_ni; ni->_INE(base_ntfs_ino) = base_ni;
...@@ -433,7 +432,7 @@ MFT_RECORD *map_extent_mft_record(ntfs_inode *base_ni, MFT_REF mref, ...@@ -433,7 +432,7 @@ MFT_RECORD *map_extent_mft_record(ntfs_inode *base_ni, MFT_REF mref,
if (IS_ERR(m)) { if (IS_ERR(m)) {
up(&base_ni->extent_lock); up(&base_ni->extent_lock);
atomic_dec(&base_ni->count); atomic_dec(&base_ni->count);
ntfs_clear_inode(ni); ntfs_clear_extent_inode(ni);
goto map_err_out; goto map_err_out;
} }
/* Verify the sequence number. */ /* Verify the sequence number. */
...@@ -479,7 +478,7 @@ MFT_RECORD *map_extent_mft_record(ntfs_inode *base_ni, MFT_REF mref, ...@@ -479,7 +478,7 @@ MFT_RECORD *map_extent_mft_record(ntfs_inode *base_ni, MFT_REF mref,
* release it or we will leak memory. * release it or we will leak memory.
*/ */
if (destroy_ni) if (destroy_ni)
ntfs_clear_inode(ni); ntfs_clear_extent_inode(ni);
return m; return m;
} }
...@@ -38,8 +38,8 @@ ...@@ -38,8 +38,8 @@
* supplying the name of the inode in @dent->d_name.name. ntfs_lookup() * supplying the name of the inode in @dent->d_name.name. ntfs_lookup()
* converts the name to Unicode and walks the contents of the directory inode * converts the name to Unicode and walks the contents of the directory inode
* @dir_ino looking for the converted Unicode name. If the name is found in the * @dir_ino looking for the converted Unicode name. If the name is found in the
* directory, the corresponding inode is loaded by calling iget() on its inode * directory, the corresponding inode is loaded by calling ntfs_iget() on its
* number and the inode is associated with the dentry @dent via a call to * inode number and the inode is associated with the dentry @dent via a call to
* d_add(). * d_add().
* *
* If the name is not found in the directory, a NULL inode is inserted into the * If the name is not found in the directory, a NULL inode is inserted into the
...@@ -111,9 +111,9 @@ static struct dentry *ntfs_lookup(struct inode *dir_ino, struct dentry *dent) ...@@ -111,9 +111,9 @@ static struct dentry *ntfs_lookup(struct inode *dir_ino, struct dentry *dent)
kmem_cache_free(ntfs_name_cache, uname); kmem_cache_free(ntfs_name_cache, uname);
if (!IS_ERR_MREF(mref)) { if (!IS_ERR_MREF(mref)) {
dent_ino = MREF(mref); dent_ino = MREF(mref);
ntfs_debug("Found inode 0x%lx. Calling iget.", dent_ino); ntfs_debug("Found inode 0x%lx. Calling ntfs_iget.", dent_ino);
dent_inode = iget(vol->sb, dent_ino); dent_inode = ntfs_iget(vol->sb, dent_ino);
if (dent_inode) { if (likely(!IS_ERR(dent_inode))) {
/* Consistency check. */ /* Consistency check. */
if (MSEQNO(mref) == NTFS_I(dent_inode)->seq_no || if (MSEQNO(mref) == NTFS_I(dent_inode)->seq_no ||
dent_ino == FILE_MFT) { dent_ino == FILE_MFT) {
...@@ -132,16 +132,19 @@ static struct dentry *ntfs_lookup(struct inode *dir_ino, struct dentry *dent) ...@@ -132,16 +132,19 @@ static struct dentry *ntfs_lookup(struct inode *dir_ino, struct dentry *dent)
ntfs_error(vol->sb, "Found stale reference to inode " ntfs_error(vol->sb, "Found stale reference to inode "
"0x%lx (reference sequence number = " "0x%lx (reference sequence number = "
"0x%x, inode sequence number = 0x%x, " "0x%x, inode sequence number = 0x%x, "
"returning -EACCES. Run chkdsk.", "returning -EIO. Run chkdsk.",
dent_ino, MSEQNO(mref), dent_ino, MSEQNO(mref),
NTFS_I(dent_inode)->seq_no); NTFS_I(dent_inode)->seq_no);
iput(dent_inode); iput(dent_inode);
dent_inode = ERR_PTR(-EIO);
} else } else
ntfs_error(vol->sb, "iget(0x%lx) failed, returning " ntfs_error(vol->sb, "ntfs_iget(0x%lx) failed with "
"-EACCES.", dent_ino); "error code %li.", dent_ino,
PTR_ERR(dent_inode));
if (name) if (name)
kfree(name); kfree(name);
return ERR_PTR(-EACCES); /* Return the error code. */
return (struct dentry *)dent_inode;
} }
/* It is guaranteed that name is no longer allocated at this point. */ /* It is guaranteed that name is no longer allocated at this point. */
if (MREF_ERR(mref) == -ENOENT) { if (MREF_ERR(mref) == -ENOENT) {
...@@ -256,7 +259,8 @@ static struct dentry *ntfs_lookup(struct inode *dir_ino, struct dentry *dent) ...@@ -256,7 +259,8 @@ static struct dentry *ntfs_lookup(struct inode *dir_ino, struct dentry *dent)
BUG_ON(real_dent->d_inode != dent_inode); BUG_ON(real_dent->d_inode != dent_inode);
/* /*
* Already have the inode and the dentry attached, decrement * Already have the inode and the dentry attached, decrement
* the reference count to balance the iget() we did earlier on. * the reference count to balance the ntfs_iget() we did
* earlier on.
*/ */
iput(dent_inode); iput(dent_inode);
return real_dent; return real_dent;
......
...@@ -53,41 +53,6 @@ typedef enum { ...@@ -53,41 +53,6 @@ typedef enum {
NTFS_MAX_NAME_LEN = 255, NTFS_MAX_NAME_LEN = 255,
} NTFS_CONSTANTS; } NTFS_CONSTANTS;
/*
* Defined bits for the state field in the ntfs_inode structure.
* (f) = files only, (d) = directories only
*/
typedef enum {
NI_Dirty, /* 1: Mft record needs to be written to disk. */
NI_AttrList, /* 1: Mft record contains an attribute list. */
NI_AttrListNonResident, /* 1: Attribute list is non-resident. Implies
NI_AttrList is set. */
NI_NonResident, /* 1: Unnamed data attr is non-resident (f).
1: $I30 index alloc attr is present (d). */
NI_Compressed, /* 1: Unnamed data attr is compressed (f).
1: Create compressed files by default (d). */
NI_Encrypted, /* 1: Unnamed data attr is encrypted (f).
1: Create encrypted files by default (d). */
NI_BmpNonResident, /* 1: $I30 bitmap attr is non resident (d). */
} ntfs_inode_state_bits;
/*
* NOTE: We should be adding dirty mft records to a list somewhere and they
* should be independent of the (ntfs/vfs) inode structure so that an inode can
* be removed but the record can be left dirty for syncing later.
*/
#define NInoDirty(n_ino) test_bit(NI_Dirty, &(n_ino)->state)
#define NInoSetDirty(n_ino) set_bit(NI_Dirty, &(n_ino)->state)
#define NInoClearDirty(n_ino) clear_bit(NI_Dirty, &(n_ino)->state)
#define NInoAttrList(n_ino) test_bit(NI_AttrList, &(n_ino)->state)
#define NInoNonResident(n_ino) test_bit(NI_NonResident, &(n_ino)->state)
#define NInoIndexAllocPresent(n_ino) test_bit(NI_NonResident, &(n_ino)->state)
#define NInoCompressed(n_ino) test_bit(NI_Compressed, &(n_ino)->state)
#define NInoEncrypted(n_ino) test_bit(NI_Encrypted, &(n_ino)->state)
#define NInoBmpNonResident(n_ino) test_bit(NI_BmpNonResident, &(n_ino)->state)
/* Global variables. */ /* Global variables. */
/* Slab caches (from super.c). */ /* Slab caches (from super.c). */
......
This diff is collapsed.
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* of the Linux-NTFS project. * of the Linux-NTFS project.
* *
* Copyright (c) 2001,2002 Anton Altaparmakov. * Copyright (c) 2001,2002 Anton Altaparmakov.
* Copyright (C) 2002 Richard Russon. * Copyright (c) 2002 Richard Russon.
* *
* This program/include file is free software; you can redistribute it and/or * This program/include file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published * modify it under the terms of the GNU General Public License as published
...@@ -89,10 +89,8 @@ typedef struct { ...@@ -89,10 +89,8 @@ typedef struct {
u32 index_record_size; /* in bytes */ u32 index_record_size; /* in bytes */
u32 index_record_size_mask; /* index_record_size - 1 */ u32 index_record_size_mask; /* index_record_size - 1 */
u8 index_record_size_bits; /* log2(index_record_size) */ u8 index_record_size_bits; /* log2(index_record_size) */
union { LCN nr_clusters; /* Volume size in clusters == number of
LCN nr_clusters; /* Volume size in clusters. */ bits in lcn bitmap. */
LCN nr_lcn_bits; /* Number of bits in lcn bitmap. */
} SN(vcl);
LCN mft_lcn; /* Cluster location of mft data. */ LCN mft_lcn; /* Cluster location of mft data. */
LCN mftmirr_lcn; /* Cluster location of copy of mft. */ LCN mftmirr_lcn; /* Cluster location of copy of mft. */
u64 serial_no; /* The volume serial number. */ u64 serial_no; /* The volume serial number. */
...@@ -104,10 +102,8 @@ typedef struct { ...@@ -104,10 +102,8 @@ typedef struct {
struct inode *mft_ino; /* The VFS inode of $MFT. */ struct inode *mft_ino; /* The VFS inode of $MFT. */
struct rw_semaphore mftbmp_lock; /* Lock for serializing accesses to the struct rw_semaphore mftbmp_lock; /* Lock for serializing accesses to the
mft record bitmap ($MFT/$BITMAP). */ mft record bitmap ($MFT/$BITMAP). */
union { unsigned long nr_mft_records; /* Number of mft records == number of
unsigned long nr_mft_records; /* Number of mft records. */ bits in mft bitmap. */
unsigned long nr_mft_bits; /* Number of bits in mft bitmap. */
} SN(vmm);
struct address_space mftbmp_mapping; /* Page cache for $MFT/$BITMAP. */ struct address_space mftbmp_mapping; /* Page cache for $MFT/$BITMAP. */
run_list mftbmp_rl; /* Run list for $MFT/$BITMAP. */ run_list mftbmp_rl; /* Run list for $MFT/$BITMAP. */
s64 mftbmp_size; /* Data size of $MFT/$BITMAP. */ s64 mftbmp_size; /* Data size of $MFT/$BITMAP. */
...@@ -128,8 +124,5 @@ typedef struct { ...@@ -128,8 +124,5 @@ typedef struct {
struct nls_table *nls_map; struct nls_table *nls_map;
} ntfs_volume; } ntfs_volume;
#define _VCL(X) SC(vcl,X)
#define _VMM(X) SC(vmm,X)
#endif /* _LINUX_NTFS_VOLUME_H */ #endif /* _LINUX_NTFS_VOLUME_H */
...@@ -71,6 +71,7 @@ ...@@ -71,6 +71,7 @@
#include <linux/signal.h> #include <linux/signal.h>
#include <linux/highmem.h> #include <linux/highmem.h>
#include <linux/file.h> #include <linux/file.h>
#include <linux/times.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
...@@ -360,10 +361,10 @@ int proc_pid_stat(struct task_struct *task, char * buffer) ...@@ -360,10 +361,10 @@ int proc_pid_stat(struct task_struct *task, char * buffer)
task->cmin_flt, task->cmin_flt,
task->maj_flt, task->maj_flt,
task->cmaj_flt, task->cmaj_flt,
task->times.tms_utime, jiffies_to_clock_t(task->utime),
task->times.tms_stime, jiffies_to_clock_t(task->stime),
task->times.tms_cutime, jiffies_to_clock_t(task->cutime),
task->times.tms_cstime, jiffies_to_clock_t(task->cstime),
priority, priority,
nice, nice,
0UL /* removed */, 0UL /* removed */,
...@@ -692,8 +693,8 @@ int proc_pid_cpu(struct task_struct *task, char * buffer) ...@@ -692,8 +693,8 @@ int proc_pid_cpu(struct task_struct *task, char * buffer)
len = sprintf(buffer, len = sprintf(buffer,
"cpu %lu %lu\n", "cpu %lu %lu\n",
task->times.tms_utime, task->utime,
task->times.tms_stime); task->stime);
for (i = 0 ; i < NR_CPUS; i++) { for (i = 0 ; i < NR_CPUS; i++) {
if (cpu_online(i)) if (cpu_online(i))
......
...@@ -98,7 +98,7 @@ static int uptime_read_proc(char *page, char **start, off_t off, ...@@ -98,7 +98,7 @@ static int uptime_read_proc(char *page, char **start, off_t off,
int len; int len;
uptime = jiffies; uptime = jiffies;
idle = init_task.times.tms_utime + init_task.times.tms_stime; idle = init_task.utime + init_task.stime;
/* The formula for the fraction parts really is ((t * 100) / HZ) % 100, but /* The formula for the fraction parts really is ((t * 100) / HZ) % 100, but
that would overflow about every five days at HZ == 100. that would overflow about every five days at HZ == 100.
......
#ifndef _ASMi386_PARAM_H #ifndef _ASMi386_PARAM_H
#define _ASMi386_PARAM_H #define _ASMi386_PARAM_H
#ifdef __KERNEL__
# define HZ 1000 /* Internal kernel timer frequency */
# define USER_HZ 100 /* .. some user interfaces are in "ticks" */
# define CLOCKS_PER_SEC (USER_HZ) /* like times() */
#endif
#ifndef HZ #ifndef HZ
#define HZ 100 #define HZ 100
#endif #endif
...@@ -17,8 +23,4 @@ ...@@ -17,8 +23,4 @@
#define MAXHOSTNAMELEN 64 /* max length of hostname */ #define MAXHOSTNAMELEN 64 /* max length of hostname */
#ifdef __KERNEL__
# define CLOCKS_PER_SEC 100 /* frequency at which times() counts */
#endif
#endif #endif
...@@ -10,7 +10,6 @@ extern unsigned long event; ...@@ -10,7 +10,6 @@ extern unsigned long event;
#include <linux/threads.h> #include <linux/threads.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/times.h>
#include <linux/timex.h> #include <linux/timex.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/rbtree.h> #include <linux/rbtree.h>
...@@ -310,7 +309,7 @@ struct task_struct { ...@@ -310,7 +309,7 @@ struct task_struct {
unsigned long it_real_value, it_prof_value, it_virt_value; unsigned long it_real_value, it_prof_value, it_virt_value;
unsigned long it_real_incr, it_prof_incr, it_virt_incr; unsigned long it_real_incr, it_prof_incr, it_virt_incr;
struct timer_list real_timer; struct timer_list real_timer;
struct tms times; unsigned long utime, stime, cutime, cstime;
unsigned long start_time; unsigned long start_time;
long per_cpu_utime[NR_CPUS], per_cpu_stime[NR_CPUS]; long per_cpu_utime[NR_CPUS], per_cpu_stime[NR_CPUS];
/* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */ /* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */
......
...@@ -12,6 +12,16 @@ struct timespec { ...@@ -12,6 +12,16 @@ struct timespec {
}; };
#endif /* _STRUCT_TIMESPEC */ #endif /* _STRUCT_TIMESPEC */
struct timeval {
time_t tv_sec; /* seconds */
suseconds_t tv_usec; /* microseconds */
};
struct timezone {
int tz_minuteswest; /* minutes west of Greenwich */
int tz_dsttime; /* type of dst correction */
};
#ifdef __KERNEL__ #ifdef __KERNEL__
/* /*
...@@ -48,6 +58,27 @@ jiffies_to_timespec(unsigned long jiffies, struct timespec *value) ...@@ -48,6 +58,27 @@ jiffies_to_timespec(unsigned long jiffies, struct timespec *value)
value->tv_sec = jiffies / HZ; value->tv_sec = jiffies / HZ;
} }
/* Same for "timeval" */
static __inline__ unsigned long
timeval_to_jiffies(struct timeval *value)
{
unsigned long sec = value->tv_sec;
long usec = value->tv_usec;
if (sec >= (MAX_JIFFY_OFFSET / HZ))
return MAX_JIFFY_OFFSET;
usec += 1000000L / HZ - 1;
usec /= 1000000L / HZ;
return HZ * sec + usec;
}
static __inline__ void
jiffies_to_timeval(unsigned long jiffies, struct timeval *value)
{
value->tv_usec = (jiffies % HZ) * (1000000L / HZ);
value->tv_sec = jiffies / HZ;
}
/* Converts Gregorian date to seconds since 1970-01-01 00:00:00. /* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
* Assumes input in normal date format, i.e. 1980-12-31 23:59:59 * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
...@@ -88,17 +119,6 @@ extern struct timeval xtime; ...@@ -88,17 +119,6 @@ extern struct timeval xtime;
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
struct timeval {
time_t tv_sec; /* seconds */
suseconds_t tv_usec; /* microseconds */
};
struct timezone {
int tz_minuteswest; /* minutes west of Greenwich */
int tz_dsttime; /* type of dst correction */
};
#define NFDBITS __NFDBITS #define NFDBITS __NFDBITS
#ifdef __KERNEL__ #ifdef __KERNEL__
......
#ifndef _LINUX_TIMES_H #ifndef _LINUX_TIMES_H
#define _LINUX_TIMES_H #define _LINUX_TIMES_H
#ifdef __KERNEL__
# define jiffies_to_clock_t(x) ((x) / (HZ / USER_HZ))
#endif
struct tms { struct tms {
clock_t tms_utime; clock_t tms_utime;
clock_t tms_stime; clock_t tms_stime;
......
...@@ -319,8 +319,8 @@ static void do_acct_process(long exitcode, struct file *file) ...@@ -319,8 +319,8 @@ static void do_acct_process(long exitcode, struct file *file)
ac.ac_btime = CT_TO_SECS(current->start_time) + ac.ac_btime = CT_TO_SECS(current->start_time) +
(xtime.tv_sec - (jiffies / HZ)); (xtime.tv_sec - (jiffies / HZ));
ac.ac_etime = encode_comp_t(jiffies - current->start_time); ac.ac_etime = encode_comp_t(jiffies - current->start_time);
ac.ac_utime = encode_comp_t(current->times.tms_utime); ac.ac_utime = encode_comp_t(current->utime);
ac.ac_stime = encode_comp_t(current->times.tms_stime); ac.ac_stime = encode_comp_t(current->stime);
ac.ac_uid = current->uid; ac.ac_uid = current->uid;
ac.ac_gid = current->gid; ac.ac_gid = current->gid;
ac.ac_tty = (current->tty) ? kdev_t_to_nr(current->tty->device) : 0; ac.ac_tty = (current->tty) ? kdev_t_to_nr(current->tty->device) : 0;
......
...@@ -648,8 +648,8 @@ asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr, int options, struc ...@@ -648,8 +648,8 @@ asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr, int options, struc
} }
goto end_wait4; goto end_wait4;
case TASK_ZOMBIE: case TASK_ZOMBIE:
current->times.tms_cutime += p->times.tms_utime + p->times.tms_cutime; current->cutime += p->utime + p->cutime;
current->times.tms_cstime += p->times.tms_stime + p->times.tms_cstime; current->cstime += p->stime + p->cstime;
read_unlock(&tasklist_lock); read_unlock(&tasklist_lock);
retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0; retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0;
if (!retval && stat_addr) if (!retval && stat_addr)
......
...@@ -686,8 +686,8 @@ struct task_struct *do_fork(unsigned long clone_flags, ...@@ -686,8 +686,8 @@ struct task_struct *do_fork(unsigned long clone_flags,
p->leader = 0; /* session leadership doesn't inherit */ p->leader = 0; /* session leadership doesn't inherit */
p->tty_old_pgrp = 0; p->tty_old_pgrp = 0;
p->times.tms_utime = p->times.tms_stime = 0; p->utime = p->stime = 0;
p->times.tms_cutime = p->times.tms_cstime = 0; p->cutime = p->cstime = 0;
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
{ {
int i; int i;
......
...@@ -12,34 +12,6 @@ ...@@ -12,34 +12,6 @@
#include <asm/uaccess.h> #include <asm/uaccess.h>
/*
* change timeval to jiffies, trying to avoid the
* most obvious overflows..
*
* The tv_*sec values are signed, but nothing seems to
* indicate whether we really should use them as signed values
* when doing itimers. POSIX doesn't mention this (but if
* alarm() uses itimers without checking, we have to use unsigned
* arithmetic).
*/
static unsigned long tvtojiffies(struct timeval *value)
{
unsigned long sec = (unsigned) value->tv_sec;
unsigned long usec = (unsigned) value->tv_usec;
if (sec > (ULONG_MAX / HZ))
return ULONG_MAX;
usec += 1000000 / HZ - 1;
usec /= 1000000 / HZ;
return HZ*sec+usec;
}
static void jiffiestotv(unsigned long jiffies, struct timeval *value)
{
value->tv_usec = (jiffies % HZ) * (1000000 / HZ);
value->tv_sec = jiffies / HZ;
}
int do_getitimer(int which, struct itimerval *value) int do_getitimer(int which, struct itimerval *value)
{ {
register unsigned long val, interval; register unsigned long val, interval;
...@@ -70,8 +42,8 @@ int do_getitimer(int which, struct itimerval *value) ...@@ -70,8 +42,8 @@ int do_getitimer(int which, struct itimerval *value)
default: default:
return(-EINVAL); return(-EINVAL);
} }
jiffiestotv(val, &value->it_value); jiffies_to_timeval(val, &value->it_value);
jiffiestotv(interval, &value->it_interval); jiffies_to_timeval(interval, &value->it_interval);
return 0; return 0;
} }
...@@ -110,8 +82,8 @@ int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue) ...@@ -110,8 +82,8 @@ int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
register unsigned long i, j; register unsigned long i, j;
int k; int k;
i = tvtojiffies(&value->it_interval); i = timeval_to_jiffies(&value->it_interval);
j = tvtojiffies(&value->it_value); j = timeval_to_jiffies(&value->it_value);
if (ovalue && (k = do_getitimer(which, ovalue)) < 0) if (ovalue && (k = do_getitimer(which, ovalue)) < 0)
return k; return k;
switch (which) { switch (which) {
......
...@@ -779,8 +779,8 @@ void do_notify_parent(struct task_struct *tsk, int sig) ...@@ -779,8 +779,8 @@ void do_notify_parent(struct task_struct *tsk, int sig)
info.si_uid = tsk->uid; info.si_uid = tsk->uid;
/* FIXME: find out whether or not this is supposed to be c*time. */ /* FIXME: find out whether or not this is supposed to be c*time. */
info.si_utime = tsk->times.tms_utime; info.si_utime = tsk->utime;
info.si_stime = tsk->times.tms_stime; info.si_stime = tsk->stime;
status = tsk->exit_code & 0x7f; status = tsk->exit_code & 0x7f;
why = SI_KERNEL; /* shouldn't happen */ why = SI_KERNEL; /* shouldn't happen */
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/tqueue.h> #include <linux/tqueue.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/times.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -833,10 +834,16 @@ asmlinkage long sys_times(struct tms * tbuf) ...@@ -833,10 +834,16 @@ asmlinkage long sys_times(struct tms * tbuf)
* atomically safe type this is just fine. Conceptually its * atomically safe type this is just fine. Conceptually its
* as if the syscall took an instant longer to occur. * as if the syscall took an instant longer to occur.
*/ */
if (tbuf) if (tbuf) {
if (copy_to_user(tbuf, &current->times, sizeof(struct tms))) struct tms tmp;
tmp.tms_utime = jiffies_to_clock_t(current->utime);
tmp.tms_stime = jiffies_to_clock_t(current->stime);
tmp.tms_cutime = jiffies_to_clock_t(current->cutime);
tmp.tms_cstime = jiffies_to_clock_t(current->cstime);
if (copy_to_user(tbuf, &tmp, sizeof(struct tms)))
return -EFAULT; return -EFAULT;
return jiffies; }
return jiffies_to_clock_t(jiffies);
} }
/* /*
...@@ -1193,28 +1200,22 @@ int getrusage(struct task_struct *p, int who, struct rusage *ru) ...@@ -1193,28 +1200,22 @@ int getrusage(struct task_struct *p, int who, struct rusage *ru)
memset((char *) &r, 0, sizeof(r)); memset((char *) &r, 0, sizeof(r));
switch (who) { switch (who) {
case RUSAGE_SELF: case RUSAGE_SELF:
r.ru_utime.tv_sec = CT_TO_SECS(p->times.tms_utime); jiffies_to_timeval(p->utime, &r.ru_utime);
r.ru_utime.tv_usec = CT_TO_USECS(p->times.tms_utime); jiffies_to_timeval(p->stime, &r.ru_stime);
r.ru_stime.tv_sec = CT_TO_SECS(p->times.tms_stime);
r.ru_stime.tv_usec = CT_TO_USECS(p->times.tms_stime);
r.ru_minflt = p->min_flt; r.ru_minflt = p->min_flt;
r.ru_majflt = p->maj_flt; r.ru_majflt = p->maj_flt;
r.ru_nswap = p->nswap; r.ru_nswap = p->nswap;
break; break;
case RUSAGE_CHILDREN: case RUSAGE_CHILDREN:
r.ru_utime.tv_sec = CT_TO_SECS(p->times.tms_cutime); jiffies_to_timeval(p->cutime, &r.ru_utime);
r.ru_utime.tv_usec = CT_TO_USECS(p->times.tms_cutime); jiffies_to_timeval(p->cstime, &r.ru_stime);
r.ru_stime.tv_sec = CT_TO_SECS(p->times.tms_cstime);
r.ru_stime.tv_usec = CT_TO_USECS(p->times.tms_cstime);
r.ru_minflt = p->cmin_flt; r.ru_minflt = p->cmin_flt;
r.ru_majflt = p->cmaj_flt; r.ru_majflt = p->cmaj_flt;
r.ru_nswap = p->cnswap; r.ru_nswap = p->cnswap;
break; break;
default: default:
r.ru_utime.tv_sec = CT_TO_SECS(p->times.tms_utime + p->times.tms_cutime); jiffies_to_timeval(p->utime + p->cutime, &r.ru_utime);
r.ru_utime.tv_usec = CT_TO_USECS(p->times.tms_utime + p->times.tms_cutime); jiffies_to_timeval(p->stime + p->cstime, &r.ru_stime);
r.ru_stime.tv_sec = CT_TO_SECS(p->times.tms_stime + p->times.tms_cstime);
r.ru_stime.tv_usec = CT_TO_USECS(p->times.tms_stime + p->times.tms_cstime);
r.ru_minflt = p->min_flt + p->cmin_flt; r.ru_minflt = p->min_flt + p->cmin_flt;
r.ru_majflt = p->maj_flt + p->cmaj_flt; r.ru_majflt = p->maj_flt + p->cmaj_flt;
r.ru_nswap = p->nswap + p->cnswap; r.ru_nswap = p->nswap + p->cnswap;
......
...@@ -527,8 +527,8 @@ static inline void do_process_times(struct task_struct *p, ...@@ -527,8 +527,8 @@ static inline void do_process_times(struct task_struct *p,
{ {
unsigned long psecs; unsigned long psecs;
psecs = (p->times.tms_utime += user); psecs = (p->utime += user);
psecs += (p->times.tms_stime += system); psecs += (p->stime += system);
if (psecs / HZ > p->rlim[RLIMIT_CPU].rlim_cur) { if (psecs / HZ > p->rlim[RLIMIT_CPU].rlim_cur) {
/* Send SIGXCPU every second.. */ /* Send SIGXCPU every second.. */
if (!(psecs % HZ)) if (!(psecs % HZ))
......
...@@ -72,7 +72,7 @@ static int badness(struct task_struct *p) ...@@ -72,7 +72,7 @@ static int badness(struct task_struct *p)
* very well in practice. This is not safe against jiffie wraps * very well in practice. This is not safe against jiffie wraps
* but we don't care _that_ much... * but we don't care _that_ much...
*/ */
cpu_time = (p->times.tms_utime + p->times.tms_stime) >> (SHIFT_HZ + 3); cpu_time = (p->utime + p->stime) >> (SHIFT_HZ + 3);
run_time = (jiffies - p->start_time) >> (SHIFT_HZ + 10); run_time = (jiffies - p->start_time) >> (SHIFT_HZ + 10);
points /= int_sqrt(cpu_time); points /= int_sqrt(cpu_time);
......
...@@ -3573,9 +3573,18 @@ maestro_probe(struct pci_dev *pcidev,const struct pci_device_id *pdid) ...@@ -3573,9 +3573,18 @@ maestro_probe(struct pci_dev *pcidev,const struct pci_device_id *pdid)
static void maestro_remove(struct pci_dev *pcidev) { static void maestro_remove(struct pci_dev *pcidev) {
struct ess_card *card = pci_get_drvdata(pcidev); struct ess_card *card = pci_get_drvdata(pcidev);
int i; int i;
u32 n;
/* XXX maybe should force stop bob, but should be all /* XXX maybe should force stop bob, but should be all
stopped by _release by now */ stopped by _release by now */
/* Turn off hardware volume control interrupt.
This has to come before we leave the IRQ below,
or a crash results if a button is pressed ! */
n = inw(card->iobase+0x18);
n&=~(1<<6);
outw(n, card->iobase+0x18);
free_irq(card->irq, card); free_irq(card->irq, card);
unregister_sound_mixer(card->dev_mixer); unregister_sound_mixer(card->dev_mixer);
for(i=0;i<NR_DSPS;i++) for(i=0;i<NR_DSPS;i++)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment