Вопрос: Как реализовать частичную специализацию для указателя на определённый класс?

Лучший ответ: Так как вы хотите специализировать параметры шаблона класса, то придётся специализировать весь класс:template <typename Node, typename DataType>
class List
{
  Node *head, *tail;
  int count;

public:
  // ...
  void AddHead(DataType data);
};

template <typename Node>
class List<Node, Storage_device*>
{
  using DataType = Storage_device*;

  Node *head, *tail;
  int count;

public:
  // ...
  void AddHead(DataType data);
};
Теперь для этой специализации класса получится определить AddHead, как у вас.
Можно обойтись без специализации всего класса, искусственно добавив шаблон в функцию:template<typename = std::enable_if<std::is_same<DataType, Storage_device*>>::type>
void AddHead(DataType data);  // specialized version

template<typename = std::enable_if<!std::is_same<DataType, Storage_device*>>::type>
void AddHead(DataType data);  // general version
Правда, я давно не использовал std::enable_if, не гарантирую, что это работает.template<typename Node, typename DataType>
class List {
    //...
public:
    template<typename = std::enable_if<std::is_same<DataType, Storage_device*>>::type>
    void AddHead(DataType data);

    template<typename = std::enable_if<!std::is_same<DataType, Storage_device*>>::type>
    void AddHead(DataType data);
};

template<typename Node, typename DataType>
template<typename = std::enable_if<std::is_same<DataType, Storage_device*>>::type>
void List<Node, DataType>::AddHead(DataType data);

template<typename Node, typename DataType>
template<typename = std::enable_if<!std::is_same<DataType, Storage_device*>>::type>
void List<Node, DataType>::AddHead(DataType data);

Худший ответ: В общем, Антон Жилин все описал правильно, но есть еще один выход.
Чтобы понять преимущество предлагаемого мной подхода, нужно обратиться к коду std::basic_string.
Например, вот эта реализация.
https://android.googlesource.com/platform/ndk/+/bf...
Вторым параметром идут так называемые черты - traits для типа символов в строке. По своей сути функциональность std::string, std::wstring, std::u16string и std::u32string отличается только реализацией именно этого параметра.
Сам шаблон черт для строки описан немногим выше 75й строки.
Вся реализация std::basic_string полностью опирается на список статических функций из заданных в шаблоне черт.
Я предлагаю вынести частную специализацию за пределы твоего шаблона List и определить черты ListTraits, которые уже и специализировать для нужных классов, в частности - для Storage_device.
В черты можно и нужно выделять только важные функции. Это можно сравнить с вынужденной мерой.template< typename TDataType >
class ListTraits
{
public:
	// ...
	
	template< typename TNodeType >
	inline static void AddHead( TNodeType node, TDataType data );
	
	// ...
};

template<>
class ListTraits<Storage_device*>
{
public:
	// ...
	
	template< typename TNodeType >
	inline static void AddHead( TNodeType node, Storage_device* data );
	
	// ...
};

template< typename TNodeType, typename TDataType >
class List
{
	// Тип используемых черт.
	using Traits = ListTraits<TDataType>;
	
	TNodeType *head, *tail;
	int count;

public:
	// ...
	
	void AddHead(TDataType data);
	
	// ...
};

template< typename TNodeType, typename TDataType >
void List<TNodeType, TDataType>::AddHead( TDataType data )
{
	// ...
	
	Traits::template AddHead( temp, data );
	
	// ...
};