The Pedigree Project  0.1
CdiDisk.cc
1 /*
2  * Copyright (c) 2008-2014, Pedigree Developers
3  *
4  * Please see the CONTRIB file in the root of the source tree for a full
5  * list of contributors.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include "CdiDisk.h"
21 #include <stddef.h>
22 #include "pedigree/kernel/Log.h"
23 #include "pedigree/kernel/Service.h"
24 #include "pedigree/kernel/ServiceFeatures.h"
25 #include "pedigree/kernel/ServiceManager.h"
26 #include "pedigree/kernel/machine/Device.h"
27 #include "pedigree/kernel/utilities/assert.h"
28 #include "pedigree/kernel/utilities/new"
29 
30 // Prototypes in the extern "C" block to ensure that they are not mangled
31 extern "C" {
32  void cdi_cpp_disk_register(struct cdi_storage_device* device);
33 
34  int cdi_storage_read(struct cdi_storage_device* device, uint64_t pos, size_t size, void* dest);
35  int cdi_storage_write(struct cdi_storage_device* device, uint64_t pos, size_t size, void* src);
36 };
37 
38 CdiDisk::CdiDisk(Disk* pDev, struct cdi_storage_device* device) :
39  Disk(pDev), m_Device(device), m_Cache()
40 {
41  setSpecificType(String("CDI Disk"));
42 }
43 
44 CdiDisk::CdiDisk(struct cdi_storage_device *device) :
45  Disk(), m_Device(device), m_Cache()
46 {
47  setSpecificType(String("CDI Disk"));
48 }
49 
50 CdiDisk::~CdiDisk()
51 {
52 }
53 
55 {
56  // Chat to the partition service and let it pick up that we're around now
57  ServiceFeatures *pFeatures = ServiceManager::instance().enumerateOperations(String("partition"));
58  Service *pService = ServiceManager::instance().getService(String("partition"));
59  NOTICE("Asking if the partition provider supports touch");
60  if(pFeatures->provides(ServiceFeatures::touch))
61  {
62  NOTICE("It does, attempting to inform the partitioner of our presence...");
63  if(pService)
64  {
65  if(pService->serve(ServiceFeatures::touch,
66  reinterpret_cast<void*>(static_cast<Disk*>(this)),
67  sizeof(*static_cast<Disk*>(this))))
68  {
69  NOTICE("Successful.");
70  }
71  else
72  {
73  ERROR("Failed.");
74  return false;
75  }
76  }
77  else
78  {
79  ERROR("FileDisk: Couldn't tell the partition service about the new disk presence");
80  return false;
81  }
82  }
83  else
84  {
85  ERROR("FileDisk: Partition service doesn't appear to support touch");
86  return false;
87  }
88 
89  return true;
90 }
91 
92 // These are the functions that others call - they add a request to the parent controller's queue.
93 uintptr_t CdiDisk::read(uint64_t location)
94 {
95  assert( (location % 512) == 0 );
96  uintptr_t buff = m_Cache.lookup(location);
97  if (!buff)
98  {
99  buff = m_Cache.insert(location);
100  if (cdi_storage_read(m_Device, location, 512, reinterpret_cast<void*>(buff)) != 0)
101  return 0;
102 
103  m_Cache.markNoLongerEditing(location);
104  }
105  return buff;
106 }
107 
108 void CdiDisk::write(uint64_t location)
109 {
110  assert( (location % 512) == 0 );
111  uintptr_t buff = m_Cache.lookup(location);
112  assert(buff);
113  CachePageGuard guard(m_Cache, location);
114 
115  if (cdi_storage_write(m_Device, location, 512, reinterpret_cast<void*>(buff)) != 0)
116  return;
117 }
118 
119 void cdi_cpp_disk_register(struct cdi_storage_device* device)
120 {
121  // Create a new CdiDisk node.
122  CdiDisk *pCdiDisk = new CdiDisk(0, device);
123  if(!pCdiDisk->initialise())
124  {
125  delete pCdiDisk;
126  return;
127  }
128 
129  // Insert into the tree, properly
130  Device::addToRoot(pCdiDisk);
131 }
virtual void write(uint64_t location)
Definition: CdiDisk.cc:108
static void addToRoot(Device *device)
Definition: Device.cc:102
Definition: String.h:49
virtual bool provides(Type service)
Definition: Disk.h:32
#define NOTICE(text)
Definition: Log.h:74
#define assert(x)
Definition: assert.h:37
Service * getService(const String &serviceName)
bool initialise()
Definition: CdiDisk.cc:54
virtual bool serve(ServiceFeatures::Type type, void *pData, size_t dataLen)=0
#define ERROR(text)
Definition: Log.h:82
ServiceFeatures * enumerateOperations(const String &serviceName)
virtual uintptr_t read(uint64_t location)
Definition: CdiDisk.cc:93