1227064Sbz/*
2227064Sbz * Copyright 2010, Ingo Weinhold, ingo_weinhold@gmx.de.
3227064Sbz * Distributed under the terms of the MIT License.
4227064Sbz */
5227064Sbz#ifndef IO_CACHE_H
6227064Sbz#define IO_CACHE_H
7227064Sbz
8227064Sbz
9227064Sbz#include <lock.h>
10227064Sbz#include <vm/vm_page.h>
11227064Sbz
12227064Sbz#include "dma_resources.h"
13227064Sbz#include "IOScheduler.h"
14227064Sbz
15227064Sbz
16227064Sbzstruct VMCache;
17227064Sbzstruct vm_page;
18227064Sbz
19227064Sbz
20227064Sbzclass IOCache : public IOScheduler {
21227064Sbzpublic:
22227064Sbz								IOCache(DMAResource* resource,
23227064Sbz									size_t cacheLineSize);
24227064Sbz	virtual						~IOCache();
25227064Sbz
26227064Sbz	virtual	status_t			Init(const char* name);
27227064Sbz
28227064Sbz	virtual	void				SetDeviceCapacity(off_t deviceCapacity);
29227064Sbz	virtual void				MediaChanged();
30227064Sbz
31227064Sbz	virtual	status_t			ScheduleRequest(IORequest* request);
32227064Sbz
33227064Sbz	virtual	void				AbortRequest(IORequest* request,
34227064Sbz									status_t status = B_CANCELED);
35227064Sbz	virtual	void				OperationCompleted(IOOperation* operation,
36227064Sbz									status_t status,
37227064Sbz									generic_size_t transferredBytes);
38227064Sbz
39227064Sbz	virtual	void				Dump() const;
40227064Sbz
41227064Sbzprivate:
42227064Sbz			struct Operation;
43227064Sbz
44227064Sbzprivate:
45227064Sbz			status_t			_DoRequest(IORequest* request,
46227064Sbz									generic_size_t& _bytesTransferred);
47227064Sbz			status_t			_TransferRequestLine(IORequest* request,
48227064Sbz									off_t lineOffset, size_t lineSize,
49227064Sbz									off_t requestOffset, size_t requestLength);
50227064Sbz			status_t			_TransferRequestLineUncached(IORequest* request,
51227064Sbz									off_t lineOffset, off_t requestOffset,
52227064Sbz									size_t requestLength);
53227064Sbz			status_t			_DoOperation(Operation& operation);
54227064Sbz
55227064Sbz			status_t			_TransferPages(size_t firstPage,
56227064Sbz									size_t pageCount, bool isWrite, bool isVIP);
57227064Sbz			void				_DiscardPages(size_t firstPage,
58227064Sbz									size_t pageCount);
59227064Sbz			void				_CachePages(size_t firstPage, size_t pageCount);
60227064Sbz
61227064Sbz			status_t			_CopyPages(IORequest* request,
62227064Sbz									size_t pagesRelativeOffset,
63227064Sbz									off_t requestOffset, size_t requestLength,
64227064Sbz									bool toRequest);
65227064Sbz
66227064Sbz			status_t			_MapPages(size_t firstPage, size_t endPage);
67227064Sbz			void				_UnmapPages(size_t firstPage, size_t endPage);
68227064Sbz
69227064Sbzprivate:
70227064Sbz			mutex				fSerializationLock;
71227064Sbz			off_t				fDeviceCapacity;
72227064Sbz			size_t				fLineSize;
73227064Sbz			uint32				fLineSizeShift;
74227064Sbz			size_t				fPagesPerLine;
75227064Sbz			area_id				fArea;
76227064Sbz			void*				fAreaBase;
77227064Sbz			vm_page_reservation	fMappingReservation;
78227064Sbz			VMCache*			fCache;
79227064Sbz			vm_page**			fPages;
80227064Sbz			generic_io_vec*		fVecs;
81227064Sbz};
82227064Sbz
83227064Sbz
84227064Sbz#endif	// IO_CACHE_H
85227064Sbz